blob: 793d0d3655cfc25c6c1e5a1af5d0476c8a0d1e43 [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
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070019import android.annotation.Nullable;
Dianne Hackborn61659e52014-07-09 16:13:01 -070020import android.app.ActivityManager;
Adam Lesinski33dac552015-03-09 15:24:48 -070021import android.bluetooth.BluetoothActivityEnergyInfo;
Jaikumar Ganesh3f034962010-09-27 17:02:23 -070022import android.bluetooth.BluetoothDevice;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -070023import android.bluetooth.BluetoothHeadset;
Dianne Hackborna7c837f2014-01-15 16:20:44 -080024import android.content.Context;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070025import android.net.ConnectivityManager;
26import android.net.NetworkStats;
Adam Lesinski33dac552015-03-09 15:24:48 -070027import android.net.wifi.WifiActivityEnergyInfo;
Dianne Hackborn3251b902014-06-20 14:40:53 -070028import android.net.wifi.WifiManager;
Dianne Hackborn00e25212014-02-19 10:49:24 -080029import android.os.BadParcelableException;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070030import android.os.BatteryManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080031import android.os.BatteryStats;
Dianne Hackborncd0e3352014-08-07 17:08:09 -070032import android.os.Build;
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070033import android.os.FileUtils;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070034import android.os.Handler;
Jeff Brown6f357d32014-01-15 20:40:55 -080035import android.os.Looper;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070036import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.os.Parcel;
38import android.os.ParcelFormatException;
39import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070040import android.os.Process;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080041import android.os.SystemClock;
Jeff Sharkey418d12d2011-12-13 15:38:03 -080042import android.os.SystemProperties;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070043import android.os.WorkSource;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070044import android.telephony.DataConnectionRealTimeInfo;
Amith Yamasanif37447b2009-10-08 18:28:01 -070045import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070046import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070047import android.telephony.TelephonyManager;
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -070048import android.text.TextUtils;
Dianne Hackborn61659e52014-07-09 16:13:01 -070049import android.util.ArrayMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080050import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070051import android.util.LogWriter;
Dianne Hackbornd953c532014-08-16 18:17:38 -070052import android.util.MutableInt;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070053import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070055import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080056import android.util.SparseArray;
Dianne Hackborn099bc622014-01-22 13:39:16 -080057import android.util.SparseIntArray;
Adam Lesinskie08af192015-03-25 16:42:59 -070058import android.util.SparseLongArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070059import android.util.TimeUtils;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080060import android.util.Xml;
Jeff Browne95c3cd2014-05-02 16:59:26 -070061import android.view.Display;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070063import com.android.internal.net.NetworkStatsFactory;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080064import com.android.internal.util.ArrayUtils;
Dianne Hackborn8c841092013-06-24 13:46:13 -070065import com.android.internal.util.FastPrintWriter;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080066import com.android.internal.util.FastXmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070067import com.android.internal.util.JournaledFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080068import com.android.internal.util.XmlUtils;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070069import com.android.server.NetworkManagementSocketTagger;
70import libcore.util.EmptyArray;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080071import org.xmlpull.v1.XmlPullParser;
72import org.xmlpull.v1.XmlPullParserException;
73import org.xmlpull.v1.XmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070074
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080075import java.io.ByteArrayOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080076import java.io.File;
77import java.io.FileInputStream;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080078import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080079import java.io.FileOutputStream;
80import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070081import java.io.PrintWriter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080082import java.util.ArrayList;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080083import java.util.Calendar;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080084import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070085import java.util.Iterator;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070086import java.util.List;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import java.util.Map;
Christopher Tate4cee7252010-03-19 14:50:40 -070088import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070089import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090
91/**
92 * All information we are collecting about things that can happen that impact
93 * battery life. All times are represented in microseconds except where indicated
94 * otherwise.
95 */
96public final class BatteryStatsImpl extends BatteryStats {
97 private static final String TAG = "BatteryStatsImpl";
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080098 private static final boolean DEBUG = false;
Adam Lesinskie08af192015-03-25 16:42:59 -070099 private static final boolean DEBUG_ENERGY = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700100 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -0700101 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700102
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700103 // TODO: remove "tcp" from network methods, since we measure total stats.
104
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700106 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107
108 // Current on-disk Parcel version
Kweku Adams030980a2015-04-01 16:07:48 -0700109 private static final int VERSION = 123 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700110
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700111 // Maximum number of items we will record in the history.
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700112 private static final int MAX_HISTORY_ITEMS = 2000;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700113
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700114 // No, really, THIS is the maximum number of items we will record in the history.
115 private static final int MAX_MAX_HISTORY_ITEMS = 3000;
116
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800117 // The maximum number of names wakelocks we will keep track of
118 // per uid; once the limit is reached, we batch the remaining wakelocks
119 // in to one common name.
Dianne Hackbornacc4a122014-08-18 16:33:44 -0700120 private static final int MAX_WAKELOCKS_PER_UID = 100;
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700121
Amith Yamasanie43530a2009-08-21 13:11:37 -0700122 private static int sNumSpeedSteps;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800123
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700124 private final JournaledFile mFile;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700125 public final AtomicFile mCheckinFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800126 public final AtomicFile mDailyFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800127
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700128 static final int MSG_UPDATE_WAKELOCKS = 1;
129 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700130 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700131
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700132 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
133 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
134
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700135 public interface BatteryCallback {
136 public void batteryNeedsCpuUpdate();
137 public void batteryPowerChanged(boolean onBattery);
138 }
139
140 final class MyHandler extends Handler {
Jeff Brown6f357d32014-01-15 20:40:55 -0800141 public MyHandler(Looper looper) {
142 super(looper, null, true);
143 }
144
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700145 @Override
146 public void handleMessage(Message msg) {
147 BatteryCallback cb = mCallback;
148 switch (msg.what) {
149 case MSG_UPDATE_WAKELOCKS:
150 if (cb != null) {
151 cb.batteryNeedsCpuUpdate();
152 }
153 break;
154 case MSG_REPORT_POWER_CHANGE:
155 if (cb != null) {
156 cb.batteryPowerChanged(msg.arg1 != 0);
157 }
158 break;
159 }
160 }
161 }
162
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700163 public interface ExternalStatsSync {
164 void scheduleSync();
165 }
166
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700167 public final MyHandler mHandler;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700168 private final ExternalStatsSync mExternalSync;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700169
170 private BatteryCallback mCallback;
171
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800172 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -0800173 * Mapping isolated uids to the actual owning app uid.
174 */
175 final SparseIntArray mIsolatedUids = new SparseIntArray();
176
177 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800178 * The statistics we have collected organized by uids.
179 */
180 final SparseArray<BatteryStatsImpl.Uid> mUidStats =
181 new SparseArray<BatteryStatsImpl.Uid>();
182
183 // A set of pools of currently active timers. When a timer is queried, we will divide the
184 // elapsed time by the number of active timers to arrive at that timer's share of the time.
185 // In order to do this, we must refresh each timer whenever the number of active timers
186 // changes.
Adam Lesinskie08af192015-03-25 16:42:59 -0700187 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
188 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
189 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
190 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
191 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
192 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
193 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
194 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
195 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
196 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
197 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800198
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700199 // Last partial timers we use for distributing CPU usage.
Adam Lesinskie08af192015-03-25 16:42:59 -0700200 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700201
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800202 // These are the objects that will want to do something when the device
203 // is unplugged from power.
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800204 final TimeBase mOnBatteryTimeBase = new TimeBase();
205
206 // These are the objects that will want to do something when the device
207 // is unplugged from power *and* the screen is off.
208 final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
209
210 // Set to true when we want to distribute CPU across wakelocks for the next
211 // CPU update, even if we aren't currently running wake locks.
212 boolean mDistributeWakelockCpu;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700213
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700214 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700215
Dianne Hackborn37de0982014-05-09 09:32:18 -0700216 final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800217
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700218 long mHistoryBaseTime;
219 boolean mHaveBatteryLevel = false;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700220 boolean mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700221 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700222
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700223 static final int MAX_HISTORY_BUFFER = 256*1024; // 256KB
224 static final int MAX_MAX_HISTORY_BUFFER = 320*1024; // 320KB
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700225 final Parcel mHistoryBuffer = Parcel.obtain();
226 final HistoryItem mHistoryLastWritten = new HistoryItem();
227 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700228 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700229 final HistoryItem mHistoryAddTmp = new HistoryItem();
Adam Lesinskie08af192015-03-25 16:42:59 -0700230 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
Dianne Hackborn099bc622014-01-22 13:39:16 -0800231 String[] mReadHistoryStrings;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800232 int[] mReadHistoryUids;
233 int mReadHistoryChars;
234 int mNextHistoryTagIdx = 0;
235 int mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700236 int mHistoryBufferLastPos = -1;
237 boolean mHistoryOverflow = false;
Dianne Hackborn40c87252014-03-19 16:55:40 -0700238 long mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700239 long mTrackRunningHistoryElapsedRealtime = 0;
240 long mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700241
242 final HistoryItem mHistoryCur = new HistoryItem();
243
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700244 HistoryItem mHistory;
245 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700246 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700247 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700248
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800249 // Used by computeHistoryStepDetails
250 HistoryStepDetails mLastHistoryStepDetails = null;
251 byte mLastHistoryStepLevel = 0;
252 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
253 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails();
254 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
255 /**
256 * Total time (in 1/100 sec) spent executing in user code.
257 */
258 long mLastStepCpuUserTime;
259 long mCurStepCpuUserTime;
260 /**
261 * Total time (in 1/100 sec) spent executing in kernel code.
262 */
263 long mLastStepCpuSystemTime;
264 long mCurStepCpuSystemTime;
265 /**
266 * Times from /proc/stat
267 */
268 long mLastStepStatUserTime;
269 long mLastStepStatSystemTime;
270 long mLastStepStatIOWaitTime;
271 long mLastStepStatIrqTime;
272 long mLastStepStatSoftIrqTime;
273 long mLastStepStatIdleTime;
274 long mCurStepStatUserTime;
275 long mCurStepStatSystemTime;
276 long mCurStepStatIOWaitTime;
277 long mCurStepStatIrqTime;
278 long mCurStepStatSoftIrqTime;
279 long mCurStepStatIdleTime;
280
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700281 private HistoryItem mHistoryIterator;
282 private boolean mReadOverflow;
283 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 int mStartCount;
286
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800287 long mStartClockTime;
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700288 String mStartPlatformVersion;
289 String mEndPlatformVersion;
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800290
Dianne Hackborna7d0d552014-09-12 17:15:52 -0700291 long mLastRecordedClockTime;
292 long mLastRecordedClockRealtime;
293
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800294 long mUptime;
295 long mUptimeStart;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800296 long mRealtime;
297 long mRealtimeStart;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700298
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800299 int mWakeLockNesting;
300 boolean mWakeLockImportant;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700301 boolean mRecordAllHistory;
Dianne Hackborn9a755432014-05-15 17:05:22 -0700302 boolean mNoAutoReset;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800303
Jeff Browne95c3cd2014-05-02 16:59:26 -0700304 int mScreenState = Display.STATE_UNKNOWN;
Evan Millarc64edde2009-04-18 12:26:32 -0700305 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700306
Dianne Hackborn617f8772009-03-31 15:04:46 -0700307 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700308 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700309
Jeff Browne95c3cd2014-05-02 16:59:26 -0700310 boolean mInteractive;
311 StopwatchTimer mInteractiveTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700312
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700313 boolean mPowerSaveModeEnabled;
314 StopwatchTimer mPowerSaveModeEnabledTimer;
315
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700316 boolean mDeviceIdling;
317 StopwatchTimer mDeviceIdlingTimer;
318
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700319 boolean mDeviceIdleModeEnabled;
320 StopwatchTimer mDeviceIdleModeEnabledTimer;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700323 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700324
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700325 int mAudioOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700326 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700327
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700328 int mVideoOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700329 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700330
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700331 boolean mFlashlightOn;
332 StopwatchTimer mFlashlightOnTimer;
333
Dianne Hackborn627bba72009-03-24 22:32:56 -0700334 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800335 int mPhoneSignalStrengthBinRaw = -1;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700336 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800337 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700338
339 StopwatchTimer mPhoneSignalScanningTimer;
340
Dianne Hackborn627bba72009-03-24 22:32:56 -0700341 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700342 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700343 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700344
Dianne Hackborn57ed6a62013-12-09 18:15:56 -0800345 final LongSamplingCounter[] mNetworkByteActivityCounters =
346 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
347 final LongSamplingCounter[] mNetworkPacketActivityCounters =
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700348 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
349
Adam Lesinski33dac552015-03-09 15:24:48 -0700350 final LongSamplingCounter[] mBluetoothActivityCounters =
351 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
352
353 final LongSamplingCounter[] mWifiActivityCounters =
354 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
355
The Android Open Source Project10592532009-03-18 17:39:46 -0700356 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700357 StopwatchTimer mWifiOnTimer;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700358
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700359 boolean mGlobalWifiRunning;
360 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700361
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800362 int mWifiState = -1;
363 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
364
Dianne Hackborn3251b902014-06-20 14:40:53 -0700365 int mWifiSupplState = -1;
366 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES];
367
368 int mWifiSignalStrengthBin = -1;
369 final StopwatchTimer[] mWifiSignalStrengthsTimer =
370 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS];
371
The Android Open Source Project10592532009-03-18 17:39:46 -0700372 boolean mBluetoothOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700373 StopwatchTimer mBluetoothOnTimer;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700374
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800375 int mBluetoothState = -1;
376 final StopwatchTimer[] mBluetoothStateTimer = new StopwatchTimer[NUM_BLUETOOTH_STATES];
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800377
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700378 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackbornf7097a52014-05-13 09:56:14 -0700379 long mMobileRadioActiveStartTime;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800380 StopwatchTimer mMobileRadioActiveTimer;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800381 StopwatchTimer mMobileRadioActivePerAppTimer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700382 LongSamplingCounter mMobileRadioActiveAdjustedTime;
Dianne Hackbornd45665b2014-02-26 12:35:32 -0800383 LongSamplingCounter mMobileRadioActiveUnknownTime;
384 LongSamplingCounter mMobileRadioActiveUnknownCount;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800385
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700386 /** Bluetooth headset object */
387 BluetoothHeadset mBtHeadset;
388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800389 /**
390 * These provide time bases that discount the time the device is plugged
391 * in to power.
392 */
393 boolean mOnBattery;
394 boolean mOnBatteryInternal;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700395
The Android Open Source Project10592532009-03-18 17:39:46 -0700396 /*
397 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
398 */
Evan Millar633a1742009-04-02 16:36:33 -0700399 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700400 int mDischargeUnplugLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700401 int mDischargePlugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700402 int mDischargeCurrentLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700403 int mCurrentBatteryLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700404 int mLowDischargeAmountSinceCharge;
405 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800406 int mDischargeScreenOnUnplugLevel;
407 int mDischargeScreenOffUnplugLevel;
408 int mDischargeAmountScreenOn;
409 int mDischargeAmountScreenOnSinceCharge;
410 int mDischargeAmountScreenOff;
411 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700412
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700413 static final int MAX_LEVEL_STEPS = 200;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700414
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700415 int mInitStepMode = 0;
416 int mCurStepMode = 0;
417 int mModStepMode = 0;
418
Dianne Hackborn260c5022014-04-29 11:23:16 -0700419 int mLastDischargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700420 int mMinDischargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800421 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
422 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700423 ArrayList<PackageChange> mDailyPackageChanges;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700424
425 int mLastChargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700426 int mMaxChargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800427 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
428 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
429
430 static final int MAX_DAILY_ITEMS = 10;
431
432 long mDailyStartTime = 0;
433 long mNextMinDailyDeadline = 0;
434 long mNextMaxDailyDeadline = 0;
435
436 final ArrayList<DailyItem> mDailyItems = new ArrayList<>();
Dianne Hackborn260c5022014-04-29 11:23:16 -0700437
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800438 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700439
Amith Yamasani3f7e35c2009-07-13 16:02:45 -0700440 private int mBluetoothPingCount;
441 private int mBluetoothPingStart = -1;
442
Amith Yamasanif37447b2009-10-08 18:28:01 -0700443 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800444 private int mPhoneServiceStateRaw = -1;
445 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700446
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800447 private int mNumConnectivityChange;
448 private int mLoadedNumConnectivityChange;
449 private int mUnpluggedNumConnectivityChange;
450
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700451 private final NetworkStats.Entry mTmpNetworkStatsEntry = new NetworkStats.Entry();
452
Adam Lesinskie08af192015-03-25 16:42:59 -0700453 private PowerProfile mPowerProfile;
454
Evan Millarc64edde2009-04-18 12:26:32 -0700455 /*
456 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
457 */
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700458 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700459
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700460 public Map<String, ? extends Timer> getKernelWakelockStats() {
Evan Millarc64edde2009-04-18 12:26:32 -0700461 return mKernelWakelockStats;
462 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700463
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700464 String mLastWakeupReason = null;
465 long mLastWakeupUptimeMs = 0;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700466 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700467
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700468 public Map<String, ? extends Timer> getWakeupReasonStats() {
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700469 return mWakeupReasonStats;
470 }
471
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800472 public BatteryStatsImpl() {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700473 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700474 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800475 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700476 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700477 mExternalSync = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700478 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800479 }
480
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800481 public static interface TimeBaseObs {
482 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
483 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
484 }
485
486 static class TimeBase {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700487 private final ArrayList<TimeBaseObs> mObservers = new ArrayList<>();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800488
489 private long mUptime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800490 private long mRealtime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800491
492 private boolean mRunning;
493
494 private long mPastUptime;
495 private long mUptimeStart;
496 private long mPastRealtime;
497 private long mRealtimeStart;
498 private long mUnpluggedUptime;
499 private long mUnpluggedRealtime;
500
501 public void dump(PrintWriter pw, String prefix) {
502 StringBuilder sb = new StringBuilder(128);
503 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
504 sb.setLength(0);
505 sb.append(prefix);
506 sb.append("mUptime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700507 formatTimeMs(sb, mUptime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800508 pw.println(sb.toString());
509 sb.setLength(0);
510 sb.append(prefix);
511 sb.append("mRealtime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700512 formatTimeMs(sb, mRealtime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800513 pw.println(sb.toString());
514 sb.setLength(0);
515 sb.append(prefix);
516 sb.append("mPastUptime=");
517 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
518 formatTimeMs(sb, mUptimeStart / 1000);
519 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
520 pw.println(sb.toString());
521 sb.setLength(0);
522 sb.append(prefix);
523 sb.append("mPastRealtime=");
524 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
525 formatTimeMs(sb, mRealtimeStart / 1000);
526 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
527 pw.println(sb.toString());
528 }
529
530 public void add(TimeBaseObs observer) {
531 mObservers.add(observer);
532 }
533
534 public void remove(TimeBaseObs observer) {
535 if (!mObservers.remove(observer)) {
536 Slog.wtf(TAG, "Removed unknown observer: " + observer);
537 }
538 }
539
540 public void init(long uptime, long realtime) {
541 mRealtime = 0;
542 mUptime = 0;
543 mPastUptime = 0;
544 mPastRealtime = 0;
545 mUptimeStart = uptime;
546 mRealtimeStart = realtime;
547 mUnpluggedUptime = getUptime(mUptimeStart);
548 mUnpluggedRealtime = getRealtime(mRealtimeStart);
549 }
550
551 public void reset(long uptime, long realtime) {
552 if (!mRunning) {
553 mPastUptime = 0;
554 mPastRealtime = 0;
555 } else {
556 mUptimeStart = uptime;
557 mRealtimeStart = realtime;
558 mUnpluggedUptime = getUptime(uptime);
559 mUnpluggedRealtime = getRealtime(realtime);
560 }
561 }
562
563 public long computeUptime(long curTime, int which) {
564 switch (which) {
565 case STATS_SINCE_CHARGED:
566 return mUptime + getUptime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800567 case STATS_CURRENT:
568 return getUptime(curTime);
569 case STATS_SINCE_UNPLUGGED:
570 return getUptime(curTime) - mUnpluggedUptime;
571 }
572 return 0;
573 }
574
575 public long computeRealtime(long curTime, int which) {
576 switch (which) {
577 case STATS_SINCE_CHARGED:
578 return mRealtime + getRealtime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800579 case STATS_CURRENT:
580 return getRealtime(curTime);
581 case STATS_SINCE_UNPLUGGED:
582 return getRealtime(curTime) - mUnpluggedRealtime;
583 }
584 return 0;
585 }
586
587 public long getUptime(long curTime) {
588 long time = mPastUptime;
589 if (mRunning) {
590 time += curTime - mUptimeStart;
591 }
592 return time;
593 }
594
595 public long getRealtime(long curTime) {
596 long time = mPastRealtime;
597 if (mRunning) {
598 time += curTime - mRealtimeStart;
599 }
600 return time;
601 }
602
603 public long getUptimeStart() {
604 return mUptimeStart;
605 }
606
607 public long getRealtimeStart() {
608 return mRealtimeStart;
609 }
610
611 public boolean isRunning() {
612 return mRunning;
613 }
614
615 public boolean setRunning(boolean running, long uptime, long realtime) {
616 if (mRunning != running) {
617 mRunning = running;
618 if (running) {
619 mUptimeStart = uptime;
620 mRealtimeStart = realtime;
621 long batteryUptime = mUnpluggedUptime = getUptime(uptime);
622 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
623
624 for (int i = mObservers.size() - 1; i >= 0; i--) {
625 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
626 }
627 } else {
628 mPastUptime += uptime - mUptimeStart;
629 mPastRealtime += realtime - mRealtimeStart;
630
631 long batteryUptime = getUptime(uptime);
632 long batteryRealtime = getRealtime(realtime);
633
634 for (int i = mObservers.size() - 1; i >= 0; i--) {
635 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
636 }
637 }
638 return true;
639 }
640 return false;
641 }
642
643 public void readSummaryFromParcel(Parcel in) {
644 mUptime = in.readLong();
645 mRealtime = in.readLong();
646 }
647
648 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
649 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
650 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
651 }
652
653 public void readFromParcel(Parcel in) {
654 mRunning = false;
655 mUptime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800656 mPastUptime = in.readLong();
657 mUptimeStart = in.readLong();
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700658 mRealtime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800659 mPastRealtime = in.readLong();
660 mRealtimeStart = in.readLong();
661 mUnpluggedUptime = in.readLong();
662 mUnpluggedRealtime = in.readLong();
663 }
664
665 public void writeToParcel(Parcel out, long uptime, long realtime) {
666 final long runningUptime = getUptime(uptime);
667 final long runningRealtime = getRealtime(realtime);
668 out.writeLong(mUptime);
669 out.writeLong(runningUptime);
670 out.writeLong(mUptimeStart);
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700671 out.writeLong(mRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800672 out.writeLong(runningRealtime);
673 out.writeLong(mRealtimeStart);
674 out.writeLong(mUnpluggedUptime);
675 out.writeLong(mUnpluggedRealtime);
676 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800677 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700678
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800679 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700680 * State for keeping track of counting information.
681 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800682 public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
Christopher Tate4cee7252010-03-19 14:50:40 -0700683 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800684 final TimeBase mTimeBase;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700685 int mLoadedCount;
686 int mLastCount;
687 int mUnpluggedCount;
688 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700689
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800690 Counter(TimeBase timeBase, Parcel in) {
691 mTimeBase = timeBase;
Christopher Tate4cee7252010-03-19 14:50:40 -0700692 mPluggedCount = in.readInt();
693 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700694 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700695 mLastCount = 0;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700696 mUnpluggedCount = in.readInt();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800697 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700698 }
699
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800700 Counter(TimeBase timeBase) {
701 mTimeBase = timeBase;
702 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700703 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700704
Dianne Hackborn617f8772009-03-31 15:04:46 -0700705 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700706 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700707 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700708 out.writeInt(mUnpluggedCount);
709 }
710
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800711 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700712 mUnpluggedCount = mPluggedCount;
713 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700714 }
715
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800716 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700717 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700718 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700719
Dianne Hackborn617f8772009-03-31 15:04:46 -0700720 /**
721 * Writes a possibly null Counter to a Parcel.
722 *
723 * @param out the Parcel to be written to.
724 * @param counter a Counter, or null.
725 */
726 public static void writeCounterToParcel(Parcel out, Counter counter) {
727 if (counter == null) {
728 out.writeInt(0); // indicates null
729 return;
730 }
731 out.writeInt(1); // indicates non-null
732
733 counter.writeToParcel(out);
734 }
735
736 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700737 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700738 int val = mCount.get();
739 if (which == STATS_SINCE_UNPLUGGED) {
740 val -= mUnpluggedCount;
741 } else if (which != STATS_SINCE_CHARGED) {
742 val -= mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700743 }
744
745 return val;
746 }
747
748 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700749 pw.println(prefix + "mCount=" + mCount.get()
Dianne Hackborn617f8772009-03-31 15:04:46 -0700750 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
751 + " mUnpluggedCount=" + mUnpluggedCount
752 + " mPluggedCount=" + mPluggedCount);
753 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700754
Christopher Tate4cee7252010-03-19 14:50:40 -0700755 void stepAtomic() {
756 mCount.incrementAndGet();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700757 }
758
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700759 /**
760 * Clear state of this counter.
761 */
762 void reset(boolean detachIfReset) {
763 mCount.set(0);
764 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
765 if (detachIfReset) {
766 detach();
767 }
768 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700769
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700770 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800771 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700772 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700773
Dianne Hackborn617f8772009-03-31 15:04:46 -0700774 void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700775 int count = mCount.get();
776 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700777 }
778
779 void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700780 mLoadedCount = in.readInt();
781 mCount.set(mLoadedCount);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700782 mLastCount = 0;
Christopher Tate4cee7252010-03-19 14:50:40 -0700783 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700784 }
785 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700786
787 public static class SamplingCounter extends Counter {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800788 SamplingCounter(TimeBase timeBase, Parcel in) {
789 super(timeBase, in);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700790 }
791
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800792 SamplingCounter(TimeBase timeBase) {
793 super(timeBase);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700794 }
795
Christopher Tate4cee7252010-03-19 14:50:40 -0700796 public void addCountAtomic(long count) {
797 mCount.addAndGet((int)count);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700798 }
799 }
800
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700801 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800802 final TimeBase mTimeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700803 long mCount;
804 long mLoadedCount;
805 long mLastCount;
806 long mUnpluggedCount;
807 long mPluggedCount;
808
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800809 LongSamplingCounter(TimeBase timeBase, Parcel in) {
810 mTimeBase = timeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700811 mPluggedCount = in.readLong();
812 mCount = mPluggedCount;
813 mLoadedCount = in.readLong();
814 mLastCount = 0;
815 mUnpluggedCount = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800816 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700817 }
818
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800819 LongSamplingCounter(TimeBase timeBase) {
820 mTimeBase = timeBase;
821 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700822 }
823
824 public void writeToParcel(Parcel out) {
825 out.writeLong(mCount);
826 out.writeLong(mLoadedCount);
827 out.writeLong(mUnpluggedCount);
828 }
829
830 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800831 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700832 mUnpluggedCount = mPluggedCount;
833 mCount = mPluggedCount;
834 }
835
836 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800837 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700838 mPluggedCount = mCount;
839 }
840
841 public long getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700842 long val = mCount;
843 if (which == STATS_SINCE_UNPLUGGED) {
844 val -= mUnpluggedCount;
845 } else if (which != STATS_SINCE_CHARGED) {
846 val -= mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700847 }
848
849 return val;
850 }
851
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700852 @Override
853 public void logState(Printer pw, String prefix) {
854 pw.println(prefix + "mCount=" + mCount
855 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
856 + " mUnpluggedCount=" + mUnpluggedCount
857 + " mPluggedCount=" + mPluggedCount);
858 }
859
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700860 void addCountLocked(long count) {
861 mCount += count;
862 }
863
864 /**
865 * Clear state of this counter.
866 */
867 void reset(boolean detachIfReset) {
868 mCount = 0;
869 mLoadedCount = mLastCount = mPluggedCount = mUnpluggedCount = 0;
870 if (detachIfReset) {
871 detach();
872 }
873 }
874
875 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800876 mTimeBase.remove(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700877 }
878
879 void writeSummaryFromParcelLocked(Parcel out) {
880 out.writeLong(mCount);
881 }
882
883 void readSummaryFromParcelLocked(Parcel in) {
884 mLoadedCount = in.readLong();
885 mCount = mLoadedCount;
886 mLastCount = 0;
887 mUnpluggedCount = mPluggedCount = mLoadedCount;
888 }
889 }
890
Dianne Hackborn617f8772009-03-31 15:04:46 -0700891 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 * State for keeping track of timing information.
893 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800894 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 final int mType;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800896 final TimeBase mTimeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700897
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898 int mCount;
899 int mLoadedCount;
900 int mLastCount;
901 int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700902
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 // Times are in microseconds for better accuracy when dividing by the
904 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700905
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800906 /**
907 * The total time we have accumulated since the start of the original
908 * boot, to the last time something interesting happened in the
909 * current run.
910 */
911 long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800913 /**
914 * The total time we loaded for the previous runs. Subtract this from
915 * mTotalTime to find the time for the current run of the system.
916 */
917 long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700918
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 /**
920 * The run time of the last run of the system, as loaded from the
921 * saved data.
922 */
923 long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700924
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925 /**
926 * The value of mTotalTime when unplug() was last called. Subtract
927 * this from mTotalTime to find the time since the last unplug from
928 * power.
929 */
930 long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700931
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700932 /**
Adam Lesinskie08af192015-03-25 16:42:59 -0700933 * The total time this timer has been running until the latest mark has been set.
934 * Subtract this from mTotalTime to get the time spent running since the mark was set.
935 */
936 long mTimeBeforeMark;
937
938 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700939 * Constructs from a parcel.
940 * @param type
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800941 * @param timeBase
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700942 * @param in
943 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800944 Timer(int type, TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800946 mTimeBase = timeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700947
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800948 mCount = in.readInt();
949 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700950 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800951 mUnpluggedCount = in.readInt();
952 mTotalTime = in.readLong();
953 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700954 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 mUnpluggedTime = in.readLong();
Adam Lesinskie08af192015-03-25 16:42:59 -0700956 mTimeBeforeMark = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800957 timeBase.add(this);
Dianne Hackborn29325132014-05-21 15:01:03 -0700958 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800959 }
960
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800961 Timer(int type, TimeBase timeBase) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800962 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800963 mTimeBase = timeBase;
964 timeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800965 }
Evan Millarc64edde2009-04-18 12:26:32 -0700966
967 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700968
Evan Millarc64edde2009-04-18 12:26:32 -0700969 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700970
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700971 /**
972 * Clear state of this timer. Returns true if the timer is inactive
973 * so can be completely dropped.
974 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800975 boolean reset(boolean detachIfReset) {
Adam Lesinskie08af192015-03-25 16:42:59 -0700976 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700977 mCount = mLoadedCount = mLastCount = 0;
978 if (detachIfReset) {
979 detach();
980 }
981 return true;
982 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700983
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700984 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800985 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700986 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700987
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800988 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
Dianne Hackborn29325132014-05-21 15:01:03 -0700989 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
990 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800991 out.writeInt(mCount);
992 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800993 out.writeInt(mUnpluggedCount);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800994 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800995 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996 out.writeLong(mUnpluggedTime);
Adam Lesinskie08af192015-03-25 16:42:59 -0700997 out.writeLong(mTimeBeforeMark);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800998 }
999
Adam Lesinskie08af192015-03-25 16:42:59 -07001000 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001001 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001002 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001003 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001004 + " old mUnpluggedTime=" + mUnpluggedTime
1005 + " old mUnpluggedCount=" + mUnpluggedCount);
1006 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001007 mUnpluggedTime = computeRunTimeLocked(baseRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 mUnpluggedCount = mCount;
1009 if (DEBUG && mType < 0) {
1010 Log.v(TAG, "unplug #" + mType
1011 + ": new mUnpluggedTime=" + mUnpluggedTime
1012 + " new mUnpluggedCount=" + mUnpluggedCount);
1013 }
1014 }
1015
Adam Lesinskie08af192015-03-25 16:42:59 -07001016 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001017 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001018 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001019 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
Evan Millarc64edde2009-04-18 12:26:32 -07001020 + " old mTotalTime=" + mTotalTime);
1021 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001022 mTotalTime = computeRunTimeLocked(baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001023 mCount = computeCurrentCountLocked();
1024 if (DEBUG && mType < 0) {
1025 Log.v(TAG, "plug #" + mType
1026 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 }
1028 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001030 /**
1031 * Writes a possibly null Timer to a Parcel.
1032 *
1033 * @param out the Parcel to be written to.
1034 * @param timer a Timer, or null.
1035 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001036 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001037 if (timer == null) {
1038 out.writeInt(0); // indicates null
1039 return;
1040 }
1041 out.writeInt(1); // indicates non-null
1042
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001043 timer.writeToParcel(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001044 }
1045
1046 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001047 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001048 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1049 if (which == STATS_SINCE_UNPLUGGED) {
1050 val -= mUnpluggedTime;
1051 } else if (which != STATS_SINCE_CHARGED) {
1052 val -= mLoadedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053 }
1054
1055 return val;
1056 }
1057
1058 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001059 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001060 int val = computeCurrentCountLocked();
1061 if (which == STATS_SINCE_UNPLUGGED) {
1062 val -= mUnpluggedCount;
1063 } else if (which != STATS_SINCE_CHARGED) {
1064 val -= mLoadedCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001065 }
1066
1067 return val;
1068 }
1069
Adam Lesinskie08af192015-03-25 16:42:59 -07001070 @Override
1071 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) {
1072 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1073 return val - mTimeBeforeMark;
1074 }
1075
1076 @Override
Dianne Hackborn627bba72009-03-24 22:32:56 -07001077 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001078 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
1080 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001081 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001082 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001083 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001084 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001085 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001086
1087
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001088 void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
1089 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1090 out.writeLong(runTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001091 out.writeInt(mCount);
Evan Millarc64edde2009-04-18 12:26:32 -07001092 }
1093
1094 void readSummaryFromParcelLocked(Parcel in) {
1095 // Multiply by 1000 for backwards compatibility
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001096 mTotalTime = mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001097 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001098 mUnpluggedTime = mTotalTime;
1099 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001100 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001101 mUnpluggedCount = mCount;
Adam Lesinskie08af192015-03-25 16:42:59 -07001102
1103 // When reading the summary, we set the mark to be the latest information.
1104 mTimeBeforeMark = mTotalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001105 }
1106 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001107
Evan Millarc64edde2009-04-18 12:26:32 -07001108 public static final class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001109
Evan Millarc64edde2009-04-18 12:26:32 -07001110 /**
1111 * The most recent reported count from /proc/wakelocks.
1112 */
1113 int mCurrentReportedCount;
1114
1115 /**
1116 * The reported count from /proc/wakelocks when unplug() was last
1117 * called.
1118 */
1119 int mUnpluggedReportedCount;
1120
1121 /**
1122 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001123 */
Evan Millarc64edde2009-04-18 12:26:32 -07001124 long mCurrentReportedTotalTime;
1125
1126
1127 /**
1128 * The reported total_time from /proc/wakelocks when unplug() was last
1129 * called.
1130 */
1131 long mUnpluggedReportedTotalTime;
1132
1133 /**
1134 * Whether we are currently in a discharge cycle.
1135 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001136 boolean mTimeBaseRunning;
Evan Millarc64edde2009-04-18 12:26:32 -07001137
1138 /**
1139 * Whether we are currently recording reported values.
1140 */
1141 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001142
Evan Millarc64edde2009-04-18 12:26:32 -07001143 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001144 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -07001145 */
1146 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001147
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001148 SamplingTimer(TimeBase timeBase, Parcel in) {
1149 super(0, timeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07001150 mCurrentReportedCount = in.readInt();
1151 mUnpluggedReportedCount = in.readInt();
1152 mCurrentReportedTotalTime = in.readLong();
1153 mUnpluggedReportedTotalTime = in.readLong();
1154 mTrackingReportedValues = in.readInt() == 1;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001155 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001156 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001157
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001158 SamplingTimer(TimeBase timeBase, boolean trackReportedValues) {
1159 super(0, timeBase);
Evan Millarc64edde2009-04-18 12:26:32 -07001160 mTrackingReportedValues = trackReportedValues;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001161 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001162 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001163
Evan Millarc64edde2009-04-18 12:26:32 -07001164 public void setStale() {
1165 mTrackingReportedValues = false;
1166 mUnpluggedReportedTotalTime = 0;
1167 mUnpluggedReportedCount = 0;
1168 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001169
Evan Millarc64edde2009-04-18 12:26:32 -07001170 public void setUpdateVersion(int version) {
1171 mUpdateVersion = version;
1172 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001173
Evan Millarc64edde2009-04-18 12:26:32 -07001174 public int getUpdateVersion() {
1175 return mUpdateVersion;
1176 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001177
Evan Millarc64edde2009-04-18 12:26:32 -07001178 public void updateCurrentReportedCount(int count) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001179 if (mTimeBaseRunning && mUnpluggedReportedCount == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001180 // Updating the reported value for the first time.
1181 mUnpluggedReportedCount = count;
1182 // If we are receiving an update update mTrackingReportedValues;
1183 mTrackingReportedValues = true;
1184 }
1185 mCurrentReportedCount = count;
1186 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001187
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001188 public void addCurrentReportedCount(int delta) {
1189 updateCurrentReportedCount(mCurrentReportedCount + delta);
1190 }
1191
Evan Millarc64edde2009-04-18 12:26:32 -07001192 public void updateCurrentReportedTotalTime(long totalTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001193 if (mTimeBaseRunning && mUnpluggedReportedTotalTime == 0) {
Evan Millarc64edde2009-04-18 12:26:32 -07001194 // Updating the reported value for the first time.
1195 mUnpluggedReportedTotalTime = totalTime;
1196 // If we are receiving an update update mTrackingReportedValues;
1197 mTrackingReportedValues = true;
1198 }
1199 mCurrentReportedTotalTime = totalTime;
1200 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001201
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001202 public void addCurrentReportedTotalTime(long delta) {
1203 updateCurrentReportedTotalTime(mCurrentReportedTotalTime + delta);
1204 }
1205
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001206 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1207 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001208 if (mTrackingReportedValues) {
1209 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
1210 mUnpluggedReportedCount = mCurrentReportedCount;
1211 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001212 mTimeBaseRunning = true;
Evan Millarc64edde2009-04-18 12:26:32 -07001213 }
1214
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001215 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1216 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1217 mTimeBaseRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001218 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001219
Evan Millarc64edde2009-04-18 12:26:32 -07001220 public void logState(Printer pw, String prefix) {
1221 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001222 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -07001223 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
1224 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
1225 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
1226 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001227
Evan Millarc64edde2009-04-18 12:26:32 -07001228 protected long computeRunTimeLocked(long curBatteryRealtime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001229 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001230 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
1231 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001232
Evan Millarc64edde2009-04-18 12:26:32 -07001233 protected int computeCurrentCountLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001234 return mCount + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001235 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
1236 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001237
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001238 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1239 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001240 out.writeInt(mCurrentReportedCount);
1241 out.writeInt(mUnpluggedReportedCount);
1242 out.writeLong(mCurrentReportedTotalTime);
1243 out.writeLong(mUnpluggedReportedTotalTime);
1244 out.writeInt(mTrackingReportedValues ? 1 : 0);
1245 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001246
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001247 boolean reset(boolean detachIfReset) {
1248 super.reset(detachIfReset);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001249 setStale();
1250 return true;
1251 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001252
Evan Millarc64edde2009-04-18 12:26:32 -07001253 void writeSummaryFromParcelLocked(Parcel out, long batteryRealtime) {
1254 super.writeSummaryFromParcelLocked(out, batteryRealtime);
1255 out.writeLong(mCurrentReportedTotalTime);
1256 out.writeInt(mCurrentReportedCount);
1257 out.writeInt(mTrackingReportedValues ? 1 : 0);
1258 }
1259
1260 void readSummaryFromParcelLocked(Parcel in) {
1261 super.readSummaryFromParcelLocked(in);
1262 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = in.readLong();
1263 mUnpluggedReportedCount = mCurrentReportedCount = in.readInt();
1264 mTrackingReportedValues = in.readInt() == 1;
1265 }
1266 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001267
Evan Millarc64edde2009-04-18 12:26:32 -07001268 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001269 * A timer that increments in batches. It does not run for durations, but just jumps
1270 * for a pre-determined amount.
1271 */
1272 public static final class BatchTimer extends Timer {
1273 final Uid mUid;
1274
1275 /**
1276 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
1277 */
1278 long mLastAddedTime;
1279
1280 /**
1281 * The last duration that we added to the timer. This is in microseconds.
1282 */
1283 long mLastAddedDuration;
1284
1285 /**
1286 * Whether we are currently in a discharge cycle.
1287 */
1288 boolean mInDischarge;
1289
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001290 BatchTimer(Uid uid, int type, TimeBase timeBase, Parcel in) {
1291 super(type, timeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001292 mUid = uid;
1293 mLastAddedTime = in.readLong();
1294 mLastAddedDuration = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001295 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001296 }
1297
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001298 BatchTimer(Uid uid, int type, TimeBase timeBase) {
1299 super(type, timeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001300 mUid = uid;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001301 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001302 }
1303
1304 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001305 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1306 super.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001307 out.writeLong(mLastAddedTime);
1308 out.writeLong(mLastAddedDuration);
1309 }
1310
1311 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001312 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001313 recomputeLastDuration(SystemClock.elapsedRealtime() * 1000, false);
1314 mInDischarge = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001315 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001316 }
1317
1318 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001319 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001320 recomputeLastDuration(elapsedRealtime, false);
1321 mInDischarge = true;
1322 // If we are still within the last added duration, then re-added whatever remains.
1323 if (mLastAddedTime == elapsedRealtime) {
1324 mTotalTime += mLastAddedDuration;
1325 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001326 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001327 }
1328
1329 @Override
1330 public void logState(Printer pw, String prefix) {
1331 super.logState(pw, prefix);
1332 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
1333 + " mLastAddedDuration=" + mLastAddedDuration);
1334 }
1335
1336 private long computeOverage(long curTime) {
1337 if (mLastAddedTime > 0) {
1338 return mLastTime + mLastAddedDuration - curTime;
1339 }
1340 return 0;
1341 }
1342
1343 private void recomputeLastDuration(long curTime, boolean abort) {
1344 final long overage = computeOverage(curTime);
1345 if (overage > 0) {
1346 // Aborting before the duration ran out -- roll back the remaining
1347 // duration. Only do this if currently discharging; otherwise we didn't
1348 // actually add the time.
1349 if (mInDischarge) {
1350 mTotalTime -= overage;
1351 }
1352 if (abort) {
1353 mLastAddedTime = 0;
1354 } else {
1355 mLastAddedTime = curTime;
1356 mLastAddedDuration -= overage;
1357 }
1358 }
1359 }
1360
1361 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
1362 final long now = SystemClock.elapsedRealtime() * 1000;
1363 recomputeLastDuration(now, true);
1364 mLastAddedTime = now;
1365 mLastAddedDuration = durationMillis * 1000;
1366 if (mInDischarge) {
1367 mTotalTime += mLastAddedDuration;
1368 mCount++;
1369 }
1370 }
1371
1372 public void abortLastDuration(BatteryStatsImpl stats) {
1373 final long now = SystemClock.elapsedRealtime() * 1000;
1374 recomputeLastDuration(now, true);
1375 }
1376
1377 @Override
1378 protected int computeCurrentCountLocked() {
1379 return mCount;
1380 }
1381
1382 @Override
1383 protected long computeRunTimeLocked(long curBatteryRealtime) {
1384 final long overage = computeOverage(SystemClock.elapsedRealtime() * 1000);
1385 if (overage > 0) {
1386 return mTotalTime = overage;
1387 }
1388 return mTotalTime;
1389 }
1390
1391 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001392 boolean reset(boolean detachIfReset) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001393 final long now = SystemClock.elapsedRealtime() * 1000;
1394 recomputeLastDuration(now, true);
1395 boolean stillActive = mLastAddedTime == now;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001396 super.reset(!stillActive && detachIfReset);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001397 return !stillActive;
1398 }
1399 }
1400
1401 /**
Evan Millarc64edde2009-04-18 12:26:32 -07001402 * State for keeping track of timing information.
1403 */
1404 public static final class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001405 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07001406 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001407
Evan Millarc64edde2009-04-18 12:26:32 -07001408 int mNesting;
1409
Evan Millarc64edde2009-04-18 12:26:32 -07001410 /**
1411 * The last time at which we updated the timer. If mNesting is > 0,
1412 * subtract this from the current battery time to find the amount of
1413 * time we have been running since we last computed an update.
1414 */
1415 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001416
Evan Millarc64edde2009-04-18 12:26:32 -07001417 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001418 * The total time at which the timer was acquired, to determine if it
Evan Millarc64edde2009-04-18 12:26:32 -07001419 * was actually held for an interesting duration.
1420 */
1421 long mAcquireTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001422
Amith Yamasanif37447b2009-10-08 18:28:01 -07001423 long mTimeout;
1424
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001425 /**
1426 * For partial wake locks, keep track of whether we are in the list
1427 * to consume CPU cycles.
1428 */
1429 boolean mInList;
1430
1431 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001432 TimeBase timeBase, Parcel in) {
1433 super(type, timeBase, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001434 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001435 mTimerPool = timerPool;
1436 mUpdateTime = in.readLong();
1437 }
1438
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001439 StopwatchTimer(Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001440 TimeBase timeBase) {
1441 super(type, timeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001442 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07001443 mTimerPool = timerPool;
1444 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001445
Amith Yamasanif37447b2009-10-08 18:28:01 -07001446 void setTimeout(long timeout) {
1447 mTimeout = timeout;
1448 }
1449
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001450 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1451 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001452 out.writeLong(mUpdateTime);
1453 }
1454
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001455 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001456 if (mNesting > 0) {
1457 if (DEBUG && mType < 0) {
1458 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
1459 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001460 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1461 mUpdateTime = baseRealtime;
Evan Millarc64edde2009-04-18 12:26:32 -07001462 if (DEBUG && mType < 0) {
1463 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
1464 }
1465 }
1466 }
1467
1468 public void logState(Printer pw, String prefix) {
1469 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001470 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001471 + " mAcquireTime=" + mAcquireTime);
1472 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001473
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001474 void startRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001475 if (mNesting++ == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001476 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001477 mUpdateTime = batteryRealtime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 if (mTimerPool != null) {
1479 // Accumulate time to all currently active timers before adding
1480 // this new one to the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001481 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001482 // Add this timer to the active pool
1483 mTimerPool.add(this);
1484 }
1485 // Increment the count
1486 mCount++;
1487 mAcquireTime = mTotalTime;
1488 if (DEBUG && mType < 0) {
1489 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
1490 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1491 + " mAcquireTime=" + mAcquireTime);
1492 }
1493 }
1494 }
1495
Amith Yamasani32dbefd2009-06-19 09:21:17 -07001496 boolean isRunningLocked() {
1497 return mNesting > 0;
1498 }
1499
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001500 void stopRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 // Ignore attempt to stop a timer that isn't running
1502 if (mNesting == 0) {
1503 return;
1504 }
1505 if (--mNesting == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001506 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 if (mTimerPool != null) {
1508 // Accumulate time to all active counters, scaled by the total
1509 // active in the pool, before taking this one out of the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001510 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 // Remove this timer from the active pool
1512 mTimerPool.remove(this);
1513 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001514 mNesting = 1;
1515 mTotalTime = computeRunTimeLocked(batteryRealtime);
1516 mNesting = 0;
1517 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001518
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001519 if (DEBUG && mType < 0) {
1520 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
1521 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
1522 + " mAcquireTime=" + mAcquireTime);
1523 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001525 if (mTotalTime == mAcquireTime) {
1526 // If there was no change in the time, then discard this
1527 // count. A somewhat cheezy strategy, but hey.
1528 mCount--;
1529 }
1530 }
1531 }
1532
Dianne Hackborn10eaa852014-07-22 22:54:55 -07001533 void stopAllRunningLocked(long elapsedRealtimeMs) {
1534 if (mNesting > 0) {
1535 mNesting = 1;
1536 stopRunningLocked(elapsedRealtimeMs);
1537 }
1538 }
1539
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001540 // Update the total time for all other running Timers with the same type as this Timer
1541 // due to a change in timer count
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001542 private static long refreshTimersLocked(long batteryRealtime,
1543 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001544 long selfTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 final int N = pool.size();
1546 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07001547 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 long heldTime = batteryRealtime - t.mUpdateTime;
1549 if (heldTime > 0) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001550 final long myTime = heldTime / N;
1551 if (t == self) {
1552 selfTime = myTime;
1553 }
1554 t.mTotalTime += myTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 }
1556 t.mUpdateTime = batteryRealtime;
1557 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08001558 return selfTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 }
1560
Evan Millarc64edde2009-04-18 12:26:32 -07001561 @Override
1562 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07001563 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
1564 curBatteryRealtime = mUpdateTime + mTimeout;
1565 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001566 return mTotalTime + (mNesting > 0
1567 ? (curBatteryRealtime - mUpdateTime)
1568 / (mTimerPool != null ? mTimerPool.size() : 1)
1569 : 0);
1570 }
1571
Evan Millarc64edde2009-04-18 12:26:32 -07001572 @Override
1573 protected int computeCurrentCountLocked() {
1574 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001575 }
1576
Adam Lesinskie08af192015-03-25 16:42:59 -07001577 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001578 boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001579 boolean canDetach = mNesting <= 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001580 super.reset(canDetach && detachIfReset);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001581 if (mNesting > 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001582 mUpdateTime = mTimeBase.getRealtime(SystemClock.elapsedRealtime() * 1000);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07001583 }
1584 mAcquireTime = mTotalTime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001585 return canDetach;
1586 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001587
Adam Lesinskie08af192015-03-25 16:42:59 -07001588 @Override
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001589 void detach() {
1590 super.detach();
1591 if (mTimerPool != null) {
1592 mTimerPool.remove(this);
1593 }
1594 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001595
Adam Lesinskie08af192015-03-25 16:42:59 -07001596 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001597 void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001598 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001599 mNesting = 0;
1600 }
Adam Lesinskie08af192015-03-25 16:42:59 -07001601
1602 /**
1603 * Set the mark so that we can query later for the total time the timer has
1604 * accumulated since this point. The timer can be running or not.
1605 *
1606 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds.
1607 */
1608 public void setMark(long elapsedRealtimeMs) {
1609 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
1610 if (mNesting > 0) {
1611 // We are running.
1612 if (mTimerPool != null) {
1613 refreshTimersLocked(batteryRealtime, mTimerPool, this);
1614 } else {
1615 mTotalTime += batteryRealtime - mUpdateTime;
1616 mUpdateTime = batteryRealtime;
1617 }
1618 }
1619 mTimeBeforeMark = mTotalTime;
1620 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001621 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001622
Dianne Hackbornd953c532014-08-16 18:17:38 -07001623 public abstract class OverflowArrayMap<T> {
1624 private static final String OVERFLOW_NAME = "*overflow*";
1625
1626 final ArrayMap<String, T> mMap = new ArrayMap<>();
1627 T mCurOverflow;
1628 ArrayMap<String, MutableInt> mActiveOverflow;
1629
1630 public OverflowArrayMap() {
1631 }
1632
1633 public ArrayMap<String, T> getMap() {
1634 return mMap;
1635 }
1636
1637 public void clear() {
1638 mMap.clear();
1639 mCurOverflow = null;
1640 mActiveOverflow = null;
1641 }
1642
1643 public void add(String name, T obj) {
1644 mMap.put(name, obj);
1645 if (OVERFLOW_NAME.equals(name)) {
1646 mCurOverflow = obj;
1647 }
1648 }
1649
1650 public void cleanup() {
1651 if (mActiveOverflow != null) {
1652 if (mActiveOverflow.size() == 0) {
1653 mActiveOverflow = null;
1654 }
1655 }
1656 if (mActiveOverflow == null) {
1657 // There is no currently active overflow, so we should no longer have
1658 // an overflow entry.
1659 if (mMap.containsKey(OVERFLOW_NAME)) {
1660 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry "
1661 + mMap.get(OVERFLOW_NAME));
1662 mMap.remove(OVERFLOW_NAME);
1663 }
1664 mCurOverflow = null;
1665 } else {
1666 // There is currently active overflow, so we should still have an overflow entry.
1667 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) {
1668 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur="
1669 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME));
1670 }
1671 }
1672 }
1673
1674 public T startObject(String name) {
1675 T obj = mMap.get(name);
1676 if (obj != null) {
1677 return obj;
1678 }
1679
1680 // No object exists for the given name, but do we currently have it
1681 // running as part of the overflow?
1682 if (mActiveOverflow != null) {
1683 MutableInt over = mActiveOverflow.get(name);
1684 if (over != null) {
1685 // We are already actively counting this name in the overflow object.
1686 obj = mCurOverflow;
1687 if (obj == null) {
1688 // Shouldn't be here, but we'll try to recover.
1689 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow");
1690 obj = mCurOverflow = instantiateObject();
1691 mMap.put(OVERFLOW_NAME, obj);
1692 }
1693 over.value++;
1694 return obj;
1695 }
1696 }
1697
1698 // No object exists for given name nor in the overflow; we need to make
1699 // a new one.
1700 final int N = mMap.size();
1701 if (N >= MAX_WAKELOCKS_PER_UID) {
1702 // Went over the limit on number of objects to track; this one goes
1703 // in to the overflow.
1704 obj = mCurOverflow;
1705 if (obj == null) {
1706 // Need to start overflow now...
1707 obj = mCurOverflow = instantiateObject();
1708 mMap.put(OVERFLOW_NAME, obj);
1709 }
1710 if (mActiveOverflow == null) {
1711 mActiveOverflow = new ArrayMap<>();
1712 }
1713 mActiveOverflow.put(name, new MutableInt(1));
1714 return obj;
1715 }
1716
1717 // Normal case where we just need to make a new object.
1718 obj = instantiateObject();
1719 mMap.put(name, obj);
1720 return obj;
1721 }
1722
1723 public T stopObject(String name) {
1724 T obj = mMap.get(name);
1725 if (obj != null) {
1726 return obj;
1727 }
1728
1729 // No object exists for the given name, but do we currently have it
1730 // running as part of the overflow?
1731 if (mActiveOverflow != null) {
1732 MutableInt over = mActiveOverflow.get(name);
1733 if (over != null) {
1734 // We are already actively counting this name in the overflow object.
1735 obj = mCurOverflow;
1736 if (obj != null) {
1737 over.value--;
1738 if (over.value <= 0) {
1739 mActiveOverflow.remove(name);
1740 }
1741 return obj;
1742 }
1743 }
1744 }
1745
1746 // Huh, they are stopping an active operation but we can't find one!
1747 // That's not good.
1748 Slog.wtf(TAG, "Unable to find object for " + name + " mapsize="
1749 + mMap.size() + " activeoverflow=" + mActiveOverflow
1750 + " curoverflow=" + mCurOverflow);
1751 return null;
1752 }
1753
1754 public abstract T instantiateObject();
1755 }
1756
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001757 /*
1758 * Get the wakeup reason counter, and create a new one if one
1759 * doesn't already exist.
1760 */
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001761 public SamplingTimer getWakeupReasonTimerLocked(String name) {
1762 SamplingTimer timer = mWakeupReasonStats.get(name);
1763 if (timer == null) {
1764 timer = new SamplingTimer(mOnBatteryTimeBase, true);
1765 mWakeupReasonStats.put(name, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001766 }
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001767 return timer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001768 }
1769
Evan Millarc64edde2009-04-18 12:26:32 -07001770 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001771 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07001772 * doesn't already exist.
1773 */
1774 public SamplingTimer getKernelWakelockTimerLocked(String name) {
1775 SamplingTimer kwlt = mKernelWakelockStats.get(name);
1776 if (kwlt == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001777 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, true /* track reported values */);
Evan Millarc64edde2009-04-18 12:26:32 -07001778 mKernelWakelockStats.put(name, kwlt);
1779 }
1780 return kwlt;
1781 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07001782
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001783 private int getCurrentBluetoothPingCount() {
1784 if (mBtHeadset != null) {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001785 List<BluetoothDevice> deviceList = mBtHeadset.getConnectedDevices();
1786 if (deviceList.size() > 0) {
1787 return mBtHeadset.getBatteryUsageHint(deviceList.get(0));
Jaikumar Ganesh3f034962010-09-27 17:02:23 -07001788 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001789 }
1790 return -1;
1791 }
1792
1793 public int getBluetoothPingCount() {
1794 if (mBluetoothPingStart == -1) {
1795 return mBluetoothPingCount;
1796 } else if (mBtHeadset != null) {
1797 return getCurrentBluetoothPingCount() - mBluetoothPingStart;
1798 }
Amith Yamasani82cb0292009-08-18 11:29:28 -07001799 return 0;
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001800 }
1801
1802 public void setBtHeadset(BluetoothHeadset headset) {
Amith Yamasani82cb0292009-08-18 11:29:28 -07001803 if (headset != null && mBtHeadset == null && isOnBattery() && mBluetoothPingStart == -1) {
1804 mBluetoothPingStart = getCurrentBluetoothPingCount();
1805 }
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07001806 mBtHeadset = headset;
1807 }
1808
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001809 private int writeHistoryTag(HistoryTag tag) {
1810 Integer idxObj = mHistoryTagPool.get(tag);
1811 int idx;
1812 if (idxObj != null) {
1813 idx = idxObj;
1814 } else {
1815 idx = mNextHistoryTagIdx;
1816 HistoryTag key = new HistoryTag();
1817 key.setTo(tag);
1818 tag.poolIdx = idx;
1819 mHistoryTagPool.put(key, idx);
1820 mNextHistoryTagIdx++;
1821 mNumHistoryTagChars += key.string.length() + 1;
1822 }
1823 return idx;
1824 }
1825
1826 private void readHistoryTag(int index, HistoryTag tag) {
1827 tag.string = mReadHistoryStrings[index];
1828 tag.uid = mReadHistoryUids[index];
1829 tag.poolIdx = index;
1830 }
1831
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001832 // Part of initial delta int that specifies the time delta.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001833 static final int DELTA_TIME_MASK = 0x7ffff;
1834 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
1835 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
1836 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001837 // Flag in delta int: a new battery level int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001838 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001839 // Flag in delta int: a new full state and battery status int follows.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08001840 static final int DELTA_STATE_FLAG = 0x00100000;
1841 // Flag in delta int: a new full state2 int follows.
1842 static final int DELTA_STATE2_FLAG = 0x00200000;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001843 // Flag in delta int: contains a wakelock or wakeReason tag.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001844 static final int DELTA_WAKELOCK_FLAG = 0x00400000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001845 // Flag in delta int: contains an event description.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001846 static final int DELTA_EVENT_FLAG = 0x00800000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001847 // These upper bits are the frequently changing state bits.
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001848 static final int DELTA_STATE_MASK = 0xff000000;
1849
1850 // These are the pieces of battery state that are packed in to the upper bits of
1851 // the state int that have been packed in to the first delta int. They must fit
1852 // in DELTA_STATE_MASK.
1853 static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
1854 static final int STATE_BATTERY_STATUS_SHIFT = 29;
1855 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
1856 static final int STATE_BATTERY_HEALTH_SHIFT = 26;
1857 static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
1858 static final int STATE_BATTERY_PLUG_SHIFT = 24;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001859
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001860 // We use the low bit of the battery state int to indicate that we have full details
1861 // from a battery level change.
1862 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001;
1863
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001864 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001865 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001866 dest.writeInt(DELTA_TIME_ABS);
1867 cur.writeToParcel(dest, 0);
1868 return;
1869 }
1870
1871 final long deltaTime = cur.time - last.time;
1872 final int lastBatteryLevelInt = buildBatteryLevelInt(last);
1873 final int lastStateInt = buildStateInt(last);
1874
1875 int deltaTimeToken;
1876 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
1877 deltaTimeToken = DELTA_TIME_LONG;
1878 } else if (deltaTime >= DELTA_TIME_ABS) {
1879 deltaTimeToken = DELTA_TIME_INT;
1880 } else {
1881 deltaTimeToken = (int)deltaTime;
1882 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001883 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001884 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel
1885 ? BATTERY_DELTA_LEVEL_FLAG : 0;
1886 final boolean computeStepDetails = includeStepDetails != 0
1887 || mLastHistoryStepDetails == null;
1888 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001889 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
1890 if (batteryLevelIntChanged) {
1891 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
1892 }
1893 final int stateInt = buildStateInt(cur);
1894 final boolean stateIntChanged = stateInt != lastStateInt;
1895 if (stateIntChanged) {
1896 firstToken |= DELTA_STATE_FLAG;
1897 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001898 final boolean state2IntChanged = cur.states2 != last.states2;
1899 if (state2IntChanged) {
1900 firstToken |= DELTA_STATE2_FLAG;
1901 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001902 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001903 firstToken |= DELTA_WAKELOCK_FLAG;
1904 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001905 if (cur.eventCode != HistoryItem.EVENT_NONE) {
1906 firstToken |= DELTA_EVENT_FLAG;
1907 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001908 dest.writeInt(firstToken);
1909 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
1910 + " deltaTime=" + deltaTime);
1911
1912 if (deltaTimeToken >= DELTA_TIME_INT) {
1913 if (deltaTimeToken == DELTA_TIME_INT) {
1914 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
1915 dest.writeInt((int)deltaTime);
1916 } else {
1917 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
1918 dest.writeLong(deltaTime);
1919 }
1920 }
1921 if (batteryLevelIntChanged) {
1922 dest.writeInt(batteryLevelInt);
1923 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
1924 + Integer.toHexString(batteryLevelInt)
1925 + " batteryLevel=" + cur.batteryLevel
1926 + " batteryTemp=" + cur.batteryTemperature
1927 + " batteryVolt=" + (int)cur.batteryVoltage);
1928 }
1929 if (stateIntChanged) {
1930 dest.writeInt(stateInt);
1931 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
1932 + Integer.toHexString(stateInt)
1933 + " batteryStatus=" + cur.batteryStatus
1934 + " batteryHealth=" + cur.batteryHealth
1935 + " batteryPlugType=" + cur.batteryPlugType
1936 + " states=0x" + Integer.toHexString(cur.states));
1937 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001938 if (state2IntChanged) {
1939 dest.writeInt(cur.states2);
1940 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
1941 + Integer.toHexString(cur.states2));
1942 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001943 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
1944 int wakeLockIndex;
1945 int wakeReasonIndex;
1946 if (cur.wakelockTag != null) {
1947 wakeLockIndex = writeHistoryTag(cur.wakelockTag);
1948 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
1949 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
1950 } else {
1951 wakeLockIndex = 0xffff;
1952 }
1953 if (cur.wakeReasonTag != null) {
1954 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
1955 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
1956 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
1957 } else {
1958 wakeReasonIndex = 0xffff;
1959 }
1960 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001961 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001962 if (cur.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001963 int index = writeHistoryTag(cur.eventTag);
1964 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
Dianne Hackborn099bc622014-01-22 13:39:16 -08001965 dest.writeInt(codeAndIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08001966 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
1967 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
1968 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001969 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001970 if (computeStepDetails) {
1971 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
1972 if (includeStepDetails != 0) {
1973 mCurHistoryStepDetails.writeToParcel(dest);
1974 }
1975 cur.stepDetails = mCurHistoryStepDetails;
1976 mLastHistoryStepDetails = mCurHistoryStepDetails;
1977 } else {
1978 cur.stepDetails = null;
1979 }
1980 if (mLastHistoryStepLevel < cur.batteryLevel) {
1981 mLastHistoryStepDetails = null;
1982 }
1983 mLastHistoryStepLevel = cur.batteryLevel;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001984 }
1985
1986 private int buildBatteryLevelInt(HistoryItem h) {
1987 return ((((int)h.batteryLevel)<<25)&0xfe000000)
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08001988 | ((((int)h.batteryTemperature)<<14)&0x01ff8000)
1989 | ((((int)h.batteryVoltage)<<1)&0x00007fff);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08001990 }
1991
1992 private int buildStateInt(HistoryItem h) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08001993 int plugType = 0;
1994 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
1995 plugType = 1;
1996 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
1997 plugType = 2;
1998 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
1999 plugType = 3;
2000 }
2001 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
2002 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
2003 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002004 | (h.states&(~DELTA_STATE_MASK));
2005 }
2006
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002007 private void computeHistoryStepDetails(final HistoryStepDetails out,
2008 final HistoryStepDetails last) {
2009 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out;
2010
2011 // Perform a CPU update right after we do this collection, so we have started
2012 // collecting good data for the next step.
2013 requestImmediateCpuUpdate();
2014
2015 if (last == null) {
2016 // We are not generating a delta, so all we need to do is reset the stats
2017 // we will later be doing a delta from.
2018 final int NU = mUidStats.size();
2019 for (int i=0; i<NU; i++) {
2020 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
2021 uid.mLastStepUserTime = uid.mCurStepUserTime;
2022 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
2023 }
2024 mLastStepCpuUserTime = mCurStepCpuUserTime;
2025 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
2026 mLastStepStatUserTime = mCurStepStatUserTime;
2027 mLastStepStatSystemTime = mCurStepStatSystemTime;
2028 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
2029 mLastStepStatIrqTime = mCurStepStatIrqTime;
2030 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
2031 mLastStepStatIdleTime = mCurStepStatIdleTime;
2032 tmp.clear();
2033 return;
2034 }
2035 if (DEBUG) {
2036 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys="
2037 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime
2038 + " irq=" + mLastStepStatIrqTime + " sirq="
2039 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime);
2040 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys="
2041 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime
2042 + " irq=" + mCurStepStatIrqTime + " sirq="
2043 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime);
2044 }
2045 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime);
2046 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime);
2047 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime);
2048 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime);
2049 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime);
2050 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime);
2051 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime);
2052 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime);
2053 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1;
2054 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0;
2055 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0;
2056 final int NU = mUidStats.size();
2057 for (int i=0; i<NU; i++) {
2058 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
2059 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime);
2060 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime);
2061 final int totalTime = totalUTime + totalSTime;
2062 uid.mLastStepUserTime = uid.mCurStepUserTime;
2063 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
2064 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) {
2065 continue;
2066 }
2067 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) {
2068 out.appCpuUid3 = uid.mUid;
2069 out.appCpuUTime3 = totalUTime;
2070 out.appCpuSTime3 = totalSTime;
2071 } else {
2072 out.appCpuUid3 = out.appCpuUid2;
2073 out.appCpuUTime3 = out.appCpuUTime2;
2074 out.appCpuSTime3 = out.appCpuSTime2;
2075 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) {
2076 out.appCpuUid2 = uid.mUid;
2077 out.appCpuUTime2 = totalUTime;
2078 out.appCpuSTime2 = totalSTime;
2079 } else {
2080 out.appCpuUid2 = out.appCpuUid1;
2081 out.appCpuUTime2 = out.appCpuUTime1;
2082 out.appCpuSTime2 = out.appCpuSTime1;
2083 out.appCpuUid1 = uid.mUid;
2084 out.appCpuUTime1 = totalUTime;
2085 out.appCpuSTime1 = totalSTime;
2086 }
2087 }
2088 }
2089 mLastStepCpuUserTime = mCurStepCpuUserTime;
2090 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
2091 mLastStepStatUserTime = mCurStepStatUserTime;
2092 mLastStepStatSystemTime = mCurStepStatSystemTime;
2093 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
2094 mLastStepStatIrqTime = mCurStepStatIrqTime;
2095 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
2096 mLastStepStatIdleTime = mCurStepStatIdleTime;
2097 }
2098
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002099 public void readHistoryDelta(Parcel src, HistoryItem cur) {
2100 int firstToken = src.readInt();
2101 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002102 cur.cmd = HistoryItem.CMD_UPDATE;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002103 cur.numReadInts = 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002104 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
2105 + " deltaTimeToken=" + deltaTimeToken);
2106
2107 if (deltaTimeToken < DELTA_TIME_ABS) {
2108 cur.time += deltaTimeToken;
2109 } else if (deltaTimeToken == DELTA_TIME_ABS) {
2110 cur.time = src.readLong();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002111 cur.numReadInts += 2;
2112 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002113 cur.readFromParcel(src);
2114 return;
2115 } else if (deltaTimeToken == DELTA_TIME_INT) {
2116 int delta = src.readInt();
2117 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002118 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002119 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
2120 } else {
2121 long delta = src.readLong();
2122 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
2123 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002124 cur.numReadInts += 2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002125 }
2126
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002127 final int batteryLevelInt;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002128 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002129 batteryLevelInt = src.readInt();
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002130 cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f);
2131 cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21);
2132 cur.batteryVoltage = (char)(batteryLevelInt&0x3fff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002133 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002134 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
2135 + Integer.toHexString(batteryLevelInt)
2136 + " batteryLevel=" + cur.batteryLevel
2137 + " batteryTemp=" + cur.batteryTemperature
2138 + " batteryVolt=" + (int)cur.batteryVoltage);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002139 } else {
2140 batteryLevelInt = 0;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002141 }
2142
2143 if ((firstToken&DELTA_STATE_FLAG) != 0) {
2144 int stateInt = src.readInt();
2145 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~DELTA_STATE_MASK));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002146 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
2147 & STATE_BATTERY_STATUS_MASK);
2148 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
2149 & STATE_BATTERY_HEALTH_MASK);
2150 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
2151 & STATE_BATTERY_PLUG_MASK);
2152 switch (cur.batteryPlugType) {
2153 case 1:
2154 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
2155 break;
2156 case 2:
2157 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
2158 break;
2159 case 3:
2160 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
2161 break;
2162 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002163 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002164 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
2165 + Integer.toHexString(stateInt)
2166 + " batteryStatus=" + cur.batteryStatus
2167 + " batteryHealth=" + cur.batteryHealth
2168 + " batteryPlugType=" + cur.batteryPlugType
2169 + " states=0x" + Integer.toHexString(cur.states));
2170 } else {
2171 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~DELTA_STATE_MASK));
2172 }
2173
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002174 if ((firstToken&DELTA_STATE2_FLAG) != 0) {
2175 cur.states2 = src.readInt();
2176 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
2177 + Integer.toHexString(cur.states2));
2178 }
2179
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002180 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002181 int indexes = src.readInt();
2182 int wakeLockIndex = indexes&0xffff;
2183 int wakeReasonIndex = (indexes>>16)&0xffff;
2184 if (wakeLockIndex != 0xffff) {
2185 cur.wakelockTag = cur.localWakelockTag;
2186 readHistoryTag(wakeLockIndex, cur.wakelockTag);
2187 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
2188 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
2189 } else {
2190 cur.wakelockTag = null;
2191 }
2192 if (wakeReasonIndex != 0xffff) {
2193 cur.wakeReasonTag = cur.localWakeReasonTag;
2194 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
2195 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
2196 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
2197 } else {
2198 cur.wakeReasonTag = null;
2199 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002200 cur.numReadInts += 1;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002201 } else {
2202 cur.wakelockTag = null;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002203 cur.wakeReasonTag = null;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002204 }
2205
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002206 if ((firstToken&DELTA_EVENT_FLAG) != 0) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002207 cur.eventTag = cur.localEventTag;
2208 final int codeAndIndex = src.readInt();
Dianne Hackborn099bc622014-01-22 13:39:16 -08002209 cur.eventCode = (codeAndIndex&0xffff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002210 final int index = ((codeAndIndex>>16)&0xffff);
2211 readHistoryTag(index, cur.eventTag);
2212 cur.numReadInts += 1;
2213 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
2214 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
2215 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002216 } else {
2217 cur.eventCode = HistoryItem.EVENT_NONE;
2218 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002219
2220 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) {
2221 cur.stepDetails = mReadHistoryStepDetails;
2222 cur.stepDetails.readFromParcel(src);
2223 } else {
2224 cur.stepDetails = null;
2225 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002226 }
2227
Dianne Hackbornfc064132014-06-02 12:42:12 -07002228 @Override
2229 public void commitCurrentHistoryBatchLocked() {
2230 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
2231 }
2232
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002233 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002234 if (!mHaveBatteryLevel || !mRecordingHistory) {
2235 return;
2236 }
2237
Dianne Hackborn40c87252014-03-19 16:55:40 -07002238 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002239 final int diffStates = mHistoryLastWritten.states^cur.states;
2240 final int diffStates2 = mHistoryLastWritten.states2^cur.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002241 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002242 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002243 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
2244 + Integer.toHexString(diffStates) + " lastDiff="
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002245 + Integer.toHexString(lastDiffStates) + " diff2="
2246 + Integer.toHexString(diffStates2) + " lastDiff2="
2247 + Integer.toHexString(lastDiffStates2));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002248 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002249 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002250 && (diffStates2&lastDiffStates2) == 0
2251 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
2252 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002253 && mHistoryLastWritten.stepDetails == null
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002254 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002255 || cur.eventCode == HistoryItem.EVENT_NONE)
2256 && mHistoryLastWritten.batteryLevel == cur.batteryLevel
2257 && mHistoryLastWritten.batteryStatus == cur.batteryStatus
2258 && mHistoryLastWritten.batteryHealth == cur.batteryHealth
2259 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
2260 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
2261 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002262 // We can merge this new change in with the last one. Merging is
Dianne Hackborn40c87252014-03-19 16:55:40 -07002263 // allowed as long as only the states have changed, and within those states
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002264 // as long as no bit has changed both between now and the last entry, as
2265 // well as the last entry and the one before it (so we capture any toggles).
2266 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002267 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
2268 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
2269 mHistoryBufferLastPos = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002270 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002271 // If the last written history had a wakelock tag, we need to retain it.
2272 // Note that the condition above made sure that we aren't in a case where
2273 // both it and the current history item have a wakelock tag.
2274 if (mHistoryLastWritten.wakelockTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002275 cur.wakelockTag = cur.localWakelockTag;
2276 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002277 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002278 // If the last written history had a wake reason tag, we need to retain it.
2279 // Note that the condition above made sure that we aren't in a case where
2280 // both it and the current history item have a wakelock tag.
2281 if (mHistoryLastWritten.wakeReasonTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002282 cur.wakeReasonTag = cur.localWakeReasonTag;
2283 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002284 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002285 // If the last written history had an event, we need to retain it.
2286 // Note that the condition above made sure that we aren't in a case where
2287 // both it and the current history item have an event.
2288 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002289 cur.eventCode = mHistoryLastWritten.eventCode;
2290 cur.eventTag = cur.localEventTag;
2291 cur.eventTag.setTo(mHistoryLastWritten.eventTag);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002292 }
Dianne Hackborn1fadab52011-04-14 17:57:33 -07002293 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002294 }
2295
2296 final int dataSize = mHistoryBuffer.dataSize();
2297 if (dataSize >= MAX_HISTORY_BUFFER) {
2298 if (!mHistoryOverflow) {
2299 mHistoryOverflow = true;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002300 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
2301 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002302 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002303 }
2304
2305 // Once we've reached the maximum number of items, we only
2306 // record changes to the battery level and the most interesting states.
2307 // Once we've reached the maximum maximum number of items, we only
2308 // record changes to the battery level.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002309 if (mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002310 (dataSize >= MAX_MAX_HISTORY_BUFFER
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002311 || ((mHistoryLastWritten.states^cur.states)
Dianne Hackborn3251b902014-06-20 14:40:53 -07002312 & HistoryItem.MOST_INTERESTING_STATES) == 0
2313 || ((mHistoryLastWritten.states2^cur.states2)
2314 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002315 return;
2316 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002317
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002318 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002319 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002320 }
2321
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002322 if (dataSize == 0) {
2323 // The history is currently empty; we need it to start with a time stamp.
2324 cur.currentTime = System.currentTimeMillis();
Dianne Hackborna7d0d552014-09-12 17:15:52 -07002325 mLastRecordedClockTime = cur.currentTime;
2326 mLastRecordedClockRealtime = elapsedRealtimeMs;
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002327 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur);
2328 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002329 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002330 }
2331
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002332 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
2333 HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002334 if (mIteratingHistory) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002335 throw new IllegalStateException("Can't do this while iterating history!");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002336 }
2337 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
2338 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002339 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002340 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07002341 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002342 cur.wakelockTag = null;
2343 cur.wakeReasonTag = null;
2344 cur.eventCode = HistoryItem.EVENT_NONE;
2345 cur.eventTag = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002346 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
2347 + " now " + mHistoryBuffer.dataPosition()
2348 + " size is now " + mHistoryBuffer.dataSize());
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002349 }
2350
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002351 int mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002352 int mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002353
Dianne Hackborn40c87252014-03-19 16:55:40 -07002354 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002355 if (mTrackRunningHistoryElapsedRealtime != 0) {
2356 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
2357 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
2358 if (diffUptime < (diffElapsed-20)) {
2359 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
2360 mHistoryAddTmp.setTo(mHistoryLastWritten);
2361 mHistoryAddTmp.wakelockTag = null;
2362 mHistoryAddTmp.wakeReasonTag = null;
2363 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
2364 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
2365 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
2366 }
2367 }
2368 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
2369 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
2370 mTrackRunningHistoryUptime = uptimeMs;
2371 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
2372 }
2373
2374 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
2375 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002376
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002377 if (!USE_OLD_HISTORY) {
2378 return;
2379 }
2380
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002381 if (!mHaveBatteryLevel || !mRecordingHistory) {
2382 return;
2383 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002384
2385 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002386 // and no states have since the last recorded entry changed and
2387 // are now resetting back to their original value, then just collapse
2388 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002389 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002390 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002391 && ((mHistoryEnd.states^cur.states)&mChangedStates) == 0
2392 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002393 // If the current is the same as the one before, then we no
2394 // longer need the entry.
2395 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07002396 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002397 && mHistoryLastEnd.sameNonEvent(cur)) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002398 mHistoryLastEnd.next = null;
2399 mHistoryEnd.next = mHistoryCache;
2400 mHistoryCache = mHistoryEnd;
2401 mHistoryEnd = mHistoryLastEnd;
2402 mHistoryLastEnd = null;
2403 } else {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002404 mChangedStates |= mHistoryEnd.states^cur.states;
2405 mChangedStates2 |= mHistoryEnd.states^cur.states2;
2406 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002407 }
2408 return;
2409 }
2410
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002411 mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002412 mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002413
2414 if (mNumHistoryItems == MAX_HISTORY_ITEMS
2415 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002416 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002417 }
2418
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002419 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
2420 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002421 // record changes to the battery level and the most interesting states.
2422 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002423 // record changes to the battery level.
2424 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002425 == cur.batteryLevel &&
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002426 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002427 || ((mHistoryEnd.states^cur.states)
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07002428 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002429 return;
2430 }
2431 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002432
Dianne Hackborn40c87252014-03-19 16:55:40 -07002433 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002434 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002435
Dianne Hackborn40c87252014-03-19 16:55:40 -07002436 void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
2437 String name, int uid) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002438 mHistoryCur.eventCode = code;
2439 mHistoryCur.eventTag = mHistoryCur.localEventTag;
2440 mHistoryCur.eventTag.string = name;
2441 mHistoryCur.eventTag.uid = uid;
Dianne Hackborn4590e522014-03-24 13:36:46 -07002442 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002443 }
2444
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002445 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002446 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002447 if (rec != null) {
2448 mHistoryCache = rec.next;
2449 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002450 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002451 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002452 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002453
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002454 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002455 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002456
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002457 void addHistoryRecordLocked(HistoryItem rec) {
2458 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002459 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002460 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002461 if (mHistoryEnd != null) {
2462 mHistoryEnd.next = rec;
2463 mHistoryEnd = rec;
2464 } else {
2465 mHistory = mHistoryEnd = rec;
2466 }
2467 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002468
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002469 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002470 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002471 if (USE_OLD_HISTORY) {
2472 if (mHistory != null) {
2473 mHistoryEnd.next = mHistoryCache;
2474 mHistoryCache = mHistory;
2475 mHistory = mHistoryLastEnd = mHistoryEnd = null;
2476 }
2477 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002478 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07002479
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002480 mHistoryBaseTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002481 mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002482 mTrackRunningHistoryElapsedRealtime = 0;
2483 mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002484
2485 mHistoryBuffer.setDataSize(0);
2486 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002487 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002488 mHistoryLastLastWritten.clear();
2489 mHistoryLastWritten.clear();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002490 mHistoryTagPool.clear();
2491 mNextHistoryTagIdx = 0;
2492 mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07002493 mHistoryBufferLastPos = -1;
2494 mHistoryOverflow = false;
Dianne Hackborna7d0d552014-09-12 17:15:52 -07002495 mLastRecordedClockTime = 0;
2496 mLastRecordedClockRealtime = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07002497 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002498
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002499 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
2500 long realtime) {
2501 if (mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime)) {
2502 if (unplugged) {
2503 // Track bt headset ping count
2504 mBluetoothPingStart = getCurrentBluetoothPingCount();
2505 mBluetoothPingCount = 0;
2506 } else {
2507 // Track bt headset ping count
2508 mBluetoothPingCount = getBluetoothPingCount();
2509 mBluetoothPingStart = -1;
2510 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002511 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07002512
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002513 boolean unpluggedScreenOff = unplugged && screenOff;
2514 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
2515 updateKernelWakelocksLocked();
2516 requestWakelockCpuUpdate();
2517 if (!unpluggedScreenOff) {
2518 // We are switching to no longer tracking wake locks, but we want
2519 // the next CPU update we receive to take them in to account.
2520 mDistributeWakelockCpu = true;
2521 }
2522 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002523 }
2524 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002525
Dianne Hackborn099bc622014-01-22 13:39:16 -08002526 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
2527 mIsolatedUids.put(isolatedUid, appUid);
2528 }
2529
2530 public void removeIsolatedUidLocked(int isolatedUid, int appUid) {
2531 int curUid = mIsolatedUids.get(isolatedUid, -1);
2532 if (curUid == appUid) {
2533 mIsolatedUids.delete(isolatedUid);
2534 }
2535 }
2536
2537 public int mapUid(int uid) {
2538 int isolated = mIsolatedUids.get(uid, -1);
2539 return isolated > 0 ? isolated : uid;
2540 }
2541
2542 public void noteEventLocked(int code, String name, int uid) {
2543 uid = mapUid(uid);
Dianne Hackborn37de0982014-05-09 09:32:18 -07002544 if (!mActiveEvents.updateState(code, name, uid, 0)) {
2545 return;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002546 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07002547 final long elapsedRealtime = SystemClock.elapsedRealtime();
2548 final long uptime = SystemClock.uptimeMillis();
2549 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002550 }
2551
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07002552 public void noteCurrentTimeChangedLocked() {
2553 final long currentTime = System.currentTimeMillis();
2554 final long elapsedRealtime = SystemClock.elapsedRealtime();
2555 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborna7d0d552014-09-12 17:15:52 -07002556 if (isStartClockTimeValid()) {
2557 // Has the time changed sufficiently that it is really worth recording?
2558 if (mLastRecordedClockTime != 0) {
2559 long expectedClockTime = mLastRecordedClockTime
2560 + (elapsedRealtime - mLastRecordedClockRealtime);
2561 if (currentTime >= (expectedClockTime-500)
2562 && currentTime <= (expectedClockTime+500)) {
2563 // Not sufficiently changed, skip!
2564 return;
2565 }
2566 }
2567 }
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07002568 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
2569 if (isStartClockTimeValid()) {
2570 mStartClockTime = currentTime;
2571 }
2572 }
2573
Dianne Hackborn61659e52014-07-09 16:13:01 -07002574 public void noteProcessStartLocked(String name, int uid) {
2575 uid = mapUid(uid);
2576 if (isOnBattery()) {
2577 Uid u = getUidStatsLocked(uid);
2578 u.getProcessStatsLocked(name).incStartsLocked();
2579 }
2580 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) {
2581 return;
2582 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002583 if (!mRecordAllHistory) {
2584 return;
2585 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07002586 final long elapsedRealtime = SystemClock.elapsedRealtime();
2587 final long uptime = SystemClock.uptimeMillis();
2588 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid);
2589 }
2590
Dianne Hackborn1e01d162014-12-04 17:46:42 -08002591 public void noteProcessCrashLocked(String name, int uid) {
2592 uid = mapUid(uid);
2593 if (isOnBattery()) {
2594 Uid u = getUidStatsLocked(uid);
2595 u.getProcessStatsLocked(name).incNumCrashesLocked();
2596 }
2597 }
2598
2599 public void noteProcessAnrLocked(String name, int uid) {
2600 uid = mapUid(uid);
2601 if (isOnBattery()) {
2602 Uid u = getUidStatsLocked(uid);
2603 u.getProcessStatsLocked(name).incNumAnrsLocked();
2604 }
2605 }
2606
Dianne Hackborn61659e52014-07-09 16:13:01 -07002607 public void noteProcessStateLocked(String name, int uid, int state) {
2608 uid = mapUid(uid);
2609 final long elapsedRealtime = SystemClock.elapsedRealtime();
2610 getUidStatsLocked(uid).updateProcessStateLocked(name, state, elapsedRealtime);
2611 }
2612
2613 public void noteProcessFinishLocked(String name, int uid) {
2614 uid = mapUid(uid);
2615 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) {
2616 return;
2617 }
2618 final long elapsedRealtime = SystemClock.elapsedRealtime();
2619 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn61659e52014-07-09 16:13:01 -07002620 getUidStatsLocked(uid).updateProcessStateLocked(name, Uid.PROCESS_STATE_NONE,
2621 elapsedRealtime);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002622 if (!mRecordAllHistory) {
2623 return;
2624 }
2625 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid);
Dianne Hackborn61659e52014-07-09 16:13:01 -07002626 }
2627
Dianne Hackbornfdb19562014-07-11 16:03:36 -07002628 public void noteSyncStartLocked(String name, int uid) {
2629 uid = mapUid(uid);
2630 final long elapsedRealtime = SystemClock.elapsedRealtime();
2631 final long uptime = SystemClock.uptimeMillis();
2632 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime);
2633 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
2634 return;
2635 }
2636 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid);
2637 }
2638
2639 public void noteSyncFinishLocked(String name, int uid) {
2640 uid = mapUid(uid);
2641 final long elapsedRealtime = SystemClock.elapsedRealtime();
2642 final long uptime = SystemClock.uptimeMillis();
2643 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime);
2644 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
2645 return;
2646 }
2647 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid);
2648 }
2649
2650 public void noteJobStartLocked(String name, int uid) {
2651 uid = mapUid(uid);
2652 final long elapsedRealtime = SystemClock.elapsedRealtime();
2653 final long uptime = SystemClock.uptimeMillis();
2654 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime);
2655 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
2656 return;
2657 }
2658 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid);
2659 }
2660
2661 public void noteJobFinishLocked(String name, int uid) {
2662 uid = mapUid(uid);
2663 final long elapsedRealtime = SystemClock.elapsedRealtime();
2664 final long uptime = SystemClock.uptimeMillis();
2665 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime);
2666 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
2667 return;
2668 }
2669 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid);
2670 }
2671
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002672 private void requestWakelockCpuUpdate() {
2673 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
2674 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
2675 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
2676 }
2677 }
2678
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002679 private void requestImmediateCpuUpdate() {
2680 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2681 mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS);
2682 }
2683
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002684 public void setRecordAllHistoryLocked(boolean enabled) {
2685 mRecordAllHistory = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002686 if (!enabled) {
2687 // Clear out any existing state.
2688 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002689 // Record the currently running processes as stopping, now that we are no
2690 // longer tracking them.
2691 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
2692 HistoryItem.EVENT_PROC);
2693 if (active != null) {
2694 long mSecRealtime = SystemClock.elapsedRealtime();
2695 final long mSecUptime = SystemClock.uptimeMillis();
2696 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
2697 SparseIntArray uids = ent.getValue();
2698 for (int j=0; j<uids.size(); j++) {
2699 addHistoryEventLocked(mSecRealtime, mSecUptime,
2700 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j));
2701 }
2702 }
2703 }
2704 } else {
2705 // Record the currently running processes as starting, now that we are tracking them.
2706 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
2707 HistoryItem.EVENT_PROC);
2708 if (active != null) {
2709 long mSecRealtime = SystemClock.elapsedRealtime();
2710 final long mSecUptime = SystemClock.uptimeMillis();
2711 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
2712 SparseIntArray uids = ent.getValue();
2713 for (int j=0; j<uids.size(); j++) {
2714 addHistoryEventLocked(mSecRealtime, mSecUptime,
2715 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j));
2716 }
2717 }
2718 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002719 }
2720 }
2721
Dianne Hackborn9a755432014-05-15 17:05:22 -07002722 public void setNoAutoReset(boolean enabled) {
2723 mNoAutoReset = enabled;
2724 }
2725
2726 private String mInitialAcquireWakeName;
2727 private int mInitialAcquireWakeUid = -1;
2728
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002729 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002730 boolean unimportantForLogging, long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002731 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002732 if (type == WAKE_TYPE_PARTIAL) {
2733 // Only care about partial wake locks, since full wake locks
2734 // will be canceled when the user puts the screen to sleep.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002735 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002736 if (historyName == null) {
2737 historyName = name;
2738 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002739 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002740 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
2741 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002742 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002743 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002744 }
2745 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002746 if (mWakeLockNesting == 0) {
2747 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
2748 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
2749 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002750 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002751 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002752 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002753 mWakeLockImportant = !unimportantForLogging;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002754 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07002755 } else if (!mWakeLockImportant && !unimportantForLogging
2756 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002757 if (mHistoryLastWritten.wakelockTag != null) {
2758 // We'll try to update the last tag.
2759 mHistoryLastWritten.wakelockTag = null;
2760 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002761 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07002762 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002763 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002764 }
2765 mWakeLockImportant = true;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002766 }
2767 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002768 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002769 if (uid >= 0) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07002770 //if (uid == 0) {
2771 // Slog.wtf(TAG, "Acquiring wake lock from root: " + name);
2772 //}
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002773 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002774 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002775 }
2776 }
2777
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002778 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type,
2779 long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002780 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002781 if (type == WAKE_TYPE_PARTIAL) {
2782 mWakeLockNesting--;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07002783 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07002784 if (historyName == null) {
2785 historyName = name;
2786 }
2787 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
2788 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07002789 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07002790 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07002791 }
2792 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002793 if (mWakeLockNesting == 0) {
2794 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
2795 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
2796 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn37de0982014-05-09 09:32:18 -07002797 mInitialAcquireWakeName = null;
2798 mInitialAcquireWakeUid = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002799 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07002800 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002801 }
2802 if (uid >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002803 requestWakelockCpuUpdate();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08002804 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002805 }
2806 }
2807
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08002808 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
2809 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002810 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002811 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002812 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002813 for (int i=0; i<N; i++) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002814 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002815 elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002816 }
2817 }
2818
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002819 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
2820 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002821 String newHistoryName, int newType, boolean newUnimportantForLogging) {
2822 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002823 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002824 // For correct semantics, we start the need worksources first, so that we won't
2825 // make inappropriate history items as if all wake locks went away and new ones
2826 // appeared. This is okay because tracking of wake locks allows nesting.
Dianne Hackborn40c87252014-03-19 16:55:40 -07002827 final int NN = newWs.size();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002828 for (int i=0; i<NN; i++) {
2829 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
Dianne Hackborn40c87252014-03-19 16:55:40 -07002830 newUnimportantForLogging, elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002831 }
2832 final int NO = ws.size();
2833 for (int i=0; i<NO; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002834 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002835 }
2836 }
2837
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002838 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
2839 String historyName, int type) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002840 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002841 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08002842 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002843 for (int i=0; i<N; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07002844 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07002845 }
2846 }
2847
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002848 void aggregateLastWakeupUptimeLocked(long uptimeMs) {
2849 if (mLastWakeupReason != null) {
2850 long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002851 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
2852 timer.addCurrentReportedCount(1);
2853 timer.addCurrentReportedTotalTime(deltaUptime * 1000); // time is in microseconds
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002854 mLastWakeupReason = null;
2855 }
2856 }
2857
2858 public void noteWakeupReasonLocked(String reason) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002859 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07002860 final long uptime = SystemClock.uptimeMillis();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002861 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": "
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002862 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002863 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002864 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
2865 mHistoryCur.wakeReasonTag.string = reason;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002866 mHistoryCur.wakeReasonTag.uid = 0;
2867 mLastWakeupReason = reason;
2868 mLastWakeupUptimeMs = uptime;
Dianne Hackborn40c87252014-03-19 16:55:40 -07002869 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002870 }
2871
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002872 public int startAddingCpuLocked() {
2873 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
2874
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002875 if (!mOnBatteryInternal) {
2876 return -1;
2877 }
2878
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002879 final int N = mPartialTimers.size();
2880 if (N == 0) {
2881 mLastPartialTimers.clear();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002882 mDistributeWakelockCpu = false;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002883 return 0;
2884 }
2885
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002886 if (!mOnBatteryScreenOffTimeBase.isRunning() && !mDistributeWakelockCpu) {
2887 return 0;
2888 }
2889
2890 mDistributeWakelockCpu = false;
2891
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002892 // How many timers should consume CPU? Only want to include ones
2893 // that have already been in the list.
2894 for (int i=0; i<N; i++) {
2895 StopwatchTimer st = mPartialTimers.get(i);
2896 if (st.mInList) {
2897 Uid uid = st.mUid;
2898 // We don't include the system UID, because it so often
2899 // holds wake locks at one request or another of an app.
2900 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2901 return 50;
2902 }
2903 }
2904 }
2905
2906 return 0;
2907 }
2908
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002909 public void finishAddingCpuLocked(int perc, int remainUTime, int remainSTtime,
2910 int totalUTime, int totalSTime, int statUserTime, int statSystemTime,
2911 int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime,
2912 long[] cpuSpeedTimes) {
2913 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
2914 + " user=" + statUserTime + " sys=" + statSystemTime
2915 + " io=" + statIOWaitTime + " irq=" + statIrqTime
2916 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime);
2917 mCurStepCpuUserTime += totalUTime;
2918 mCurStepCpuSystemTime += totalSTime;
2919 mCurStepStatUserTime += statUserTime;
2920 mCurStepStatSystemTime += statSystemTime;
2921 mCurStepStatIOWaitTime += statIOWaitTime;
2922 mCurStepStatIrqTime += statIrqTime;
2923 mCurStepStatSoftIrqTime += statSoftIrqTime;
2924 mCurStepStatIdleTime += statIdleTime;
2925
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002926 final int N = mPartialTimers.size();
2927 if (perc != 0) {
2928 int num = 0;
2929 for (int i=0; i<N; i++) {
2930 StopwatchTimer st = mPartialTimers.get(i);
2931 if (st.mInList) {
2932 Uid uid = st.mUid;
2933 // We don't include the system UID, because it so often
2934 // holds wake locks at one request or another of an app.
2935 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
2936 num++;
2937 }
2938 }
2939 }
2940 if (num != 0) {
2941 for (int i=0; i<N; i++) {
2942 StopwatchTimer st = mPartialTimers.get(i);
2943 if (st.mInList) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002944 Uid uid = st.mUid;
2945 if (uid != null && uid.mUid != Process.SYSTEM_UID) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002946 int myUTime = remainUTime/num;
2947 int mySTime = remainSTtime/num;
2948 remainUTime -= myUTime;
2949 remainSTtime -= mySTime;
Dianne Hackborn618b8c12010-09-09 23:10:38 -07002950 num--;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002951 Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*");
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002952 proc.addCpuTimeLocked(myUTime, mySTime, cpuSpeedTimes);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002953 }
2954 }
2955 }
2956 }
2957
2958 // Just in case, collect any lost CPU time.
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002959 if (remainUTime != 0 || remainSTtime != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002960 Uid uid = getUidStatsLocked(Process.SYSTEM_UID);
2961 if (uid != null) {
2962 Uid.Proc proc = uid.getProcessStatsLocked("*lost*");
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002963 proc.addCpuTimeLocked(remainUTime, remainSTtime, cpuSpeedTimes);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002964 }
2965 }
2966 }
2967
2968 final int NL = mLastPartialTimers.size();
2969 boolean diff = N != NL;
2970 for (int i=0; i<NL && !diff; i++) {
2971 diff |= mPartialTimers.get(i) != mLastPartialTimers.get(i);
2972 }
2973 if (!diff) {
2974 for (int i=0; i<NL; i++) {
2975 mPartialTimers.get(i).mInList = true;
2976 }
2977 return;
2978 }
2979
2980 for (int i=0; i<NL; i++) {
2981 mLastPartialTimers.get(i).mInList = false;
2982 }
2983 mLastPartialTimers.clear();
2984 for (int i=0; i<N; i++) {
2985 StopwatchTimer st = mPartialTimers.get(i);
2986 st.mInList = true;
2987 mLastPartialTimers.add(st);
2988 }
2989 }
2990
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002991 public void noteProcessDiedLocked(int uid, int pid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08002992 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002993 Uid u = mUidStats.get(uid);
2994 if (u != null) {
2995 u.mPids.remove(pid);
2996 }
2997 }
2998
2999 public long getProcessWakeTime(int uid, int pid, long realtime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003000 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003001 Uid u = mUidStats.get(uid);
3002 if (u != null) {
3003 Uid.Pid p = u.mPids.get(pid);
3004 if (p != null) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003005 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003006 }
3007 }
3008 return 0;
3009 }
3010
3011 public void reportExcessiveWakeLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003012 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003013 Uid u = mUidStats.get(uid);
3014 if (u != null) {
3015 u.reportExcessiveWakeLocked(proc, overTime, usedTime);
3016 }
3017 }
3018
Dianne Hackborn287952c2010-09-22 22:34:31 -07003019 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003020 uid = mapUid(uid);
Dianne Hackborn287952c2010-09-22 22:34:31 -07003021 Uid u = mUidStats.get(uid);
3022 if (u != null) {
3023 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
3024 }
3025 }
3026
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003027 int mSensorNesting;
3028
3029 public void noteStartSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003030 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003031 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003032 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003033 if (mSensorNesting == 0) {
3034 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
3035 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
3036 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003037 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003038 }
3039 mSensorNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003040 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003041 }
3042
3043 public void noteStopSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003044 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003045 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003046 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003047 mSensorNesting--;
3048 if (mSensorNesting == 0) {
3049 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
3050 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
3051 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003052 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003053 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003054 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003055 }
3056
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003057 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003058
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003059 public void noteStartGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003060 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003061 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003062 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003063 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003064 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003065 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
3066 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003067 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003068 }
3069 mGpsNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003070 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003071 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003072
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003073 public void noteStopGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003074 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003075 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003076 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003077 mGpsNesting--;
3078 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003079 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003080 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
3081 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003082 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003083 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003084 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003085 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003086
Jeff Browne95c3cd2014-05-02 16:59:26 -07003087 public void noteScreenStateLocked(int state) {
3088 if (mScreenState != state) {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08003089 recordDailyStatsIfNeededLocked(true);
Jeff Browne95c3cd2014-05-02 16:59:26 -07003090 final int oldState = mScreenState;
3091 mScreenState = state;
3092 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
3093 + ", newState=" + Display.stateToString(state));
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003094
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003095 if (state != Display.STATE_UNKNOWN) {
3096 int stepState = state-1;
3097 if (stepState < 4) {
3098 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState;
3099 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_SCREEN_STATE) | stepState;
3100 } else {
3101 Slog.wtf(TAG, "Unexpected screen state: " + state);
3102 }
3103 }
3104
Jeff Browne95c3cd2014-05-02 16:59:26 -07003105 if (state == Display.STATE_ON) {
3106 // Screen turning on.
3107 final long elapsedRealtime = SystemClock.elapsedRealtime();
3108 final long uptime = SystemClock.uptimeMillis();
3109 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
3110 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
3111 + Integer.toHexString(mHistoryCur.states));
3112 addHistoryRecordLocked(elapsedRealtime, uptime);
3113 mScreenOnTimer.startRunningLocked(elapsedRealtime);
3114 if (mScreenBrightnessBin >= 0) {
3115 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
3116 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003117
Jeff Browne95c3cd2014-05-02 16:59:26 -07003118 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false,
3119 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003120
Jeff Browne95c3cd2014-05-02 16:59:26 -07003121 // Fake a wake lock, so we consider the device waked as long
3122 // as the screen is on.
3123 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
3124 elapsedRealtime, uptime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003125
Jeff Browne95c3cd2014-05-02 16:59:26 -07003126 // Update discharge amounts.
3127 if (mOnBatteryInternal) {
3128 updateDischargeScreenLevelsLocked(false, true);
3129 }
3130 } else if (oldState == Display.STATE_ON) {
3131 // Screen turning off or dozing.
3132 final long elapsedRealtime = SystemClock.elapsedRealtime();
3133 final long uptime = SystemClock.uptimeMillis();
3134 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
3135 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
3136 + Integer.toHexString(mHistoryCur.states));
3137 addHistoryRecordLocked(elapsedRealtime, uptime);
3138 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
3139 if (mScreenBrightnessBin >= 0) {
3140 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
3141 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003142
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003143 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL,
Jeff Browne95c3cd2014-05-02 16:59:26 -07003144 elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003145
Jeff Browne95c3cd2014-05-02 16:59:26 -07003146 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
3147 SystemClock.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003148
Jeff Browne95c3cd2014-05-02 16:59:26 -07003149 // Update discharge amounts.
3150 if (mOnBatteryInternal) {
3151 updateDischargeScreenLevelsLocked(true, false);
3152 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08003153 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07003154 }
3155 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003156
Dianne Hackborn617f8772009-03-31 15:04:46 -07003157 public void noteScreenBrightnessLocked(int brightness) {
3158 // Bin the brightness.
3159 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
3160 if (bin < 0) bin = 0;
3161 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
3162 if (mScreenBrightnessBin != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003163 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003164 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003165 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
3166 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003167 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
3168 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003169 addHistoryRecordLocked(elapsedRealtime, uptime);
Jeff Browne95c3cd2014-05-02 16:59:26 -07003170 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07003171 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003172 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003173 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003174 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07003175 }
3176 mScreenBrightnessBin = bin;
3177 }
3178 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003179
Dianne Hackborn617f8772009-03-31 15:04:46 -07003180 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08003181 if (mOnBatteryInternal) {
3182 uid = mapUid(uid);
3183 getUidStatsLocked(uid).noteUserActivityLocked(event);
3184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003185 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003186
Jeff Browne95c3cd2014-05-02 16:59:26 -07003187 public void noteInteractiveLocked(boolean interactive) {
3188 if (mInteractive != interactive) {
3189 final long elapsedRealtime = SystemClock.elapsedRealtime();
3190 mInteractive = interactive;
3191 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
3192 if (interactive) {
3193 mInteractiveTimer.startRunningLocked(elapsedRealtime);
3194 } else {
3195 mInteractiveTimer.stopRunningLocked(elapsedRealtime);
3196 }
3197 }
3198 }
3199
Dianne Hackborn1e01d162014-12-04 17:46:42 -08003200 public void noteConnectivityChangedLocked(int type, String extra) {
3201 final long elapsedRealtime = SystemClock.elapsedRealtime();
3202 final long uptime = SystemClock.uptimeMillis();
3203 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
3204 extra, type);
3205 mNumConnectivityChange++;
3206 }
3207
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003208 public void noteMobileRadioPowerState(int powerState, long timestampNs) {
3209 final long elapsedRealtime = SystemClock.elapsedRealtime();
3210 final long uptime = SystemClock.uptimeMillis();
3211 if (mMobileRadioPowerState != powerState) {
3212 long realElapsedRealtimeMs;
3213 final boolean active =
3214 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
3215 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
3216 if (active) {
Dianne Hackbornf7097a52014-05-13 09:56:14 -07003217 mMobileRadioActiveStartTime = realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003218 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
3219 } else {
3220 realElapsedRealtimeMs = timestampNs / (1000*1000);
Dianne Hackbornf7097a52014-05-13 09:56:14 -07003221 long lastUpdateTimeMs = mMobileRadioActiveStartTime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003222 if (realElapsedRealtimeMs < lastUpdateTimeMs) {
3223 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
3224 + " is before start time " + lastUpdateTimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003225 realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003226 } else if (realElapsedRealtimeMs < elapsedRealtime) {
3227 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
3228 - realElapsedRealtimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003229 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003230 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
3231 }
3232 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
3233 + Integer.toHexString(mHistoryCur.states));
3234 addHistoryRecordLocked(elapsedRealtime, uptime);
3235 mMobileRadioPowerState = powerState;
3236 if (active) {
3237 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
3238 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
3239 } else {
3240 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003241 updateMobileRadioStateLocked(realElapsedRealtimeMs);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07003242 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003243 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003244 }
3245 }
3246
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003247 public void notePowerSaveMode(boolean enabled) {
3248 if (mPowerSaveModeEnabled != enabled) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003249 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0;
3250 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState;
3251 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003252 final long elapsedRealtime = SystemClock.elapsedRealtime();
3253 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003254 mPowerSaveModeEnabled = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003255 if (enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003256 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
3257 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003258 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003259 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003260 } else {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003261 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
3262 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003263 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003264 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003265 }
3266 addHistoryRecordLocked(elapsedRealtime, uptime);
3267 }
3268 }
3269
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003270 public void noteDeviceIdleModeLocked(boolean enabled, boolean fromActive, boolean fromMotion) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003271 final long elapsedRealtime = SystemClock.elapsedRealtime();
3272 final long uptime = SystemClock.uptimeMillis();
3273 boolean nowIdling = enabled;
3274 if (mDeviceIdling && !enabled && !fromActive && !fromMotion) {
3275 // We don't go out of general idling mode until explicitly taken out of
3276 // device idle through going active or significant motion.
3277 nowIdling = true;
3278 }
3279 if (mDeviceIdling != nowIdling) {
3280 mDeviceIdling = nowIdling;
3281 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0;
3282 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState;
3283 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState;
3284 if (enabled) {
3285 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime);
3286 } else {
3287 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime);
3288 }
3289 }
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003290 if (mDeviceIdleModeEnabled != enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003291 mDeviceIdleModeEnabled = enabled;
3292 if (fromMotion) {
3293 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SIGNIFICANT_MOTION,
3294 "", 0);
3295 }
3296 if (fromActive) {
3297 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
3298 "", 0);
3299 }
3300 if (enabled) {
3301 mHistoryCur.states2 |= HistoryItem.STATE2_DEVICE_IDLE_FLAG;
3302 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode enabled to: "
3303 + Integer.toHexString(mHistoryCur.states2));
3304 mDeviceIdleModeEnabledTimer.startRunningLocked(elapsedRealtime);
3305 } else {
3306 mHistoryCur.states2 &= ~HistoryItem.STATE2_DEVICE_IDLE_FLAG;
3307 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode disabled to: "
3308 + Integer.toHexString(mHistoryCur.states2));
3309 mDeviceIdleModeEnabledTimer.stopRunningLocked(elapsedRealtime);
3310 }
3311 addHistoryRecordLocked(elapsedRealtime, uptime);
3312 }
3313 }
3314
3315 public void notePackageInstalledLocked(String pkgName, int versionCode) {
3316 final long elapsedRealtime = SystemClock.elapsedRealtime();
3317 final long uptime = SystemClock.uptimeMillis();
3318 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED,
3319 pkgName, versionCode);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003320 PackageChange pc = new PackageChange();
3321 pc.mPackageName = pkgName;
3322 pc.mUpdate = true;
3323 pc.mVersionCode = versionCode;
3324 addPackageChange(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003325 }
3326
3327 public void notePackageUninstalledLocked(String pkgName) {
3328 final long elapsedRealtime = SystemClock.elapsedRealtime();
3329 final long uptime = SystemClock.uptimeMillis();
3330 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
3331 pkgName, 0);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07003332 PackageChange pc = new PackageChange();
3333 pc.mPackageName = pkgName;
3334 pc.mUpdate = true;
3335 addPackageChange(pc);
3336 }
3337
3338 private void addPackageChange(PackageChange pc) {
3339 if (mDailyPackageChanges == null) {
3340 mDailyPackageChanges = new ArrayList<>();
3341 }
3342 mDailyPackageChanges.add(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07003343 }
3344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003345 public void notePhoneOnLocked() {
3346 if (!mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003347 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003348 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003349 mHistoryCur.states |= HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003350 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
3351 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003352 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003353 mPhoneOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003354 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003355 }
3356 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003358 public void notePhoneOffLocked() {
3359 if (mPhoneOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003360 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003361 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003362 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003363 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
3364 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003365 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003366 mPhoneOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003367 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003368 }
3369 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003370
Dianne Hackborn3251b902014-06-20 14:40:53 -07003371 void stopAllPhoneSignalStrengthTimersLocked(int except) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003372 final long elapsedRealtime = SystemClock.elapsedRealtime();
Wink Saville52840902011-02-18 12:40:47 -08003373 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003374 if (i == except) {
3375 continue;
3376 }
3377 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003378 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003379 }
3380 }
3381 }
3382
Dianne Hackborne4a59512010-12-07 11:08:07 -08003383 private int fixPhoneServiceState(int state, int signalBin) {
3384 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
3385 // In this case we will always be STATE_OUT_OF_SERVICE, so need
3386 // to infer that we are scanning from other data.
3387 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08003388 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003389 state = ServiceState.STATE_IN_SERVICE;
3390 }
3391 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003392
Dianne Hackborne4a59512010-12-07 11:08:07 -08003393 return state;
3394 }
3395
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003396 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003397 boolean scanning = false;
3398 boolean newHistory = false;
3399
3400 mPhoneServiceStateRaw = state;
3401 mPhoneSimStateRaw = simState;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003402 mPhoneSignalStrengthBinRaw = strengthBin;
3403
3404 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003405 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne4a59512010-12-07 11:08:07 -08003406
3407 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
3408 // In this case we will always be STATE_OUT_OF_SERVICE, so need
3409 // to infer that we are scanning from other data.
3410 if (state == ServiceState.STATE_OUT_OF_SERVICE
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003411 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003412 state = ServiceState.STATE_IN_SERVICE;
3413 }
3414 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003415
3416 // If the phone is powered off, stop all timers.
3417 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003418 strengthBin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07003419
Dianne Hackborne4a59512010-12-07 11:08:07 -08003420 // If we are in service, make sure the correct signal string timer is running.
3421 } else if (state == ServiceState.STATE_IN_SERVICE) {
3422 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003423
3424 // If we're out of service, we are in the lowest signal strength
3425 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07003426 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003427 scanning = true;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003428 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07003429 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003430 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08003431 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003432 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
3433 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003434 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
Amith Yamasanif37447b2009-10-08 18:28:01 -07003435 }
3436 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003437
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003438 if (!scanning) {
3439 // If we are no longer scanning, then stop the scanning timer.
3440 if (mPhoneSignalScanningTimer.isRunningLocked()) {
3441 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
3442 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
3443 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08003444 newHistory = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003445 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07003446 }
3447 }
3448
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003449 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003450 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
3451 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003452 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003453 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08003454 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003455 mPhoneServiceState = state;
3456 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08003457
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003458 if (mPhoneSignalStrengthBin != strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08003459 if (mPhoneSignalStrengthBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003460 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003461 elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003462 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003463 if (strengthBin >= 0) {
3464 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003465 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003466 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07003467 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
3468 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003469 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
Dianne Hackborne4a59512010-12-07 11:08:07 -08003470 + Integer.toHexString(mHistoryCur.states));
3471 newHistory = true;
3472 } else {
Dianne Hackborn3251b902014-06-20 14:40:53 -07003473 stopAllPhoneSignalStrengthTimersLocked(-1);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003474 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003475 mPhoneSignalStrengthBin = strengthBin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08003476 }
3477
3478 if (newHistory) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07003479 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08003480 }
3481 }
3482
3483 /**
3484 * Telephony stack updates the phone state.
3485 * @param state phone state from ServiceState.getState()
3486 */
3487 public void notePhoneStateLocked(int state, int simState) {
3488 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07003489 }
3490
Wink Savillee9b06d72009-05-18 21:47:50 -07003491 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07003492 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08003493 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08003494 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003495 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003496
Dianne Hackborn627bba72009-03-24 22:32:56 -07003497 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
3498 int bin = DATA_CONNECTION_NONE;
3499 if (hasData) {
3500 switch (dataType) {
3501 case TelephonyManager.NETWORK_TYPE_EDGE:
3502 bin = DATA_CONNECTION_EDGE;
3503 break;
3504 case TelephonyManager.NETWORK_TYPE_GPRS:
3505 bin = DATA_CONNECTION_GPRS;
3506 break;
3507 case TelephonyManager.NETWORK_TYPE_UMTS:
3508 bin = DATA_CONNECTION_UMTS;
3509 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003510 case TelephonyManager.NETWORK_TYPE_CDMA:
3511 bin = DATA_CONNECTION_CDMA;
3512 break;
3513 case TelephonyManager.NETWORK_TYPE_EVDO_0:
3514 bin = DATA_CONNECTION_EVDO_0;
3515 break;
3516 case TelephonyManager.NETWORK_TYPE_EVDO_A:
3517 bin = DATA_CONNECTION_EVDO_A;
3518 break;
3519 case TelephonyManager.NETWORK_TYPE_1xRTT:
3520 bin = DATA_CONNECTION_1xRTT;
3521 break;
3522 case TelephonyManager.NETWORK_TYPE_HSDPA:
3523 bin = DATA_CONNECTION_HSDPA;
3524 break;
3525 case TelephonyManager.NETWORK_TYPE_HSUPA:
3526 bin = DATA_CONNECTION_HSUPA;
3527 break;
3528 case TelephonyManager.NETWORK_TYPE_HSPA:
3529 bin = DATA_CONNECTION_HSPA;
3530 break;
3531 case TelephonyManager.NETWORK_TYPE_IDEN:
3532 bin = DATA_CONNECTION_IDEN;
3533 break;
3534 case TelephonyManager.NETWORK_TYPE_EVDO_B:
3535 bin = DATA_CONNECTION_EVDO_B;
3536 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07003537 case TelephonyManager.NETWORK_TYPE_LTE:
3538 bin = DATA_CONNECTION_LTE;
3539 break;
3540 case TelephonyManager.NETWORK_TYPE_EHRPD:
3541 bin = DATA_CONNECTION_EHRPD;
3542 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08003543 case TelephonyManager.NETWORK_TYPE_HSPAP:
3544 bin = DATA_CONNECTION_HSPAP;
3545 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07003546 default:
3547 bin = DATA_CONNECTION_OTHER;
3548 break;
3549 }
3550 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003551 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003552 if (mPhoneDataConnectionType != bin) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003553 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003554 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003555 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
3556 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003557 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
3558 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003559 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003560 if (mPhoneDataConnectionType >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003561 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003562 elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003563 }
3564 mPhoneDataConnectionType = bin;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003565 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07003566 }
3567 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003568
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003569 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07003570 if (!mWifiOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003571 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003572 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003573 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003574 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
3575 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003576 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003577 mWifiOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003578 mWifiOnTimer.startRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003579 scheduleSyncExternalStatsLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003580 }
3581 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003582
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003583 public void noteWifiOffLocked() {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003584 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003585 final long uptime = SystemClock.uptimeMillis();
The Android Open Source Project10592532009-03-18 17:39:46 -07003586 if (mWifiOn) {
Dianne Hackborn3251b902014-06-20 14:40:53 -07003587 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003588 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
3589 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003590 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003591 mWifiOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003592 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003593 scheduleSyncExternalStatsLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003594 }
3595 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003596
3597 public void noteAudioOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003598 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003599 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003600 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003601 if (mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003602 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003603 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
3604 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003605 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003606 mAudioOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003607 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003608 mAudioOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003609 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003610 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003611
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003612 public void noteAudioOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003613 if (mAudioOnNesting == 0) {
3614 return;
3615 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003616 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003617 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003618 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003619 if (--mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003620 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003621 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3622 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003623 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003624 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003625 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003626 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003627 }
3628
3629 public void noteVideoOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003630 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003631 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003632 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003633 if (mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003634 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003635 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
3636 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003637 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003638 mVideoOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003639 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003640 mVideoOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003641 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003642 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003643
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003644 public void noteVideoOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003645 if (mVideoOnNesting == 0) {
3646 return;
3647 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003648 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003649 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003650 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003651 if (--mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003652 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003653 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3654 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003655 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003656 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003657 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003658 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07003659 }
3660
Dianne Hackborn10eaa852014-07-22 22:54:55 -07003661 public void noteResetAudioLocked() {
3662 if (mAudioOnNesting > 0) {
3663 final long elapsedRealtime = SystemClock.elapsedRealtime();
3664 final long uptime = SystemClock.uptimeMillis();
3665 mAudioOnNesting = 0;
3666 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
3667 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
3668 + Integer.toHexString(mHistoryCur.states));
3669 addHistoryRecordLocked(elapsedRealtime, uptime);
3670 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime);
3671 for (int i=0; i<mUidStats.size(); i++) {
3672 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3673 uid.noteResetAudioLocked(elapsedRealtime);
3674 }
3675 }
3676 }
3677
3678 public void noteResetVideoLocked() {
3679 if (mVideoOnNesting > 0) {
3680 final long elapsedRealtime = SystemClock.elapsedRealtime();
3681 final long uptime = SystemClock.uptimeMillis();
3682 mAudioOnNesting = 0;
3683 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
3684 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
3685 + Integer.toHexString(mHistoryCur.states));
3686 addHistoryRecordLocked(elapsedRealtime, uptime);
3687 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime);
3688 for (int i=0; i<mUidStats.size(); i++) {
3689 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3690 uid.noteResetVideoLocked(elapsedRealtime);
3691 }
3692 }
3693 }
3694
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003695 public void noteActivityResumedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003696 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003697 getUidStatsLocked(uid).noteActivityResumedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003698 }
3699
3700 public void noteActivityPausedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003701 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003702 getUidStatsLocked(uid).noteActivityPausedLocked(SystemClock.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07003703 }
3704
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003705 public void noteVibratorOnLocked(int uid, long durationMillis) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003706 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003707 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
3708 }
3709
3710 public void noteVibratorOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003711 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08003712 getUidStatsLocked(uid).noteVibratorOffLocked();
3713 }
3714
Dianne Hackbornabc7c492014-06-30 16:57:46 -07003715 public void noteFlashlightOnLocked() {
3716 if (!mFlashlightOn) {
3717 final long elapsedRealtime = SystemClock.elapsedRealtime();
3718 final long uptime = SystemClock.uptimeMillis();
3719 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
3720 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
3721 + Integer.toHexString(mHistoryCur.states));
3722 addHistoryRecordLocked(elapsedRealtime, uptime);
3723 mFlashlightOn = true;
3724 mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
3725 }
3726 }
3727
3728 public void noteFlashlightOffLocked() {
3729 final long elapsedRealtime = SystemClock.elapsedRealtime();
3730 final long uptime = SystemClock.uptimeMillis();
3731 if (mFlashlightOn) {
3732 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
3733 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
3734 + Integer.toHexString(mHistoryCur.states));
3735 addHistoryRecordLocked(elapsedRealtime, uptime);
3736 mFlashlightOn = false;
3737 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
3738 }
3739 }
3740
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003741 public void noteWifiRunningLocked(WorkSource ws) {
3742 if (!mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003743 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003744 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003745 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003746 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
3747 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003748 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003749 mGlobalWifiRunning = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003750 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003751 int N = ws.size();
3752 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003753 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003754 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003755 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003756 scheduleSyncExternalStatsLocked();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003757 } else {
3758 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003759 }
3760 }
3761
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003762 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
3763 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003764 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003765 int N = oldWs.size();
3766 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003767 int uid = mapUid(oldWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003768 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003769 }
3770 N = newWs.size();
3771 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003772 int uid = mapUid(newWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003773 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003774 }
3775 } else {
3776 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
3777 }
3778 }
3779
3780 public void noteWifiStoppedLocked(WorkSource ws) {
3781 if (mGlobalWifiRunning) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003782 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003783 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07003784 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003785 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
3786 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003787 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003788 mGlobalWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003789 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003790 int N = ws.size();
3791 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003792 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003793 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003794 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003795 scheduleSyncExternalStatsLocked();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07003796 } else {
3797 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07003798 }
3799 }
3800
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003801 public void noteWifiStateLocked(int wifiState, String accessPoint) {
3802 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
3803 if (mWifiState != wifiState) {
3804 final long elapsedRealtime = SystemClock.elapsedRealtime();
3805 if (mWifiState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003806 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003807 }
3808 mWifiState = wifiState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003809 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003810 scheduleSyncExternalStatsLocked();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003811 }
3812 }
3813
Dianne Hackborn3251b902014-06-20 14:40:53 -07003814 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
3815 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
3816 if (mWifiSupplState != supplState) {
3817 final long elapsedRealtime = SystemClock.elapsedRealtime();
3818 final long uptime = SystemClock.uptimeMillis();
3819 if (mWifiSupplState >= 0) {
3820 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime);
3821 }
3822 mWifiSupplState = supplState;
3823 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime);
3824 mHistoryCur.states2 =
3825 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
3826 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
3827 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
3828 + Integer.toHexString(mHistoryCur.states2));
3829 addHistoryRecordLocked(elapsedRealtime, uptime);
3830 }
3831 }
3832
3833 void stopAllWifiSignalStrengthTimersLocked(int except) {
3834 final long elapsedRealtime = SystemClock.elapsedRealtime();
3835 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
3836 if (i == except) {
3837 continue;
3838 }
3839 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) {
3840 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
3841 }
3842 }
3843 }
3844
3845 public void noteWifiRssiChangedLocked(int newRssi) {
3846 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
3847 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
3848 if (mWifiSignalStrengthBin != strengthBin) {
3849 final long elapsedRealtime = SystemClock.elapsedRealtime();
3850 final long uptime = SystemClock.uptimeMillis();
3851 if (mWifiSignalStrengthBin >= 0) {
3852 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked(
3853 elapsedRealtime);
3854 }
3855 if (strengthBin >= 0) {
3856 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
3857 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
3858 }
3859 mHistoryCur.states2 =
3860 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
3861 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
3862 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
3863 + Integer.toHexString(mHistoryCur.states2));
3864 addHistoryRecordLocked(elapsedRealtime, uptime);
3865 } else {
3866 stopAllWifiSignalStrengthTimersLocked(-1);
3867 }
3868 mWifiSignalStrengthBin = strengthBin;
3869 }
3870 }
3871
The Android Open Source Project10592532009-03-18 17:39:46 -07003872 public void noteBluetoothOnLocked() {
3873 if (!mBluetoothOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003874 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003875 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003876 mHistoryCur.states |= HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003877 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: "
3878 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003879 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003880 mBluetoothOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003881 mBluetoothOnTimer.startRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003882 scheduleSyncExternalStatsLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003883 }
3884 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003885
The Android Open Source Project10592532009-03-18 17:39:46 -07003886 public void noteBluetoothOffLocked() {
3887 if (mBluetoothOn) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003888 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003889 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003890 mHistoryCur.states &= ~HistoryItem.STATE_BLUETOOTH_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003891 if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: "
3892 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003893 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003894 mBluetoothOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003895 mBluetoothOnTimer.stopRunningLocked(elapsedRealtime);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07003896 scheduleSyncExternalStatsLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07003897 }
3898 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003899
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003900 public void noteBluetoothStateLocked(int bluetoothState) {
3901 if (DEBUG) Log.i(TAG, "Bluetooth state -> " + bluetoothState);
3902 if (mBluetoothState != bluetoothState) {
3903 final long elapsedRealtime = SystemClock.elapsedRealtime();
3904 if (mBluetoothState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003905 mBluetoothStateTimer[mBluetoothState].stopRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003906 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003907 mBluetoothState = bluetoothState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003908 mBluetoothStateTimer[bluetoothState].startRunningLocked(elapsedRealtime);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08003909 }
3910 }
3911
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003912 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003913
The Android Open Source Project10592532009-03-18 17:39:46 -07003914 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003915 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003916 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003917 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003918 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003919 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003920 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
3921 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003922 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003923 }
3924 mWifiFullLockNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003925 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003926 }
3927
3928 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003929 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003930 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003931 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003932 mWifiFullLockNesting--;
3933 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003934 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003935 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
3936 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003937 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003938 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003939 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003940 }
3941
Nick Pelly6ccaa542012-06-15 15:22:47 -07003942 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003943
Nick Pelly6ccaa542012-06-15 15:22:47 -07003944 public void noteWifiScanStartedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003945 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003946 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003947 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003948 if (mWifiScanNesting == 0) {
3949 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
3950 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003951 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003952 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003953 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07003954 mWifiScanNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003955 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003956 }
3957
Nick Pelly6ccaa542012-06-15 15:22:47 -07003958 public void noteWifiScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003959 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003960 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003961 final long uptime = SystemClock.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07003962 mWifiScanNesting--;
3963 if (mWifiScanNesting == 0) {
3964 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
3965 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003966 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003967 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003968 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003969 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07003970 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003971
Robert Greenwalta029ea12013-09-25 16:38:12 -07003972 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003973 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003974 final long elapsedRealtime = SystemClock.elapsedRealtime();
3975 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003976 }
3977
3978 public void noteWifiBatchedScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003979 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003980 final long elapsedRealtime = SystemClock.elapsedRealtime();
3981 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07003982 }
3983
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003984 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003985
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003986 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003987 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003988 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003989 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003990 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003991 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003992 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
3993 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07003994 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003995 }
3996 mWifiMulticastNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003997 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07003998 }
3999
4000 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004001 uid = mapUid(uid);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004002 final long elapsedRealtime = SystemClock.elapsedRealtime();
Dianne Hackborn40c87252014-03-19 16:55:40 -07004003 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004004 mWifiMulticastNesting--;
4005 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004006 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004007 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
4008 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004009 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004010 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004011 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004012 }
4013
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004014 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
4015 int N = ws.size();
4016 for (int i=0; i<N; i++) {
4017 noteFullWifiLockAcquiredLocked(ws.get(i));
4018 }
4019 }
4020
4021 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
4022 int N = ws.size();
4023 for (int i=0; i<N; i++) {
4024 noteFullWifiLockReleasedLocked(ws.get(i));
4025 }
4026 }
4027
Nick Pelly6ccaa542012-06-15 15:22:47 -07004028 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004029 int N = ws.size();
4030 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004031 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004032 }
4033 }
4034
Nick Pelly6ccaa542012-06-15 15:22:47 -07004035 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004036 int N = ws.size();
4037 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004038 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004039 }
4040 }
4041
Robert Greenwalta029ea12013-09-25 16:38:12 -07004042 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
4043 int N = ws.size();
4044 for (int i=0; i<N; i++) {
4045 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
4046 }
4047 }
4048
4049 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
4050 int N = ws.size();
4051 for (int i=0; i<N; i++) {
4052 noteWifiBatchedScanStoppedLocked(ws.get(i));
4053 }
4054 }
4055
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004056 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
4057 int N = ws.size();
4058 for (int i=0; i<N; i++) {
4059 noteWifiMulticastEnabledLocked(ws.get(i));
4060 }
4061 }
4062
4063 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
4064 int N = ws.size();
4065 for (int i=0; i<N; i++) {
4066 noteWifiMulticastDisabledLocked(ws.get(i));
4067 }
4068 }
4069
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004070 private static String[] includeInStringArray(String[] array, String str) {
4071 if (ArrayUtils.indexOf(array, str) >= 0) {
4072 return array;
4073 }
4074 String[] newArray = new String[array.length+1];
4075 System.arraycopy(array, 0, newArray, 0, array.length);
4076 newArray[array.length] = str;
4077 return newArray;
4078 }
4079
4080 private static String[] excludeFromStringArray(String[] array, String str) {
4081 int index = ArrayUtils.indexOf(array, str);
4082 if (index >= 0) {
4083 String[] newArray = new String[array.length-1];
4084 if (index > 0) {
4085 System.arraycopy(array, 0, newArray, 0, index);
4086 }
4087 if (index < array.length-1) {
4088 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
4089 }
4090 return newArray;
4091 }
4092 return array;
4093 }
4094
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004095 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07004096 if (TextUtils.isEmpty(iface)) return;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004097 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004098 mMobileIfaces = includeInStringArray(mMobileIfaces, iface);
4099 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004100 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004101 mMobileIfaces = excludeFromStringArray(mMobileIfaces, iface);
4102 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mMobileIfaces);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004103 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004104 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004105 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
4106 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004107 } else {
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08004108 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
4109 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004110 }
4111 }
4112
4113 public void noteNetworkStatsEnabledLocked() {
4114 // During device boot, qtaguid isn't enabled until after the inital
4115 // loading of battery stats. Now that they're enabled, take our initial
4116 // snapshot for future delta calculation.
Adam Lesinskie08af192015-03-25 16:42:59 -07004117 final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
4118 updateMobileRadioStateLocked(elapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07004119 updateWifiStateLocked(null);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07004120 }
4121
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004122 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
4123 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004124 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004125
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004126 @Override public int getScreenOnCount(int which) {
4127 return mScreenOnTimer.getCountLocked(which);
4128 }
4129
Dianne Hackborn617f8772009-03-31 15:04:46 -07004130 @Override public long getScreenBrightnessTime(int brightnessBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004131 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004132 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004133 elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004134 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004135
Jeff Browne95c3cd2014-05-02 16:59:26 -07004136 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
4137 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004138 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004139
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004140 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) {
4141 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004142 }
4143
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004144 @Override public int getPowerSaveModeEnabledCount(int which) {
4145 return mPowerSaveModeEnabledTimer.getCountLocked(which);
4146 }
4147
4148 @Override public long getDeviceIdleModeEnabledTime(long elapsedRealtimeUs, int which) {
4149 return mDeviceIdleModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4150 }
4151
4152 @Override public int getDeviceIdleModeEnabledCount(int which) {
4153 return mDeviceIdleModeEnabledTimer.getCountLocked(which);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004154 }
4155
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004156 @Override public long getDeviceIdlingTime(long elapsedRealtimeUs, int which) {
4157 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4158 }
4159
4160 @Override public int getDeviceIdlingCount(int which) {
4161 return mDeviceIdlingTimer.getCountLocked(which);
4162 }
4163
Dianne Hackborn1e01d162014-12-04 17:46:42 -08004164 @Override public int getNumConnectivityChange(int which) {
4165 int val = mNumConnectivityChange;
4166 if (which == STATS_CURRENT) {
4167 val -= mLoadedNumConnectivityChange;
4168 } else if (which == STATS_SINCE_UNPLUGGED) {
4169 val -= mUnpluggedNumConnectivityChange;
4170 }
4171 return val;
4172 }
4173
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004174 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
4175 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004176 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004177
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004178 @Override public int getPhoneOnCount(int which) {
4179 return mPhoneOnTimer.getCountLocked(which);
4180 }
4181
Dianne Hackborn627bba72009-03-24 22:32:56 -07004182 @Override public long getPhoneSignalStrengthTime(int strengthBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004183 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004184 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004185 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004186 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07004187
4188 @Override public long getPhoneSignalScanningTime(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004189 long elapsedRealtimeUs, int which) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07004190 return mPhoneSignalScanningTimer.getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004191 elapsedRealtimeUs, which);
Amith Yamasanif37447b2009-10-08 18:28:01 -07004192 }
4193
Catherine Liufb900812012-07-17 14:12:56 -05004194 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
4195 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004196 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004197
Dianne Hackborn627bba72009-03-24 22:32:56 -07004198 @Override public long getPhoneDataConnectionTime(int dataType,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004199 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004200 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004201 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004202 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004203
Dianne Hackborn617f8772009-03-31 15:04:46 -07004204 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07004205 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004206 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004207
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004208 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
4209 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004210 }
4211
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004212 @Override public int getMobileRadioActiveCount(int which) {
4213 return mMobileRadioActiveTimer.getCountLocked(which);
4214 }
4215
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004216 @Override public long getMobileRadioActiveAdjustedTime(int which) {
4217 return mMobileRadioActiveAdjustedTime.getCountLocked(which);
4218 }
4219
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004220 @Override public long getMobileRadioActiveUnknownTime(int which) {
4221 return mMobileRadioActiveUnknownTime.getCountLocked(which);
4222 }
4223
4224 @Override public int getMobileRadioActiveUnknownCount(int which) {
4225 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
4226 }
4227
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004228 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
4229 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004230 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004231
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004232 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
4233 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07004234 }
4235
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004236 @Override public long getWifiStateTime(int wifiState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004237 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004238 return mWifiStateTimer[wifiState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004239 elapsedRealtimeUs, which);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004240 }
4241
4242 @Override public int getWifiStateCount(int wifiState, int which) {
4243 return mWifiStateTimer[wifiState].getCountLocked(which);
4244 }
4245
Dianne Hackborn3251b902014-06-20 14:40:53 -07004246 @Override public long getWifiSupplStateTime(int state,
4247 long elapsedRealtimeUs, int which) {
4248 return mWifiSupplStateTimer[state].getTotalTimeLocked(
4249 elapsedRealtimeUs, which);
4250 }
4251
4252 @Override public int getWifiSupplStateCount(int state, int which) {
4253 return mWifiSupplStateTimer[state].getCountLocked(which);
4254 }
4255
4256 @Override public long getWifiSignalStrengthTime(int strengthBin,
4257 long elapsedRealtimeUs, int which) {
4258 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
4259 elapsedRealtimeUs, which);
4260 }
4261
4262 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) {
4263 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which);
4264 }
4265
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004266 @Override public long getBluetoothOnTime(long elapsedRealtimeUs, int which) {
4267 return mBluetoothOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004268 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004269
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004270 @Override public long getBluetoothStateTime(int bluetoothState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004271 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004272 return mBluetoothStateTimer[bluetoothState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004273 elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004274 }
4275
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004276 @Override public int getBluetoothStateCount(int bluetoothState, int which) {
4277 return mBluetoothStateTimer[bluetoothState].getCountLocked(which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004278 }
4279
Adam Lesinski33dac552015-03-09 15:24:48 -07004280 @Override public long getBluetoothControllerActivity(int type, int which) {
4281 if (type >= 0 && type < mBluetoothActivityCounters.length) {
4282 return mBluetoothActivityCounters[type].getCountLocked(which);
4283 }
4284 return 0;
4285 }
4286
4287 @Override public long getWifiControllerActivity(int type, int which) {
4288 if (type >= 0 && type < mWifiActivityCounters.length) {
4289 return mWifiActivityCounters[type].getCountLocked(which);
4290 }
4291 return 0;
4292 }
4293
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004294 @Override public long getFlashlightOnTime(long elapsedRealtimeUs, int which) {
4295 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
4296 }
4297
4298 @Override public long getFlashlightOnCount(int which) {
4299 return mFlashlightOnTimer.getCountLocked(which);
4300 }
4301
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004302 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004303 public long getNetworkActivityBytes(int type, int which) {
4304 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
4305 return mNetworkByteActivityCounters[type].getCountLocked(which);
4306 } else {
4307 return 0;
4308 }
4309 }
4310
4311 @Override
4312 public long getNetworkActivityPackets(int type, int which) {
4313 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
4314 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004315 } else {
4316 return 0;
4317 }
4318 }
4319
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07004320 boolean isStartClockTimeValid() {
4321 return mStartClockTime > 365*24*60*60*1000L;
4322 }
4323
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08004324 @Override public long getStartClockTime() {
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07004325 if (!isStartClockTimeValid()) {
4326 // If the last clock time we got was very small, then we hadn't had a real
4327 // time yet, so try to get it again.
4328 mStartClockTime = System.currentTimeMillis();
4329 if (isStartClockTimeValid()) {
4330 recordCurrentTimeChangeLocked(mStartClockTime, SystemClock.elapsedRealtime(),
4331 SystemClock.uptimeMillis());
4332 }
4333 }
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08004334 return mStartClockTime;
4335 }
4336
Dianne Hackborncd0e3352014-08-07 17:08:09 -07004337 @Override public String getStartPlatformVersion() {
4338 return mStartPlatformVersion;
4339 }
4340
4341 @Override public String getEndPlatformVersion() {
4342 return mEndPlatformVersion;
4343 }
4344
4345 @Override public int getParcelVersion() {
4346 return VERSION;
4347 }
4348
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004349 @Override public boolean getIsOnBattery() {
4350 return mOnBattery;
4351 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004352
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004353 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
4354 return mUidStats;
4355 }
4356
4357 /**
4358 * The statistics associated with a particular uid.
4359 */
4360 public final class Uid extends BatteryStats.Uid {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004362 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004363
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004364 boolean mWifiRunning;
4365 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004366
The Android Open Source Project10592532009-03-18 17:39:46 -07004367 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07004368 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004369
Nick Pelly6ccaa542012-06-15 15:22:47 -07004370 boolean mWifiScanStarted;
4371 StopwatchTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004372
Dianne Hackborn61659e52014-07-09 16:13:01 -07004373 static final int NO_BATCHED_SCAN_STARTED = -1;
Robert Greenwalta029ea12013-09-25 16:38:12 -07004374 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4375 StopwatchTimer[] mWifiBatchedScanTimer;
4376
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004377 boolean mWifiMulticastEnabled;
4378 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004379
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004380 StopwatchTimer mAudioTurnedOnTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004381 StopwatchTimer mVideoTurnedOnTimer;
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004382
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004383 StopwatchTimer mForegroundActivityTimer;
4384
Dianne Hackborn61659e52014-07-09 16:13:01 -07004385 static final int PROCESS_STATE_NONE = NUM_PROCESS_STATE;
4386 int mProcessState = PROCESS_STATE_NONE;
4387 StopwatchTimer[] mProcessStateTimer;
4388
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004389 BatchTimer mVibratorOnTimer;
4390
Dianne Hackborn617f8772009-03-31 15:04:46 -07004391 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004392
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004393 LongSamplingCounter[] mNetworkByteActivityCounters;
4394 LongSamplingCounter[] mNetworkPacketActivityCounters;
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004395 LongSamplingCounter mMobileRadioActiveTime;
4396 LongSamplingCounter mMobileRadioActiveCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004397
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004398 /**
Adam Lesinskie08af192015-03-25 16:42:59 -07004399 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode.
4400 */
4401 LongSamplingCounter[] mWifiControllerTime =
4402 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
4403
4404 /**
4405 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode.
4406 */
4407 LongSamplingCounter[] mBluetoothControllerTime =
4408 new LongSamplingCounter[NUM_CONTROLLER_ACTIVITY_TYPES];
4409
4410 /**
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08004411 * The CPU times we had at the last history details update.
4412 */
4413 long mLastStepUserTime;
4414 long mLastStepSystemTime;
4415 long mCurStepUserTime;
4416 long mCurStepSystemTime;
4417
4418 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004419 * The statistics we have collected for this uid's wake locks.
4420 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004421 final OverflowArrayMap<Wakelock> mWakelockStats = new OverflowArrayMap<Wakelock>() {
4422 @Override public Wakelock instantiateObject() { return new Wakelock(); }
4423 };
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004424
4425 /**
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004426 * The statistics we have collected for this uid's syncs.
4427 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004428 final OverflowArrayMap<StopwatchTimer> mSyncStats = new OverflowArrayMap<StopwatchTimer>() {
4429 @Override public StopwatchTimer instantiateObject() {
4430 return new StopwatchTimer(Uid.this, SYNC, null, mOnBatteryTimeBase);
4431 }
4432 };
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004433
4434 /**
4435 * The statistics we have collected for this uid's jobs.
4436 */
Dianne Hackbornd953c532014-08-16 18:17:38 -07004437 final OverflowArrayMap<StopwatchTimer> mJobStats = new OverflowArrayMap<StopwatchTimer>() {
4438 @Override public StopwatchTimer instantiateObject() {
4439 return new StopwatchTimer(Uid.this, JOB, null, mOnBatteryTimeBase);
4440 }
4441 };
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004442
4443 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004444 * The statistics we have collected for this uid's sensor activations.
4445 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004446 final SparseArray<Sensor> mSensorStats = new SparseArray<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004447
4448 /**
4449 * The statistics we have collected for this uid's processes.
4450 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004451 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004452
4453 /**
4454 * The statistics we have collected for this uid's processes.
4455 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004456 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004457
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004458 /**
4459 * The transient wake stats we have collected for this uid's pids.
4460 */
Adam Lesinskie08af192015-03-25 16:42:59 -07004461 final SparseArray<Pid> mPids = new SparseArray<>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004462
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004463 public Uid(int uid) {
4464 mUid = uid;
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004465 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004466 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004467 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004468 mFullWifiLockTimers, mOnBatteryTimeBase);
Nick Pelly6ccaa542012-06-15 15:22:47 -07004469 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004470 mWifiScanTimers, mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004471 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004472 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004473 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn61659e52014-07-09 16:13:01 -07004474 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004475 }
4476
4477 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004478 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004479 return mWakelockStats.getMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004480 }
4481
4482 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004483 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004484 return mSyncStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004485 }
4486
4487 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004488 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07004489 return mJobStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07004490 }
4491
4492 @Override
Dianne Hackborn61659e52014-07-09 16:13:01 -07004493 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004494 return mSensorStats;
4495 }
4496
4497 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004498 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004499 return mProcessStats;
4500 }
4501
4502 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07004503 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004504 return mPackageStats;
4505 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004506
4507 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004508 public int getUid() {
4509 return mUid;
4510 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07004511
4512 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004513 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004514 if (!mWifiRunning) {
4515 mWifiRunning = true;
4516 if (mWifiRunningTimer == null) {
4517 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004518 mWifiRunningTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004519 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004520 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004521 }
4522 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004523
Dianne Hackborn617f8772009-03-31 15:04:46 -07004524 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004525 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004526 if (mWifiRunning) {
4527 mWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004528 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004529 }
4530 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004531
Dianne Hackborn617f8772009-03-31 15:04:46 -07004532 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004533 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07004534 if (!mFullWifiLockOut) {
4535 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004536 if (mFullWifiLockTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004537 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004538 mFullWifiLockTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004539 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004540 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004541 }
4542 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004543
The Android Open Source Project10592532009-03-18 17:39:46 -07004544 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004545 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07004546 if (mFullWifiLockOut) {
4547 mFullWifiLockOut = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004548 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004549 }
4550 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004551
The Android Open Source Project10592532009-03-18 17:39:46 -07004552 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004553 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004554 if (!mWifiScanStarted) {
4555 mWifiScanStarted = true;
4556 if (mWifiScanTimer == null) {
4557 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004558 mWifiScanTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004559 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004560 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004561 }
4562 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004563
The Android Open Source Project10592532009-03-18 17:39:46 -07004564 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004565 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004566 if (mWifiScanStarted) {
4567 mWifiScanStarted = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004568 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07004569 }
4570 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004571
4572 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004573 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004574 int bin = 0;
4575 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS) {
4576 csph = csph >> 3;
4577 bin++;
4578 }
4579
4580 if (mWifiBatchedScanBinStarted == bin) return;
4581
4582 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
4583 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004584 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004585 }
4586 mWifiBatchedScanBinStarted = bin;
4587 if (mWifiBatchedScanTimer[bin] == null) {
4588 makeWifiBatchedScanBin(bin, null);
4589 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004590 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004591 }
4592
4593 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004594 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004595 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
4596 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004597 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004598 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
4599 }
4600 }
4601
4602 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004603 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004604 if (!mWifiMulticastEnabled) {
4605 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004606 if (mWifiMulticastTimer == null) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004607 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004608 mWifiMulticastTimers, mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004609 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004610 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004611 }
4612 }
4613
4614 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004615 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004616 if (mWifiMulticastEnabled) {
4617 mWifiMulticastEnabled = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004618 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004619 }
4620 }
4621
Adam Lesinskie08af192015-03-25 16:42:59 -07004622 public void noteWifiControllerActivityLocked(int type, long timeMs) {
4623 if (mWifiControllerTime[type] == null) {
4624 mWifiControllerTime[type] = new LongSamplingCounter(mOnBatteryTimeBase);
4625 }
4626 mWifiControllerTime[type].addCountLocked(timeMs);
4627 }
4628
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004629 public StopwatchTimer createAudioTurnedOnTimerLocked() {
4630 if (mAudioTurnedOnTimer == null) {
4631 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004632 mAudioTurnedOnTimers, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004633 }
4634 return mAudioTurnedOnTimer;
4635 }
4636
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004637 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004638 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4639 }
4640
4641 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
4642 if (mAudioTurnedOnTimer != null) {
4643 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004644 }
4645 }
4646
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004647 public void noteResetAudioLocked(long elapsedRealtimeMs) {
4648 if (mAudioTurnedOnTimer != null) {
4649 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004650 }
4651 }
4652
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004653 public StopwatchTimer createVideoTurnedOnTimerLocked() {
4654 if (mVideoTurnedOnTimer == null) {
4655 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004656 mVideoTurnedOnTimers, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004657 }
4658 return mVideoTurnedOnTimer;
4659 }
4660
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004661 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004662 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
4663 }
4664
4665 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
4666 if (mVideoTurnedOnTimer != null) {
4667 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004668 }
4669 }
4670
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004671 public void noteResetVideoLocked(long elapsedRealtimeMs) {
4672 if (mVideoTurnedOnTimer != null) {
4673 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004674 }
4675 }
4676
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004677 public StopwatchTimer createForegroundActivityTimerLocked() {
4678 if (mForegroundActivityTimer == null) {
4679 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004680 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004681 }
4682 return mForegroundActivityTimer;
4683 }
4684
4685 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004686 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004687 // We always start, since we want multiple foreground PIDs to nest
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004688 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004689 }
4690
4691 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004692 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004693 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004694 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004695 }
4696 }
4697
Dianne Hackborn61659e52014-07-09 16:13:01 -07004698 void updateUidProcessStateLocked(int state, long elapsedRealtimeMs) {
4699 if (mProcessState == state) return;
4700
4701 if (mProcessState != PROCESS_STATE_NONE) {
4702 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs);
4703 }
4704 mProcessState = state;
4705 if (state != PROCESS_STATE_NONE) {
4706 if (mProcessStateTimer[state] == null) {
4707 makeProcessState(state, null);
4708 }
4709 mProcessStateTimer[state].startRunningLocked(elapsedRealtimeMs);
4710 }
4711 }
4712
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004713 public BatchTimer createVibratorOnTimerLocked() {
4714 if (mVibratorOnTimer == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004715 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004716 }
4717 return mVibratorOnTimer;
4718 }
4719
4720 public void noteVibratorOnLocked(long durationMillis) {
4721 createVibratorOnTimerLocked().addDuration(BatteryStatsImpl.this, durationMillis);
4722 }
4723
4724 public void noteVibratorOffLocked() {
4725 if (mVibratorOnTimer != null) {
4726 mVibratorOnTimer.abortLastDuration(BatteryStatsImpl.this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004727 }
4728 }
4729
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004730 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004731 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004732 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004733 return 0;
4734 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004735 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004736 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004737
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004738 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004739 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004740 if (mFullWifiLockTimer == null) {
4741 return 0;
4742 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004743 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004744 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004745
4746 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004747 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07004748 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004749 return 0;
4750 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004751 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07004752 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004753
4754 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07004755 public int getWifiScanCount(int which) {
4756 if (mWifiScanTimer == null) {
4757 return 0;
4758 }
4759 return mWifiScanTimer.getCountLocked(which);
4760 }
4761
4762 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004763 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07004764 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
4765 if (mWifiBatchedScanTimer[csphBin] == null) {
4766 return 0;
4767 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004768 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004769 }
4770
4771 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07004772 public int getWifiBatchedScanCount(int csphBin, int which) {
4773 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
4774 if (mWifiBatchedScanTimer[csphBin] == null) {
4775 return 0;
4776 }
4777 return mWifiBatchedScanTimer[csphBin].getCountLocked(which);
4778 }
4779
4780 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004781 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004782 if (mWifiMulticastTimer == null) {
4783 return 0;
4784 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004785 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07004786 }
4787
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004788 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004789 public long getAudioTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004790 if (mAudioTurnedOnTimer == null) {
4791 return 0;
4792 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004793 return mAudioTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004794 }
4795
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004796 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004797 public long getVideoTurnedOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004798 if (mVideoTurnedOnTimer == null) {
4799 return 0;
4800 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004801 return mVideoTurnedOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004802 }
4803
Dianne Hackborn617f8772009-03-31 15:04:46 -07004804 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004805 public Timer getForegroundActivityTimer() {
4806 return mForegroundActivityTimer;
4807 }
4808
Dianne Hackborn61659e52014-07-09 16:13:01 -07004809 void makeProcessState(int i, Parcel in) {
4810 if (i < 0 || i >= NUM_PROCESS_STATE) return;
4811
4812 if (in == null) {
4813 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null,
4814 mOnBatteryTimeBase);
4815 } else {
4816 mProcessStateTimer[i] = new StopwatchTimer(this, PROCESS_STATE, null,
4817 mOnBatteryTimeBase, in);
4818 }
4819 }
4820
4821 @Override
4822 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) {
4823 if (state < 0 || state >= NUM_PROCESS_STATE) return 0;
4824 if (mProcessStateTimer[state] == null) {
4825 return 0;
4826 }
4827 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which);
4828 }
4829
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004830 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004831 public Timer getVibratorOnTimer() {
4832 return mVibratorOnTimer;
4833 }
4834
4835 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07004836 public void noteUserActivityLocked(int type) {
4837 if (mUserActivityCounters == null) {
4838 initUserActivityLocked();
4839 }
Jeff Browndf693de2012-07-27 12:03:38 -07004840 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
4841 mUserActivityCounters[type].stepAtomic();
4842 } else {
4843 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
4844 new Throwable());
4845 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07004846 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004847
Dianne Hackborn617f8772009-03-31 15:04:46 -07004848 @Override
4849 public boolean hasUserActivity() {
4850 return mUserActivityCounters != null;
4851 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004852
Dianne Hackborn617f8772009-03-31 15:04:46 -07004853 @Override
4854 public int getUserActivityCount(int type, int which) {
4855 if (mUserActivityCounters == null) {
4856 return 0;
4857 }
Evan Millarc64edde2009-04-18 12:26:32 -07004858 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004859 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004860
Robert Greenwalta029ea12013-09-25 16:38:12 -07004861 void makeWifiBatchedScanBin(int i, Parcel in) {
4862 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
4863
4864 ArrayList<StopwatchTimer> collected = mWifiBatchedScanTimers.get(i);
4865 if (collected == null) {
4866 collected = new ArrayList<StopwatchTimer>();
4867 mWifiBatchedScanTimers.put(i, collected);
4868 }
4869 if (in == null) {
4870 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004871 mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004872 } else {
4873 mWifiBatchedScanTimer[i] = new StopwatchTimer(this, WIFI_BATCHED_SCAN, collected,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004874 mOnBatteryTimeBase, in);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004875 }
4876 }
4877
4878
Dianne Hackborn617f8772009-03-31 15:04:46 -07004879 void initUserActivityLocked() {
4880 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
4881 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004882 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004883 }
4884 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004885
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004886 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
4887 if (mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004888 initNetworkActivityLocked();
4889 }
4890 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004891 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
4892 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004893 } else {
4894 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
4895 new Throwable());
4896 }
4897 }
4898
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004899 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
4900 if (mNetworkByteActivityCounters == null) {
4901 initNetworkActivityLocked();
4902 }
4903 mMobileRadioActiveTime.addCountLocked(batteryUptime);
4904 mMobileRadioActiveCount.addCountLocked(1);
4905 }
4906
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004907 @Override
4908 public boolean hasNetworkActivity() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004909 return mNetworkByteActivityCounters != null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004910 }
4911
4912 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004913 public long getNetworkActivityBytes(int type, int which) {
4914 if (mNetworkByteActivityCounters != null && type >= 0
4915 && type < mNetworkByteActivityCounters.length) {
4916 return mNetworkByteActivityCounters[type].getCountLocked(which);
4917 } else {
4918 return 0;
4919 }
4920 }
4921
4922 @Override
4923 public long getNetworkActivityPackets(int type, int which) {
4924 if (mNetworkPacketActivityCounters != null && type >= 0
4925 && type < mNetworkPacketActivityCounters.length) {
4926 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004927 } else {
4928 return 0;
4929 }
4930 }
4931
Dianne Hackbornd45665b2014-02-26 12:35:32 -08004932 @Override
4933 public long getMobileRadioActiveTime(int which) {
4934 return mMobileRadioActiveTime != null
4935 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
4936 }
4937
4938 @Override
4939 public int getMobileRadioActiveCount(int which) {
4940 return mMobileRadioActiveCount != null
4941 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
4942 }
4943
Adam Lesinskie08af192015-03-25 16:42:59 -07004944 @Override
4945 public long getWifiControllerActivity(int type, int which) {
4946 if (type >= 0 && type < NUM_CONTROLLER_ACTIVITY_TYPES &&
4947 mWifiControllerTime[type] != null) {
4948 return mWifiControllerTime[type].getCountLocked(which);
4949 }
4950 return 0;
4951 }
4952
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004953 void initNetworkActivityLocked() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08004954 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
4955 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004956 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004957 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
4958 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07004959 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004960 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase);
4961 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004962 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004963
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004964 /**
4965 * Clear all stats for this uid. Returns true if the uid is completely
4966 * inactive so can be dropped.
4967 */
4968 boolean reset() {
4969 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004970
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004971 if (mWifiRunningTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004972 active |= !mWifiRunningTimer.reset(false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004973 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004974 }
4975 if (mFullWifiLockTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004976 active |= !mFullWifiLockTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004977 active |= mFullWifiLockOut;
4978 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07004979 if (mWifiScanTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004980 active |= !mWifiScanTimer.reset(false);
Nick Pelly6ccaa542012-06-15 15:22:47 -07004981 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004982 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07004983 if (mWifiBatchedScanTimer != null) {
4984 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
4985 if (mWifiBatchedScanTimer[i] != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004986 active |= !mWifiBatchedScanTimer[i].reset(false);
Robert Greenwalta029ea12013-09-25 16:38:12 -07004987 }
4988 }
4989 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
4990 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004991 if (mWifiMulticastTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004992 active |= !mWifiMulticastTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004993 active |= mWifiMulticastEnabled;
4994 }
4995 if (mAudioTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004996 active |= !mAudioTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004997 }
4998 if (mVideoTurnedOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004999 active |= !mVideoTurnedOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005000 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005001 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005002 active |= !mForegroundActivityTimer.reset(false);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005003 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005004 if (mProcessStateTimer != null) {
5005 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5006 if (mProcessStateTimer[i] != null) {
5007 active |= !mProcessStateTimer[i].reset(false);
5008 }
5009 }
5010 active |= (mProcessState != PROCESS_STATE_NONE);
5011 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005012 if (mVibratorOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005013 if (mVibratorOnTimer.reset(false)) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005014 mVibratorOnTimer.detach();
5015 mVibratorOnTimer = null;
5016 } else {
5017 active = true;
5018 }
5019 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005020
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005021 if (mUserActivityCounters != null) {
5022 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5023 mUserActivityCounters[i].reset(false);
5024 }
5025 }
5026
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005027 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005028 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005029 mNetworkByteActivityCounters[i].reset(false);
5030 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005031 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005032 mMobileRadioActiveTime.reset(false);
5033 mMobileRadioActiveCount.reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005034 }
5035
Adam Lesinskie08af192015-03-25 16:42:59 -07005036 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5037 if (mWifiControllerTime[i] != null) {
5038 mWifiControllerTime[i].reset(false);
5039 }
5040
5041 if (mBluetoothControllerTime[i] != null) {
5042 mBluetoothControllerTime[i].reset(false);
5043 }
5044 }
5045
Dianne Hackbornd953c532014-08-16 18:17:38 -07005046 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
5047 for (int iw=wakeStats.size()-1; iw>=0; iw--) {
5048 Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005049 if (wl.reset()) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005050 wakeStats.removeAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005051 } else {
5052 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005053 }
5054 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005055 mWakelockStats.cleanup();
5056 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap();
5057 for (int is=syncStats.size()-1; is>=0; is--) {
5058 StopwatchTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005059 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005060 syncStats.removeAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005061 timer.detach();
5062 } else {
5063 active = true;
5064 }
5065 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005066 mSyncStats.cleanup();
5067 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
5068 for (int ij=jobStats.size()-1; ij>=0; ij--) {
5069 StopwatchTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005070 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005071 jobStats.removeAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005072 timer.detach();
5073 } else {
5074 active = true;
5075 }
5076 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005077 mJobStats.cleanup();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005078 for (int ise=mSensorStats.size()-1; ise>=0; ise--) {
5079 Sensor s = mSensorStats.valueAt(ise);
5080 if (s.reset()) {
5081 mSensorStats.removeAt(ise);
5082 } else {
5083 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005084 }
5085 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005086 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
5087 Proc proc = mProcessStats.valueAt(ip);
5088 if (proc.mProcessState == PROCESS_STATE_NONE) {
5089 proc.detach();
5090 mProcessStats.removeAt(ip);
5091 } else {
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005092 proc.reset();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005093 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005094 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005095 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005096 if (mPids.size() > 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005097 for (int i=mPids.size()-1; i>=0; i--) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005098 Pid pid = mPids.valueAt(i);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005099 if (pid.mWakeNesting > 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005100 active = true;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005101 } else {
5102 mPids.removeAt(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005103 }
5104 }
5105 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005106 if (mPackageStats.size() > 0) {
5107 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
5108 while (it.hasNext()) {
5109 Map.Entry<String, Pkg> pkgEntry = it.next();
5110 Pkg p = pkgEntry.getValue();
5111 p.detach();
5112 if (p.mServiceStats.size() > 0) {
5113 Iterator<Map.Entry<String, Pkg.Serv>> it2
5114 = p.mServiceStats.entrySet().iterator();
5115 while (it2.hasNext()) {
5116 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
5117 servEntry.getValue().detach();
5118 }
5119 }
5120 }
5121 mPackageStats.clear();
5122 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005123
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005124 mLastStepUserTime = mLastStepSystemTime = 0;
5125 mCurStepUserTime = mCurStepSystemTime = 0;
5126
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005127 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005128 if (mWifiRunningTimer != null) {
5129 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005130 }
5131 if (mFullWifiLockTimer != null) {
5132 mFullWifiLockTimer.detach();
5133 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005134 if (mWifiScanTimer != null) {
5135 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005136 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005137 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5138 if (mWifiBatchedScanTimer[i] != null) {
5139 mWifiBatchedScanTimer[i].detach();
5140 }
5141 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005142 if (mWifiMulticastTimer != null) {
5143 mWifiMulticastTimer.detach();
5144 }
5145 if (mAudioTurnedOnTimer != null) {
5146 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005147 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005148 }
5149 if (mVideoTurnedOnTimer != null) {
5150 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005151 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005152 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005153 if (mForegroundActivityTimer != null) {
5154 mForegroundActivityTimer.detach();
5155 mForegroundActivityTimer = null;
5156 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005157 if (mUserActivityCounters != null) {
5158 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5159 mUserActivityCounters[i].detach();
5160 }
5161 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005162 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005163 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005164 mNetworkByteActivityCounters[i].detach();
5165 mNetworkPacketActivityCounters[i].detach();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005166 }
5167 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005168
5169 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5170 if (mWifiControllerTime[i] != null) {
5171 mWifiControllerTime[i].detach();
5172 }
5173
5174 if (mBluetoothControllerTime[i] != null) {
5175 mBluetoothControllerTime[i].detach();
5176 }
5177 }
Dianne Hackborne5167ca2014-03-08 14:39:10 -08005178 mPids.clear();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005179 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005180
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005181 return !active;
5182 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005183
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005184 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005185 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
5186 int NW = wakeStats.size();
Dianne Hackborn61659e52014-07-09 16:13:01 -07005187 out.writeInt(NW);
5188 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005189 out.writeString(wakeStats.keyAt(iw));
5190 Uid.Wakelock wakelock = wakeStats.valueAt(iw);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005191 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005192 }
5193
Dianne Hackbornd953c532014-08-16 18:17:38 -07005194 final ArrayMap<String, StopwatchTimer> syncStats = mSyncStats.getMap();
5195 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005196 out.writeInt(NS);
5197 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005198 out.writeString(syncStats.keyAt(is));
5199 StopwatchTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005200 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
5201 }
5202
Dianne Hackbornd953c532014-08-16 18:17:38 -07005203 final ArrayMap<String, StopwatchTimer> jobStats = mJobStats.getMap();
5204 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005205 out.writeInt(NJ);
5206 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005207 out.writeString(jobStats.keyAt(ij));
5208 StopwatchTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005209 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
5210 }
5211
Dianne Hackborn61659e52014-07-09 16:13:01 -07005212 int NSE = mSensorStats.size();
5213 out.writeInt(NSE);
5214 for (int ise=0; ise<NSE; ise++) {
5215 out.writeInt(mSensorStats.keyAt(ise));
5216 Uid.Sensor sensor = mSensorStats.valueAt(ise);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005217 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005218 }
5219
Dianne Hackborn61659e52014-07-09 16:13:01 -07005220 int NP = mProcessStats.size();
5221 out.writeInt(NP);
5222 for (int ip=0; ip<NP; ip++) {
5223 out.writeString(mProcessStats.keyAt(ip));
5224 Uid.Proc proc = mProcessStats.valueAt(ip);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005225 proc.writeToParcelLocked(out);
5226 }
5227
5228 out.writeInt(mPackageStats.size());
5229 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
5230 out.writeString(pkgEntry.getKey());
5231 Uid.Pkg pkg = pkgEntry.getValue();
5232 pkg.writeToParcelLocked(out);
5233 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005234
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005235 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005236 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005237 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005238 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005239 out.writeInt(0);
5240 }
5241 if (mFullWifiLockTimer != null) {
5242 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005243 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005244 } else {
5245 out.writeInt(0);
5246 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005247 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005248 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005249 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005250 } else {
5251 out.writeInt(0);
5252 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005253 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5254 if (mWifiBatchedScanTimer[i] != null) {
5255 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005256 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005257 } else {
5258 out.writeInt(0);
5259 }
5260 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005261 if (mWifiMulticastTimer != null) {
5262 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005263 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005264 } else {
5265 out.writeInt(0);
5266 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005267
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005268 if (mAudioTurnedOnTimer != null) {
5269 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005270 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005271 } else {
5272 out.writeInt(0);
5273 }
5274 if (mVideoTurnedOnTimer != null) {
5275 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005276 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005277 } else {
5278 out.writeInt(0);
5279 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005280 if (mForegroundActivityTimer != null) {
5281 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005282 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005283 } else {
5284 out.writeInt(0);
5285 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005286 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5287 if (mProcessStateTimer[i] != null) {
5288 out.writeInt(1);
5289 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs);
5290 } else {
5291 out.writeInt(0);
5292 }
5293 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005294 if (mVibratorOnTimer != null) {
5295 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005296 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005297 } else {
5298 out.writeInt(0);
5299 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005300 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07005301 out.writeInt(1);
5302 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
5303 mUserActivityCounters[i].writeToParcel(out);
5304 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005305 } else {
5306 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005307 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005308 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005309 out.writeInt(1);
5310 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005311 mNetworkByteActivityCounters[i].writeToParcel(out);
5312 mNetworkPacketActivityCounters[i].writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005313 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005314 mMobileRadioActiveTime.writeToParcel(out);
5315 mMobileRadioActiveCount.writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005316 } else {
5317 out.writeInt(0);
5318 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005319
5320 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5321 if (mWifiControllerTime[i] != null) {
5322 out.writeInt(1);
5323 mWifiControllerTime[i].writeToParcel(out);
5324 } else {
5325 out.writeInt(0);
5326 }
5327 }
5328
5329 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5330 if (mBluetoothControllerTime[i] != null) {
5331 out.writeInt(1);
5332 mBluetoothControllerTime[i].writeToParcel(out);
5333 } else {
5334 out.writeInt(0);
5335 }
5336 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005337 }
5338
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005339 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005340 int numWakelocks = in.readInt();
5341 mWakelockStats.clear();
5342 for (int j = 0; j < numWakelocks; j++) {
5343 String wakelockName = in.readString();
5344 Uid.Wakelock wakelock = new Wakelock();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005345 wakelock.readFromParcelLocked(timeBase, screenOffTimeBase, in);
Dianne Hackbornd953c532014-08-16 18:17:38 -07005346 mWakelockStats.add(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005347 }
5348
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005349 int numSyncs = in.readInt();
5350 mSyncStats.clear();
5351 for (int j = 0; j < numSyncs; j++) {
5352 String syncName = in.readString();
5353 if (in.readInt() != 0) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005354 mSyncStats.add(syncName,
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005355 new StopwatchTimer(Uid.this, SYNC, null, timeBase, in));
5356 }
5357 }
5358
5359 int numJobs = in.readInt();
5360 mJobStats.clear();
5361 for (int j = 0; j < numJobs; j++) {
5362 String jobName = in.readString();
5363 if (in.readInt() != 0) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005364 mJobStats.add(jobName, new StopwatchTimer(Uid.this, JOB, null, timeBase, in));
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005365 }
5366 }
5367
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005368 int numSensors = in.readInt();
5369 mSensorStats.clear();
5370 for (int k = 0; k < numSensors; k++) {
5371 int sensorNumber = in.readInt();
5372 Uid.Sensor sensor = new Sensor(sensorNumber);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005373 sensor.readFromParcelLocked(mOnBatteryTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005374 mSensorStats.put(sensorNumber, sensor);
5375 }
5376
5377 int numProcs = in.readInt();
5378 mProcessStats.clear();
5379 for (int k = 0; k < numProcs; k++) {
5380 String processName = in.readString();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005381 Uid.Proc proc = new Proc(processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005382 proc.readFromParcelLocked(in);
5383 mProcessStats.put(processName, proc);
5384 }
5385
5386 int numPkgs = in.readInt();
5387 mPackageStats.clear();
5388 for (int l = 0; l < numPkgs; l++) {
5389 String packageName = in.readString();
5390 Uid.Pkg pkg = new Pkg();
5391 pkg.readFromParcelLocked(in);
5392 mPackageStats.put(packageName, pkg);
5393 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005394
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005395 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005396 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005397 mWifiRunningTimer = new StopwatchTimer(Uid.this, WIFI_RUNNING,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005398 mWifiRunningTimers, mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005399 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005400 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005401 }
5402 mFullWifiLockOut = false;
5403 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005404 mFullWifiLockTimer = new StopwatchTimer(Uid.this, FULL_WIFI_LOCK,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005405 mFullWifiLockTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005406 } else {
5407 mFullWifiLockTimer = null;
5408 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005409 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005410 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005411 mWifiScanTimer = new StopwatchTimer(Uid.this, WIFI_SCAN,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005412 mWifiScanTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005413 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005414 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005415 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07005416 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
5417 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
5418 if (in.readInt() != 0) {
5419 makeWifiBatchedScanBin(i, in);
5420 } else {
5421 mWifiBatchedScanTimer[i] = null;
5422 }
5423 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005424 mWifiMulticastEnabled = false;
5425 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005426 mWifiMulticastTimer = new StopwatchTimer(Uid.this, WIFI_MULTICAST_ENABLED,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005427 mWifiMulticastTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005428 } else {
5429 mWifiMulticastTimer = null;
5430 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005431 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005432 mAudioTurnedOnTimer = new StopwatchTimer(Uid.this, AUDIO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07005433 mAudioTurnedOnTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005434 } else {
5435 mAudioTurnedOnTimer = null;
5436 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005437 if (in.readInt() != 0) {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07005438 mVideoTurnedOnTimer = new StopwatchTimer(Uid.this, VIDEO_TURNED_ON,
Dianne Hackborn10eaa852014-07-22 22:54:55 -07005439 mVideoTurnedOnTimers, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005440 } else {
5441 mVideoTurnedOnTimer = null;
5442 }
5443 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005444 mForegroundActivityTimer = new StopwatchTimer(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005445 Uid.this, FOREGROUND_ACTIVITY, null, mOnBatteryTimeBase, in);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005446 } else {
5447 mForegroundActivityTimer = null;
5448 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07005449 mProcessState = PROCESS_STATE_NONE;
5450 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
5451 if (in.readInt() != 0) {
5452 makeProcessState(i, in);
5453 } else {
5454 mProcessStateTimer[i] = null;
5455 }
5456 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005457 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005458 mVibratorOnTimer = new BatchTimer(Uid.this, VIBRATOR_ON, mOnBatteryTimeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005459 } else {
5460 mVibratorOnTimer = null;
5461 }
5462 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07005463 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
5464 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005465 mUserActivityCounters[i] = new Counter(mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005466 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005467 } else {
5468 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07005469 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005470 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005471 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
5472 mNetworkPacketActivityCounters
5473 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005474 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005475 mNetworkByteActivityCounters[i]
5476 = new LongSamplingCounter(mOnBatteryTimeBase, in);
5477 mNetworkPacketActivityCounters[i]
5478 = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005479 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005480 mMobileRadioActiveTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
5481 mMobileRadioActiveCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005482 } else {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005483 mNetworkByteActivityCounters = null;
5484 mNetworkPacketActivityCounters = null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005485 }
Adam Lesinskie08af192015-03-25 16:42:59 -07005486
5487 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5488 if (in.readInt() != 0) {
5489 mWifiControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
5490 } else {
5491 mWifiControllerTime[i] = null;
5492 }
5493 }
5494
5495 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
5496 if (in.readInt() != 0) {
5497 mBluetoothControllerTime[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
5498 } else {
5499 mBluetoothControllerTime[i] = null;
5500 }
5501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005502 }
5503
5504 /**
5505 * The statistics associated with a particular wake lock.
5506 */
5507 public final class Wakelock extends BatteryStats.Uid.Wakelock {
5508 /**
5509 * How long (in ms) this uid has been keeping the device partially awake.
5510 */
Evan Millarc64edde2009-04-18 12:26:32 -07005511 StopwatchTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005512
5513 /**
5514 * How long (in ms) this uid has been keeping the device fully awake.
5515 */
Evan Millarc64edde2009-04-18 12:26:32 -07005516 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005517
5518 /**
5519 * How long (in ms) this uid has had a window keeping the device awake.
5520 */
Evan Millarc64edde2009-04-18 12:26:32 -07005521 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005522
5523 /**
5524 * Reads a possibly null Timer from a Parcel. The timer is associated with the
5525 * proper timer pool from the given BatteryStatsImpl object.
5526 *
5527 * @param in the Parcel to be read from.
5528 * return a new Timer, or null.
5529 */
Evan Millarc64edde2009-04-18 12:26:32 -07005530 private StopwatchTimer readTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005531 TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005532 if (in.readInt() == 0) {
5533 return null;
5534 }
5535
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005536 return new StopwatchTimer(Uid.this, type, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005537 }
5538
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005539 boolean reset() {
5540 boolean wlactive = false;
5541 if (mTimerFull != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005542 wlactive |= !mTimerFull.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005543 }
5544 if (mTimerPartial != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005545 wlactive |= !mTimerPartial.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005546 }
5547 if (mTimerWindow != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005548 wlactive |= !mTimerWindow.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005549 }
5550 if (!wlactive) {
5551 if (mTimerFull != null) {
5552 mTimerFull.detach();
5553 mTimerFull = null;
5554 }
5555 if (mTimerPartial != null) {
5556 mTimerPartial.detach();
5557 mTimerPartial = null;
5558 }
5559 if (mTimerWindow != null) {
5560 mTimerWindow.detach();
5561 mTimerWindow = null;
5562 }
5563 }
5564 return !wlactive;
5565 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005566
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005567 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005568 mTimerPartial = readTimerFromParcel(WAKE_TYPE_PARTIAL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005569 mPartialTimers, screenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005570 mTimerFull = readTimerFromParcel(WAKE_TYPE_FULL,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005571 mFullTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005572 mTimerWindow = readTimerFromParcel(WAKE_TYPE_WINDOW,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005573 mWindowTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005574 }
5575
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005576 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
5577 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
5578 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
5579 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005580 }
5581
5582 @Override
5583 public Timer getWakeTime(int type) {
5584 switch (type) {
5585 case WAKE_TYPE_FULL: return mTimerFull;
5586 case WAKE_TYPE_PARTIAL: return mTimerPartial;
5587 case WAKE_TYPE_WINDOW: return mTimerWindow;
5588 default: throw new IllegalArgumentException("type = " + type);
5589 }
5590 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07005591
5592 public StopwatchTimer getStopwatchTimer(int type) {
5593 StopwatchTimer t;
5594 switch (type) {
5595 case WAKE_TYPE_PARTIAL:
5596 t = mTimerPartial;
5597 if (t == null) {
5598 t = new StopwatchTimer(Uid.this, WAKE_TYPE_PARTIAL,
5599 mPartialTimers, mOnBatteryScreenOffTimeBase);
5600 mTimerPartial = t;
5601 }
5602 return t;
5603 case WAKE_TYPE_FULL:
5604 t = mTimerFull;
5605 if (t == null) {
5606 t = new StopwatchTimer(Uid.this, WAKE_TYPE_FULL,
5607 mFullTimers, mOnBatteryTimeBase);
5608 mTimerFull = t;
5609 }
5610 return t;
5611 case WAKE_TYPE_WINDOW:
5612 t = mTimerWindow;
5613 if (t == null) {
5614 t = new StopwatchTimer(Uid.this, WAKE_TYPE_WINDOW,
5615 mWindowTimers, mOnBatteryTimeBase);
5616 mTimerWindow = t;
5617 }
5618 return t;
5619 default:
5620 throw new IllegalArgumentException("type=" + type);
5621 }
5622 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005623 }
5624
5625 public final class Sensor extends BatteryStats.Uid.Sensor {
5626 final int mHandle;
Evan Millarc64edde2009-04-18 12:26:32 -07005627 StopwatchTimer mTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005628
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005629 public Sensor(int handle) {
5630 mHandle = handle;
5631 }
5632
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005633 private StopwatchTimer readTimerFromParcel(TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005634 if (in.readInt() == 0) {
5635 return null;
5636 }
5637
Evan Millarc64edde2009-04-18 12:26:32 -07005638 ArrayList<StopwatchTimer> pool = mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005639 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07005640 pool = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005641 mSensorTimers.put(mHandle, pool);
5642 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005643 return new StopwatchTimer(Uid.this, 0, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005644 }
5645
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005646 boolean reset() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005647 if (mTimer.reset(true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005648 mTimer = null;
5649 return true;
5650 }
5651 return false;
5652 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005653
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005654 void readFromParcelLocked(TimeBase timeBase, Parcel in) {
5655 mTimer = readTimerFromParcel(timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005656 }
5657
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005658 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
5659 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005660 }
5661
5662 @Override
5663 public Timer getSensorTime() {
5664 return mTimer;
5665 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005666
5667 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005668 public int getHandle() {
5669 return mHandle;
5670 }
5671 }
5672
5673 /**
5674 * The statistics associated with a particular process.
5675 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005676 public final class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005677 /**
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005678 * The name of this process.
5679 */
5680 final String mName;
5681
5682 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -08005683 * Remains true until removed from the stats.
5684 */
5685 boolean mActive = true;
5686
5687 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005688 * Total time (in ms) spent executing in user code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005689 */
5690 long mUserTime;
5691
5692 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005693 * Total time (in ms) spent executing in kernel code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005694 */
5695 long mSystemTime;
5696
5697 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07005698 * Amount of time (in ms) the process was running in the foreground.
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005699 */
5700 long mForegroundTime;
5701
5702 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005703 * Number of times the process has been started.
5704 */
5705 int mStarts;
5706
5707 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005708 * Number of times the process has crashed.
5709 */
5710 int mNumCrashes;
5711
5712 /**
5713 * Number of times the process has had an ANR.
5714 */
5715 int mNumAnrs;
5716
5717 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005718 * The amount of user time loaded from a previous save.
5719 */
5720 long mLoadedUserTime;
5721
5722 /**
5723 * The amount of system time loaded from a previous save.
5724 */
5725 long mLoadedSystemTime;
5726
5727 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005728 * The amount of foreground time loaded from a previous save.
5729 */
5730 long mLoadedForegroundTime;
5731
5732 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005733 * The number of times the process has started from a previous save.
5734 */
5735 int mLoadedStarts;
5736
5737 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005738 * Number of times the process has crashed from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005739 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005740 int mLoadedNumCrashes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005741
5742 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005743 * Number of times the process has had an ANR from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005744 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005745 int mLoadedNumAnrs;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005746
5747 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005748 * The amount of user time when last unplugged.
5749 */
5750 long mUnpluggedUserTime;
5751
5752 /**
5753 * The amount of system time when last unplugged.
5754 */
5755 long mUnpluggedSystemTime;
5756
5757 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005758 * The amount of foreground time since unplugged.
5759 */
5760 long mUnpluggedForegroundTime;
5761
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005762 /**
5763 * The number of times the process has started before unplugged.
5764 */
5765 int mUnpluggedStarts;
5766
Dianne Hackborn61659e52014-07-09 16:13:01 -07005767 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005768 * Number of times the process has crashed before unplugged.
5769 */
5770 int mUnpluggedNumCrashes;
5771
5772 /**
5773 * Number of times the process has had an ANR before unplugged.
5774 */
5775 int mUnpluggedNumAnrs;
5776
5777 /**
Dianne Hackborn61659e52014-07-09 16:13:01 -07005778 * Current process state.
5779 */
5780 int mProcessState = PROCESS_STATE_NONE;
5781
Amith Yamasanie43530a2009-08-21 13:11:37 -07005782 SamplingCounter[] mSpeedBins;
5783
Dianne Hackborn287952c2010-09-22 22:34:31 -07005784 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005785
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005786 Proc(String name) {
5787 mName = name;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005788 mOnBatteryTimeBase.add(this);
Amith Yamasanie43530a2009-08-21 13:11:37 -07005789 mSpeedBins = new SamplingCounter[getCpuSpeedSteps()];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005790 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005791
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005792 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005793 mUnpluggedUserTime = mUserTime;
5794 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005795 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005796 mUnpluggedStarts = mStarts;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005797 mUnpluggedNumCrashes = mNumCrashes;
5798 mUnpluggedNumAnrs = mNumAnrs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005799 }
5800
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005801 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005802 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005803
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005804 void reset() {
5805 mUserTime = mSystemTime = mForegroundTime = 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005806 mStarts = mNumCrashes = mNumAnrs = 0;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005807 mLoadedUserTime = mLoadedSystemTime = mLoadedForegroundTime = 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005808 mLoadedStarts = mLoadedNumCrashes = mLoadedNumAnrs = 0;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005809 mUnpluggedUserTime = mUnpluggedSystemTime = mUnpluggedForegroundTime = 0;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005810 mUnpluggedStarts = mUnpluggedNumCrashes = mUnpluggedNumAnrs = 0;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005811 for (int i = 0; i < mSpeedBins.length; i++) {
5812 SamplingCounter c = mSpeedBins[i];
5813 if (c != null) {
5814 c.reset(false);
5815 }
5816 }
5817 mExcessivePower = null;
5818 }
5819
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005820 void detach() {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005821 mActive = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005822 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005823 for (int i = 0; i < mSpeedBins.length; i++) {
5824 SamplingCounter c = mSpeedBins[i];
5825 if (c != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005826 mOnBatteryTimeBase.remove(c);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005827 mSpeedBins[i] = null;
5828 }
5829 }
5830 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005831
Dianne Hackborn287952c2010-09-22 22:34:31 -07005832 public int countExcessivePowers() {
5833 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005834 }
5835
Dianne Hackborn287952c2010-09-22 22:34:31 -07005836 public ExcessivePower getExcessivePower(int i) {
5837 if (mExcessivePower != null) {
5838 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005839 }
5840 return null;
5841 }
5842
5843 public void addExcessiveWake(long overTime, long usedTime) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005844 if (mExcessivePower == null) {
5845 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005846 }
Dianne Hackborn287952c2010-09-22 22:34:31 -07005847 ExcessivePower ew = new ExcessivePower();
5848 ew.type = ExcessivePower.TYPE_WAKE;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005849 ew.overTime = overTime;
5850 ew.usedTime = usedTime;
Dianne Hackborn287952c2010-09-22 22:34:31 -07005851 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005852 }
5853
Dianne Hackborn287952c2010-09-22 22:34:31 -07005854 public void addExcessiveCpu(long overTime, long usedTime) {
5855 if (mExcessivePower == null) {
5856 mExcessivePower = new ArrayList<ExcessivePower>();
5857 }
5858 ExcessivePower ew = new ExcessivePower();
5859 ew.type = ExcessivePower.TYPE_CPU;
5860 ew.overTime = overTime;
5861 ew.usedTime = usedTime;
5862 mExcessivePower.add(ew);
5863 }
5864
5865 void writeExcessivePowerToParcelLocked(Parcel out) {
5866 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005867 out.writeInt(0);
5868 return;
5869 }
5870
Dianne Hackborn287952c2010-09-22 22:34:31 -07005871 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005872 out.writeInt(N);
5873 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005874 ExcessivePower ew = mExcessivePower.get(i);
5875 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005876 out.writeLong(ew.overTime);
5877 out.writeLong(ew.usedTime);
5878 }
5879 }
5880
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005881 boolean readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005882 final int N = in.readInt();
5883 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005884 mExcessivePower = null;
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005885 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005886 }
5887
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005888 if (N > 10000) {
5889 Slog.w(TAG, "File corrupt: too many excessive power entries " + N);
5890 return false;
5891 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07005892
Dianne Hackborn287952c2010-09-22 22:34:31 -07005893 mExcessivePower = new ArrayList<ExcessivePower>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005894 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07005895 ExcessivePower ew = new ExcessivePower();
5896 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005897 ew.overTime = in.readLong();
5898 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07005899 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005900 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08005901 return true;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005902 }
5903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005904 void writeToParcelLocked(Parcel out) {
5905 out.writeLong(mUserTime);
5906 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005907 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005908 out.writeInt(mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005909 out.writeInt(mNumCrashes);
5910 out.writeInt(mNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005911 out.writeLong(mLoadedUserTime);
5912 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005913 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005914 out.writeInt(mLoadedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005915 out.writeInt(mLoadedNumCrashes);
5916 out.writeInt(mLoadedNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005917 out.writeLong(mUnpluggedUserTime);
5918 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005919 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005920 out.writeInt(mUnpluggedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005921 out.writeInt(mUnpluggedNumCrashes);
5922 out.writeInt(mUnpluggedNumAnrs);
Amith Yamasanie43530a2009-08-21 13:11:37 -07005923
5924 out.writeInt(mSpeedBins.length);
5925 for (int i = 0; i < mSpeedBins.length; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005926 SamplingCounter c = mSpeedBins[i];
5927 if (c != null) {
5928 out.writeInt(1);
5929 c.writeToParcel(out);
5930 } else {
5931 out.writeInt(0);
5932 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005933 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005934
Dianne Hackborn287952c2010-09-22 22:34:31 -07005935 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005936 }
5937
5938 void readFromParcelLocked(Parcel in) {
5939 mUserTime = in.readLong();
5940 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005941 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005942 mStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005943 mNumCrashes = in.readInt();
5944 mNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005945 mLoadedUserTime = in.readLong();
5946 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005947 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005948 mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005949 mLoadedNumCrashes = in.readInt();
5950 mLoadedNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005951 mUnpluggedUserTime = in.readLong();
5952 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005953 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005954 mUnpluggedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005955 mUnpluggedNumCrashes = in.readInt();
5956 mUnpluggedNumAnrs = in.readInt();
Amith Yamasanie43530a2009-08-21 13:11:37 -07005957
5958 int bins = in.readInt();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005959 int steps = getCpuSpeedSteps();
5960 mSpeedBins = new SamplingCounter[bins >= steps ? bins : steps];
Amith Yamasanie43530a2009-08-21 13:11:37 -07005961 for (int i = 0; i < bins; i++) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005962 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005963 mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005964 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07005965 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005966
Dianne Hackborn287952c2010-09-22 22:34:31 -07005967 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005968 }
5969
5970 public BatteryStatsImpl getBatteryStats() {
5971 return BatteryStatsImpl.this;
5972 }
5973
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005974 public void addCpuTimeLocked(int utime, int stime, long[] speedStepBins) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005975 mUserTime += utime;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005976 mCurStepUserTime += utime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005977 mSystemTime += stime;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005978 mCurStepSystemTime += stime;
5979
5980 for (int i = 0; i < mSpeedBins.length && i < speedStepBins.length; i++) {
5981 long amt = speedStepBins[i];
5982 if (amt != 0) {
5983 SamplingCounter c = mSpeedBins[i];
5984 if (c == null) {
5985 mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase);
5986 }
5987 c.addCountAtomic(speedStepBins[i]);
5988 }
5989 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005990 }
5991
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005992 public void addForegroundTimeLocked(long ttime) {
5993 mForegroundTime += ttime;
5994 }
5995
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005996 public void incStartsLocked() {
5997 mStarts++;
5998 }
5999
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006000 public void incNumCrashesLocked() {
6001 mNumCrashes++;
6002 }
6003
6004 public void incNumAnrsLocked() {
6005 mNumAnrs++;
6006 }
6007
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006008 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08006009 public boolean isActive() {
6010 return mActive;
6011 }
6012
6013 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006014 public long getUserTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006015 long val = mUserTime;
6016 if (which == STATS_CURRENT) {
6017 val -= mLoadedUserTime;
6018 } else if (which == STATS_SINCE_UNPLUGGED) {
6019 val -= mUnpluggedUserTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006020 }
6021 return val;
6022 }
6023
6024 @Override
6025 public long getSystemTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006026 long val = mSystemTime;
6027 if (which == STATS_CURRENT) {
6028 val -= mLoadedSystemTime;
6029 } else if (which == STATS_SINCE_UNPLUGGED) {
6030 val -= mUnpluggedSystemTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006031 }
6032 return val;
6033 }
6034
6035 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006036 public long getForegroundTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006037 long val = mForegroundTime;
6038 if (which == STATS_CURRENT) {
6039 val -= mLoadedForegroundTime;
6040 } else if (which == STATS_SINCE_UNPLUGGED) {
6041 val -= mUnpluggedForegroundTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006042 }
6043 return val;
6044 }
6045
6046 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006047 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006048 int val = mStarts;
6049 if (which == STATS_CURRENT) {
6050 val -= mLoadedStarts;
6051 } else if (which == STATS_SINCE_UNPLUGGED) {
6052 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006053 }
6054 return val;
6055 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07006056
Dianne Hackborn1e01d162014-12-04 17:46:42 -08006057 @Override
6058 public int getNumCrashes(int which) {
6059 int val = mNumCrashes;
6060 if (which == STATS_CURRENT) {
6061 val -= mLoadedNumCrashes;
6062 } else if (which == STATS_SINCE_UNPLUGGED) {
6063 val -= mUnpluggedNumCrashes;
6064 }
6065 return val;
6066 }
6067
6068 @Override
6069 public int getNumAnrs(int which) {
6070 int val = mNumAnrs;
6071 if (which == STATS_CURRENT) {
6072 val -= mLoadedNumAnrs;
6073 } else if (which == STATS_SINCE_UNPLUGGED) {
6074 val -= mUnpluggedNumAnrs;
6075 }
6076 return val;
6077 }
6078
Amith Yamasanie43530a2009-08-21 13:11:37 -07006079 @Override
6080 public long getTimeAtCpuSpeedStep(int speedStep, int which) {
6081 if (speedStep < mSpeedBins.length) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006082 SamplingCounter c = mSpeedBins[speedStep];
6083 return c != null ? c.getCountLocked(which) : 0;
Amith Yamasanie43530a2009-08-21 13:11:37 -07006084 } else {
6085 return 0;
6086 }
6087 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006088 }
6089
6090 /**
6091 * The statistics associated with a particular package.
6092 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006093 public final class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006094 /**
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006095 * Number of times wakeup alarms have occurred for this app.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006096 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006097 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006098
6099 /**
6100 * The statics we have collected for this package's services.
6101 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006102 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006103
6104 Pkg() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006105 mOnBatteryScreenOffTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006106 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006107
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006108 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006109 }
6110
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006111 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006112 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006113
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006114 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006115 mOnBatteryScreenOffTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006116 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006118 void readFromParcelLocked(Parcel in) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006119 int numWA = in.readInt();
6120 mWakeupAlarms.clear();
6121 for (int i=0; i<numWA; i++) {
6122 String tag = in.readString();
6123 mWakeupAlarms.put(tag, new Counter(mOnBatteryTimeBase, in));
6124 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006125
6126 int numServs = in.readInt();
6127 mServiceStats.clear();
6128 for (int m = 0; m < numServs; m++) {
6129 String serviceName = in.readString();
6130 Uid.Pkg.Serv serv = new Serv();
6131 mServiceStats.put(serviceName, serv);
6132
6133 serv.readFromParcelLocked(in);
6134 }
6135 }
6136
6137 void writeToParcelLocked(Parcel out) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006138 int numWA = mWakeupAlarms.size();
6139 out.writeInt(numWA);
6140 for (int i=0; i<numWA; i++) {
6141 out.writeString(mWakeupAlarms.keyAt(i));
6142 mWakeupAlarms.valueAt(i).writeToParcel(out);
6143 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006144
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006145 final int NS = mServiceStats.size();
6146 out.writeInt(NS);
6147 for (int i=0; i<NS; i++) {
6148 out.writeString(mServiceStats.keyAt(i));
6149 Uid.Pkg.Serv serv = mServiceStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006150 serv.writeToParcelLocked(out);
6151 }
6152 }
6153
6154 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006155 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() {
6156 return mWakeupAlarms;
6157 }
6158
6159 public void noteWakeupAlarmLocked(String tag) {
6160 Counter c = mWakeupAlarms.get(tag);
6161 if (c == null) {
6162 c = new Counter(mOnBatteryTimeBase);
6163 mWakeupAlarms.put(tag, c);
6164 }
6165 c.stepAtomic();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006166 }
6167
6168 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006169 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
6170 return mServiceStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006171 }
6172
6173 /**
6174 * The statistics associated with a particular service.
6175 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006176 public final class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006177 /**
6178 * Total time (ms in battery uptime) the service has been left started.
6179 */
6180 long mStartTime;
6181
6182 /**
6183 * If service has been started and not yet stopped, this is
6184 * when it was started.
6185 */
6186 long mRunningSince;
6187
6188 /**
6189 * True if we are currently running.
6190 */
6191 boolean mRunning;
6192
6193 /**
6194 * Total number of times startService() has been called.
6195 */
6196 int mStarts;
6197
6198 /**
6199 * Total time (ms in battery uptime) the service has been left launched.
6200 */
6201 long mLaunchedTime;
6202
6203 /**
6204 * If service has been launched and not yet exited, this is
6205 * when it was launched (ms in battery uptime).
6206 */
6207 long mLaunchedSince;
6208
6209 /**
6210 * True if we are currently launched.
6211 */
6212 boolean mLaunched;
6213
6214 /**
6215 * Total number times the service has been launched.
6216 */
6217 int mLaunches;
6218
6219 /**
6220 * The amount of time spent started loaded from a previous save
6221 * (ms in battery uptime).
6222 */
6223 long mLoadedStartTime;
6224
6225 /**
6226 * The number of starts loaded from a previous save.
6227 */
6228 int mLoadedStarts;
6229
6230 /**
6231 * The number of launches loaded from a previous save.
6232 */
6233 int mLoadedLaunches;
6234
6235 /**
6236 * The amount of time spent started as of the last run (ms
6237 * in battery uptime).
6238 */
6239 long mLastStartTime;
6240
6241 /**
6242 * The number of starts as of the last run.
6243 */
6244 int mLastStarts;
6245
6246 /**
6247 * The number of launches as of the last run.
6248 */
6249 int mLastLaunches;
6250
6251 /**
6252 * The amount of time spent started when last unplugged (ms
6253 * in battery uptime).
6254 */
6255 long mUnpluggedStartTime;
6256
6257 /**
6258 * The number of starts when last unplugged.
6259 */
6260 int mUnpluggedStarts;
6261
6262 /**
6263 * The number of launches when last unplugged.
6264 */
6265 int mUnpluggedLaunches;
6266
6267 Serv() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006268 mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006269 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006270
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006271 public void onTimeStarted(long elapsedRealtime, long baseUptime,
6272 long baseRealtime) {
6273 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006274 mUnpluggedStarts = mStarts;
6275 mUnpluggedLaunches = mLaunches;
6276 }
6277
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006278 public void onTimeStopped(long elapsedRealtime, long baseUptime,
6279 long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006280 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006281
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006282 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006283 mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006284 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006285
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006286 void readFromParcelLocked(Parcel in) {
6287 mStartTime = in.readLong();
6288 mRunningSince = in.readLong();
6289 mRunning = in.readInt() != 0;
6290 mStarts = in.readInt();
6291 mLaunchedTime = in.readLong();
6292 mLaunchedSince = in.readLong();
6293 mLaunched = in.readInt() != 0;
6294 mLaunches = in.readInt();
6295 mLoadedStartTime = in.readLong();
6296 mLoadedStarts = in.readInt();
6297 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07006298 mLastStartTime = 0;
6299 mLastStarts = 0;
6300 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006301 mUnpluggedStartTime = in.readLong();
6302 mUnpluggedStarts = in.readInt();
6303 mUnpluggedLaunches = in.readInt();
6304 }
6305
6306 void writeToParcelLocked(Parcel out) {
6307 out.writeLong(mStartTime);
6308 out.writeLong(mRunningSince);
6309 out.writeInt(mRunning ? 1 : 0);
6310 out.writeInt(mStarts);
6311 out.writeLong(mLaunchedTime);
6312 out.writeLong(mLaunchedSince);
6313 out.writeInt(mLaunched ? 1 : 0);
6314 out.writeInt(mLaunches);
6315 out.writeLong(mLoadedStartTime);
6316 out.writeInt(mLoadedStarts);
6317 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006318 out.writeLong(mUnpluggedStartTime);
6319 out.writeInt(mUnpluggedStarts);
6320 out.writeInt(mUnpluggedLaunches);
6321 }
6322
6323 long getLaunchTimeToNowLocked(long batteryUptime) {
6324 if (!mLaunched) return mLaunchedTime;
6325 return mLaunchedTime + batteryUptime - mLaunchedSince;
6326 }
6327
6328 long getStartTimeToNowLocked(long batteryUptime) {
6329 if (!mRunning) return mStartTime;
6330 return mStartTime + batteryUptime - mRunningSince;
6331 }
6332
6333 public void startLaunchedLocked() {
6334 if (!mLaunched) {
6335 mLaunches++;
6336 mLaunchedSince = getBatteryUptimeLocked();
6337 mLaunched = true;
6338 }
6339 }
6340
6341 public void stopLaunchedLocked() {
6342 if (mLaunched) {
6343 long time = getBatteryUptimeLocked() - mLaunchedSince;
6344 if (time > 0) {
6345 mLaunchedTime += time;
6346 } else {
6347 mLaunches--;
6348 }
6349 mLaunched = false;
6350 }
6351 }
6352
6353 public void startRunningLocked() {
6354 if (!mRunning) {
6355 mStarts++;
6356 mRunningSince = getBatteryUptimeLocked();
6357 mRunning = true;
6358 }
6359 }
6360
6361 public void stopRunningLocked() {
6362 if (mRunning) {
6363 long time = getBatteryUptimeLocked() - mRunningSince;
6364 if (time > 0) {
6365 mStartTime += time;
6366 } else {
6367 mStarts--;
6368 }
6369 mRunning = false;
6370 }
6371 }
6372
6373 public BatteryStatsImpl getBatteryStats() {
6374 return BatteryStatsImpl.this;
6375 }
6376
6377 @Override
6378 public int getLaunches(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006379 int val = mLaunches;
6380 if (which == STATS_CURRENT) {
6381 val -= mLoadedLaunches;
6382 } else if (which == STATS_SINCE_UNPLUGGED) {
6383 val -= mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006385 return val;
6386 }
6387
6388 @Override
6389 public long getStartTime(long now, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006390 long val = getStartTimeToNowLocked(now);
6391 if (which == STATS_CURRENT) {
6392 val -= mLoadedStartTime;
6393 } else if (which == STATS_SINCE_UNPLUGGED) {
6394 val -= mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006395 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006396 return val;
6397 }
6398
6399 @Override
6400 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07006401 int val = mStarts;
6402 if (which == STATS_CURRENT) {
6403 val -= mLoadedStarts;
6404 } else if (which == STATS_SINCE_UNPLUGGED) {
6405 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006406 }
6407
6408 return val;
6409 }
6410 }
6411
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006412 final Serv newServiceStatsLocked() {
6413 return new Serv();
6414 }
6415 }
6416
6417 /**
6418 * Retrieve the statistics object for a particular process, creating
6419 * if needed.
6420 */
6421 public Proc getProcessStatsLocked(String name) {
6422 Proc ps = mProcessStats.get(name);
6423 if (ps == null) {
Dianne Hackborncd0e3352014-08-07 17:08:09 -07006424 ps = new Proc(name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006425 mProcessStats.put(name, ps);
6426 }
6427
6428 return ps;
6429 }
6430
Dianne Hackborn61659e52014-07-09 16:13:01 -07006431 public void updateProcessStateLocked(String procName, int state, long elapsedRealtimeMs) {
6432 int procState;
6433 if (state <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
6434 procState = PROCESS_STATE_FOREGROUND;
6435 } else if (state <= ActivityManager.PROCESS_STATE_RECEIVER) {
6436 procState = PROCESS_STATE_ACTIVE;
6437 } else {
6438 procState = PROCESS_STATE_RUNNING;
6439 }
6440 updateRealProcessStateLocked(procName, procState, elapsedRealtimeMs);
6441 }
6442
6443 public void updateRealProcessStateLocked(String procName, int procState,
6444 long elapsedRealtimeMs) {
6445 Proc proc = getProcessStatsLocked(procName);
6446 if (proc.mProcessState != procState) {
6447 boolean changed;
6448 if (procState < proc.mProcessState) {
6449 // Has this process become more important? If so,
6450 // we may need to change the uid if the currrent uid proc state
6451 // is not as important as what we are now setting.
6452 changed = mProcessState > procState;
6453 } else {
6454 // Has this process become less important? If so,
6455 // we may need to change the uid if the current uid proc state
6456 // is the same importance as the old setting.
6457 changed = mProcessState == proc.mProcessState;
6458 }
6459 proc.mProcessState = procState;
6460 if (changed) {
6461 // uid's state may have changed; compute what the new state should be.
6462 int uidProcState = PROCESS_STATE_NONE;
6463 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
6464 proc = mProcessStats.valueAt(ip);
6465 if (proc.mProcessState < uidProcState) {
6466 uidProcState = proc.mProcessState;
6467 }
6468 }
6469 updateUidProcessStateLocked(uidProcState, elapsedRealtimeMs);
6470 }
6471 }
6472 }
6473
Dianne Hackbornb5e31652010-09-07 12:13:55 -07006474 public SparseArray<? extends Pid> getPidStats() {
6475 return mPids;
6476 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006477
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006478 public Pid getPidStatsLocked(int pid) {
6479 Pid p = mPids.get(pid);
6480 if (p == null) {
6481 p = new Pid();
6482 mPids.put(pid, p);
6483 }
6484 return p;
6485 }
6486
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006487 /**
6488 * Retrieve the statistics object for a particular service, creating
6489 * if needed.
6490 */
6491 public Pkg getPackageStatsLocked(String name) {
6492 Pkg ps = mPackageStats.get(name);
6493 if (ps == null) {
6494 ps = new Pkg();
6495 mPackageStats.put(name, ps);
6496 }
6497
6498 return ps;
6499 }
6500
6501 /**
6502 * Retrieve the statistics object for a particular service, creating
6503 * if needed.
6504 */
6505 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
6506 Pkg ps = getPackageStatsLocked(pkg);
6507 Pkg.Serv ss = ps.mServiceStats.get(serv);
6508 if (ss == null) {
6509 ss = ps.newServiceStatsLocked();
6510 ps.mServiceStats.put(serv, ss);
6511 }
6512
6513 return ss;
6514 }
6515
Dianne Hackbornd953c532014-08-16 18:17:38 -07006516 public void readSyncSummaryFromParcelLocked(String name, Parcel in) {
6517 StopwatchTimer timer = mSyncStats.instantiateObject();
6518 timer.readSummaryFromParcelLocked(in);
6519 mSyncStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006520 }
6521
Dianne Hackbornd953c532014-08-16 18:17:38 -07006522 public void readJobSummaryFromParcelLocked(String name, Parcel in) {
6523 StopwatchTimer timer = mJobStats.instantiateObject();
6524 timer.readSummaryFromParcelLocked(in);
6525 mJobStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006526 }
6527
Dianne Hackbornd953c532014-08-16 18:17:38 -07006528 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) {
6529 Wakelock wl = new Wakelock();
6530 mWakelockStats.add(wlName, wl);
6531 if (in.readInt() != 0) {
6532 wl.getStopwatchTimer(WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006533 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006534 if (in.readInt() != 0) {
6535 wl.getStopwatchTimer(WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
6536 }
6537 if (in.readInt() != 0) {
6538 wl.getStopwatchTimer(WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006539 }
6540 }
6541
Evan Millarc64edde2009-04-18 12:26:32 -07006542 public StopwatchTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006543 Sensor se = mSensorStats.get(sensor);
6544 if (se == null) {
6545 if (!create) {
6546 return null;
6547 }
6548 se = new Sensor(sensor);
6549 mSensorStats.put(sensor, se);
6550 }
Evan Millarc64edde2009-04-18 12:26:32 -07006551 StopwatchTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006552 if (t != null) {
6553 return t;
6554 }
Evan Millarc64edde2009-04-18 12:26:32 -07006555 ArrayList<StopwatchTimer> timers = mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006556 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07006557 timers = new ArrayList<StopwatchTimer>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006558 mSensorTimers.put(sensor, timers);
6559 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006560 t = new StopwatchTimer(Uid.this, BatteryStats.SENSOR, timers, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006561 se.mTimer = t;
6562 return t;
6563 }
6564
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006565 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006566 StopwatchTimer t = mSyncStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006567 if (t != null) {
6568 t.startRunningLocked(elapsedRealtimeMs);
6569 }
6570 }
6571
6572 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006573 StopwatchTimer t = mSyncStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006574 if (t != null) {
6575 t.stopRunningLocked(elapsedRealtimeMs);
6576 }
6577 }
6578
6579 public void noteStartJobLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07006580 StopwatchTimer t = mJobStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006581 if (t != null) {
6582 t.startRunningLocked(elapsedRealtimeMs);
6583 }
6584 }
6585
6586 public void noteStopJobLocked(String name, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006587 StopwatchTimer t = mJobStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006588 if (t != null) {
6589 t.stopRunningLocked(elapsedRealtimeMs);
6590 }
6591 }
6592
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006593 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006594 Wakelock wl = mWakelockStats.startObject(name);
6595 if (wl != null) {
6596 wl.getStopwatchTimer(type).startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006597 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07006598 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006599 Pid p = getPidStatsLocked(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006600 if (p.mWakeNesting++ == 0) {
6601 p.mWakeStartMs = elapsedRealtimeMs;
Dianne Hackbornb8071d792010-09-09 16:45:15 -07006602 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006603 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006604 }
6605
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006606 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006607 Wakelock wl = mWakelockStats.stopObject(name);
6608 if (wl != null) {
6609 wl.getStopwatchTimer(type).stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006610 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07006611 if (pid >= 0 && type == WAKE_TYPE_PARTIAL) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006612 Pid p = mPids.get(pid);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006613 if (p != null && p.mWakeNesting > 0) {
6614 if (p.mWakeNesting-- == 1) {
6615 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
6616 p.mWakeStartMs = 0;
6617 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006618 }
6619 }
6620 }
6621
6622 public void reportExcessiveWakeLocked(String proc, long overTime, long usedTime) {
6623 Proc p = getProcessStatsLocked(proc);
6624 if (p != null) {
6625 p.addExcessiveWake(overTime, usedTime);
6626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006627 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006628
Dianne Hackborn287952c2010-09-22 22:34:31 -07006629 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
6630 Proc p = getProcessStatsLocked(proc);
6631 if (p != null) {
6632 p.addExcessiveCpu(overTime, usedTime);
6633 }
6634 }
6635
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006636 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006637 StopwatchTimer t = getSensorTimerLocked(sensor, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006638 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006639 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006640 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006641 }
6642
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006643 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006644 // Don't create a timer if one doesn't already exist
Evan Millarc64edde2009-04-18 12:26:32 -07006645 StopwatchTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006646 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006647 t.stopRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006648 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006649 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006650
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006651 public void noteStartGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006652 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006653 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006654 t.startRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006655 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006656 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006657
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006658 public void noteStopGps(long elapsedRealtimeMs) {
Evan Millarc64edde2009-04-18 12:26:32 -07006659 StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006660 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006661 t.stopRunningLocked(elapsedRealtimeMs);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07006662 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006663 }
6664
6665 public BatteryStatsImpl getBatteryStats() {
6666 return BatteryStatsImpl.this;
6667 }
6668 }
6669
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006670 public BatteryStatsImpl(File systemDir, Handler handler, ExternalStatsSync externalSync) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07006671 if (systemDir != null) {
6672 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"),
6673 new File(systemDir, "batterystats.bin.tmp"));
6674 } else {
6675 mFile = null;
6676 }
6677 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006678 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006679 mExternalSync = externalSync;
Jeff Brown6f357d32014-01-15 20:40:55 -08006680 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006681 mStartCount++;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006682 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006683 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006684 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006685 }
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07006686 mInteractiveTimer = new StopwatchTimer(null, -10, null, mOnBatteryTimeBase);
6687 mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase);
6688 mDeviceIdleModeEnabledTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006689 mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006690 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase);
Wink Saville52840902011-02-18 12:40:47 -08006691 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006692 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i, null,
6693 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006694 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006695 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006696 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006697 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i, null,
6698 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07006699 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006700 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006701 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6702 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006703 }
Adam Lesinski33dac552015-03-09 15:24:48 -07006704 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
6705 mBluetoothActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6706 mWifiActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
6707 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006708 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase);
6709 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07006710 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006711 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
6712 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006713 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase);
6714 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006715 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006716 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006717 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07006718 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
6719 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i, null, mOnBatteryTimeBase);
6720 }
6721 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
6722 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i, null,
6723 mOnBatteryTimeBase);
6724 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006725 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08006726 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006727 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i, null, mOnBatteryTimeBase);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08006728 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07006729 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
6730 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07006731 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006732 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006733 long uptime = SystemClock.uptimeMillis() * 1000;
6734 long realtime = SystemClock.elapsedRealtime() * 1000;
6735 initTimes(uptime, realtime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07006736 mStartPlatformVersion = mEndPlatformVersion = Build.ID;
Evan Millar633a1742009-04-02 16:36:33 -07006737 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006738 mDischargeUnplugLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006739 mDischargePlugLevel = -1;
Evan Millar633a1742009-04-02 16:36:33 -07006740 mDischargeCurrentLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07006741 mCurrentBatteryLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08006742 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006743 clearHistoryLocked();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006744 updateDailyDeadlineLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006745 }
6746
6747 public BatteryStatsImpl(Parcel p) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07006748 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07006749 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006750 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07006751 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07006752 mExternalSync = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07006753 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006754 readFromParcel(p);
6755 }
6756
Adam Lesinskie08af192015-03-25 16:42:59 -07006757 public void setPowerProfile(PowerProfile profile) {
6758 synchronized (this) {
6759 mPowerProfile = profile;
6760 }
6761 }
6762
Dianne Hackborn0d903a82010-09-07 23:51:03 -07006763 public void setCallback(BatteryCallback cb) {
6764 mCallback = cb;
6765 }
6766
Amith Yamasanie43530a2009-08-21 13:11:37 -07006767 public void setNumSpeedSteps(int steps) {
6768 if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
6769 }
6770
Amith Yamasanif37447b2009-10-08 18:28:01 -07006771 public void setRadioScanningTimeout(long timeout) {
6772 if (mPhoneSignalScanningTimer != null) {
6773 mPhoneSignalScanningTimer.setTimeout(timeout);
6774 }
6775 }
6776
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006777 public void updateDailyDeadlineLocked() {
6778 // Get the current time.
6779 long currentTime = mDailyStartTime = System.currentTimeMillis();
6780 Calendar calDeadline = Calendar.getInstance();
6781 calDeadline.setTimeInMillis(currentTime);
6782
6783 // Move time up to the next day, ranging from 1am to 3pm.
6784 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1);
6785 calDeadline.set(Calendar.MILLISECOND, 0);
6786 calDeadline.set(Calendar.SECOND, 0);
6787 calDeadline.set(Calendar.MINUTE, 0);
6788 calDeadline.set(Calendar.HOUR_OF_DAY, 1);
6789 mNextMinDailyDeadline = calDeadline.getTimeInMillis();
6790 calDeadline.set(Calendar.HOUR_OF_DAY, 3);
6791 mNextMaxDailyDeadline = calDeadline.getTimeInMillis();
6792 }
6793
6794 public void recordDailyStatsIfNeededLocked(boolean settled) {
6795 long currentTime = System.currentTimeMillis();
6796 if (currentTime >= mNextMaxDailyDeadline) {
6797 recordDailyStatsLocked();
6798 } else if (settled && currentTime >= mNextMinDailyDeadline) {
6799 recordDailyStatsLocked();
6800 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) {
6801 recordDailyStatsLocked();
6802 }
6803 }
6804
6805 public void recordDailyStatsLocked() {
6806 DailyItem item = new DailyItem();
6807 item.mStartTime = mDailyStartTime;
6808 item.mEndTime = System.currentTimeMillis();
6809 boolean hasData = false;
6810 if (mDailyDischargeStepTracker.mNumStepDurations > 0) {
6811 hasData = true;
6812 item.mDischargeSteps = new LevelStepTracker(
6813 mDailyDischargeStepTracker.mNumStepDurations,
6814 mDailyDischargeStepTracker.mStepDurations);
6815 }
6816 if (mDailyChargeStepTracker.mNumStepDurations > 0) {
6817 hasData = true;
6818 item.mChargeSteps = new LevelStepTracker(
6819 mDailyChargeStepTracker.mNumStepDurations,
6820 mDailyChargeStepTracker.mStepDurations);
6821 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006822 if (mDailyPackageChanges != null) {
6823 hasData = true;
6824 item.mPackageChanges = mDailyPackageChanges;
6825 mDailyPackageChanges = null;
6826 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006827 mDailyDischargeStepTracker.init();
6828 mDailyChargeStepTracker.init();
6829 updateDailyDeadlineLocked();
6830
6831 if (hasData) {
6832 mDailyItems.add(item);
6833 while (mDailyItems.size() > MAX_DAILY_ITEMS) {
6834 mDailyItems.remove(0);
6835 }
6836 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
6837 try {
6838 XmlSerializer out = new FastXmlSerializer();
6839 out.setOutput(memStream, "utf-8");
6840 writeDailyItemsLocked(out);
6841 BackgroundThread.getHandler().post(new Runnable() {
6842 @Override
6843 public void run() {
6844 synchronized (mCheckinFile) {
6845 FileOutputStream stream = null;
6846 try {
6847 stream = mDailyFile.startWrite();
6848 memStream.writeTo(stream);
6849 stream.flush();
6850 FileUtils.sync(stream);
6851 stream.close();
6852 mDailyFile.finishWrite(stream);
6853 } catch (IOException e) {
6854 Slog.w("BatteryStats",
6855 "Error writing battery daily items", e);
6856 mDailyFile.failWrite(stream);
6857 }
6858 }
6859 }
6860 });
6861 } catch (IOException e) {
6862 }
6863 }
6864 }
6865
6866 private void writeDailyItemsLocked(XmlSerializer out) throws IOException {
6867 StringBuilder sb = new StringBuilder(64);
6868 out.startDocument(null, true);
6869 out.startTag(null, "daily-items");
6870 for (int i=0; i<mDailyItems.size(); i++) {
6871 final DailyItem dit = mDailyItems.get(i);
6872 out.startTag(null, "item");
6873 out.attribute(null, "start", Long.toString(dit.mStartTime));
6874 out.attribute(null, "end", Long.toString(dit.mEndTime));
6875 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb);
6876 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07006877 if (dit.mPackageChanges != null) {
6878 for (int j=0; j<dit.mPackageChanges.size(); j++) {
6879 PackageChange pc = dit.mPackageChanges.get(j);
6880 if (pc.mUpdate) {
6881 out.startTag(null, "upd");
6882 out.attribute(null, "pkg", pc.mPackageName);
6883 out.attribute(null, "ver", Integer.toString(pc.mVersionCode));
6884 out.endTag(null, "upd");
6885 } else {
6886 out.startTag(null, "rem");
6887 out.attribute(null, "pkg", pc.mPackageName);
6888 out.endTag(null, "rem");
6889 }
6890 }
6891 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08006892 out.endTag(null, "item");
6893 }
6894 out.endTag(null, "daily-items");
6895 out.endDocument();
6896 }
6897
6898 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps,
6899 StringBuilder tmpBuilder) throws IOException {
6900 if (steps != null) {
6901 out.startTag(null, tag);
6902 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations));
6903 for (int i=0; i<steps.mNumStepDurations; i++) {
6904 out.startTag(null, "s");
6905 tmpBuilder.setLength(0);
6906 steps.encodeEntryAt(i, tmpBuilder);
6907 out.attribute(null, "v", tmpBuilder.toString());
6908 out.endTag(null, "s");
6909 }
6910 out.endTag(null, tag);
6911 }
6912 }
6913
6914 public void readDailyStatsLocked() {
6915 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile());
6916 mDailyItems.clear();
6917 FileInputStream stream;
6918 try {
6919 stream = mDailyFile.openRead();
6920 } catch (FileNotFoundException e) {
6921 return;
6922 }
6923 try {
6924 XmlPullParser parser = Xml.newPullParser();
6925 parser.setInput(stream, null);
6926 readDailyItemsLocked(parser);
6927 } catch (XmlPullParserException e) {
6928 } finally {
6929 try {
6930 stream.close();
6931 } catch (IOException e) {
6932 }
6933 }
6934 }
6935
6936 private void readDailyItemsLocked(XmlPullParser parser) {
6937 try {
6938 int type;
6939 while ((type = parser.next()) != XmlPullParser.START_TAG
6940 && type != XmlPullParser.END_DOCUMENT) {
6941 ;
6942 }
6943
6944 if (type != XmlPullParser.START_TAG) {
6945 throw new IllegalStateException("no start tag found");
6946 }
6947
6948 int outerDepth = parser.getDepth();
6949 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
6950 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
6951 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
6952 continue;
6953 }
6954
6955 String tagName = parser.getName();
6956 if (tagName.equals("item")) {
6957 readDailyItemTagLocked(parser);
6958 } else {
6959 Slog.w(TAG, "Unknown element under <daily-items>: "
6960 + parser.getName());
6961 XmlUtils.skipCurrentTag(parser);
6962 }
6963 }
6964
6965 } catch (IllegalStateException e) {
6966 Slog.w(TAG, "Failed parsing daily " + e);
6967 } catch (NullPointerException e) {
6968 Slog.w(TAG, "Failed parsing daily " + e);
6969 } catch (NumberFormatException e) {
6970 Slog.w(TAG, "Failed parsing daily " + e);
6971 } catch (XmlPullParserException e) {
6972 Slog.w(TAG, "Failed parsing daily " + e);
6973 } catch (IOException e) {
6974 Slog.w(TAG, "Failed parsing daily " + e);
6975 } catch (IndexOutOfBoundsException e) {
6976 Slog.w(TAG, "Failed parsing daily " + e);
6977 }
6978 }
6979
6980 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException,
6981 XmlPullParserException, IOException {
6982 DailyItem dit = new DailyItem();
6983 String attr = parser.getAttributeValue(null, "start");
6984 if (attr != null) {
6985 dit.mStartTime = Long.parseLong(attr);
6986 }
6987 attr = parser.getAttributeValue(null, "end");
6988 if (attr != null) {
6989 dit.mEndTime = Long.parseLong(attr);
6990 }
6991 int outerDepth = parser.getDepth();
6992 int type;
6993 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
6994 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
6995 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
6996 continue;
6997 }
6998
6999 String tagName = parser.getName();
7000 if (tagName.equals("dis")) {
7001 readDailyItemTagDetailsLocked(parser, dit, false, "dis");
7002 } else if (tagName.equals("chg")) {
7003 readDailyItemTagDetailsLocked(parser, dit, true, "chg");
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007004 } else if (tagName.equals("upd")) {
7005 if (dit.mPackageChanges == null) {
7006 dit.mPackageChanges = new ArrayList<>();
7007 }
7008 PackageChange pc = new PackageChange();
7009 pc.mUpdate = true;
7010 pc.mPackageName = parser.getAttributeValue(null, "pkg");
7011 String verStr = parser.getAttributeValue(null, "ver");
7012 pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0;
7013 dit.mPackageChanges.add(pc);
7014 XmlUtils.skipCurrentTag(parser);
7015 } else if (tagName.equals("rem")) {
7016 if (dit.mPackageChanges == null) {
7017 dit.mPackageChanges = new ArrayList<>();
7018 }
7019 PackageChange pc = new PackageChange();
7020 pc.mUpdate = false;
7021 pc.mPackageName = parser.getAttributeValue(null, "pkg");
7022 dit.mPackageChanges.add(pc);
7023 XmlUtils.skipCurrentTag(parser);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007024 } else {
7025 Slog.w(TAG, "Unknown element under <item>: "
7026 + parser.getName());
7027 XmlUtils.skipCurrentTag(parser);
7028 }
7029 }
7030 mDailyItems.add(dit);
7031 }
7032
7033 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge,
7034 String tag)
7035 throws NumberFormatException, XmlPullParserException, IOException {
7036 final String numAttr = parser.getAttributeValue(null, "n");
7037 if (numAttr == null) {
7038 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription());
7039 XmlUtils.skipCurrentTag(parser);
7040 return;
7041 }
7042 final int num = Integer.parseInt(numAttr);
7043 LevelStepTracker steps = new LevelStepTracker(num);
7044 if (isCharge) {
7045 dit.mChargeSteps = steps;
7046 } else {
7047 dit.mDischargeSteps = steps;
7048 }
7049 int i = 0;
7050 int outerDepth = parser.getDepth();
7051 int type;
7052 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
7053 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
7054 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
7055 continue;
7056 }
7057
7058 String tagName = parser.getName();
7059 if ("s".equals(tagName)) {
7060 if (i < num) {
7061 String valueAttr = parser.getAttributeValue(null, "v");
7062 if (valueAttr != null) {
7063 steps.decodeEntryAt(i, valueAttr);
7064 i++;
7065 }
7066 }
7067 } else {
7068 Slog.w(TAG, "Unknown element under <" + tag + ">: "
7069 + parser.getName());
7070 XmlUtils.skipCurrentTag(parser);
7071 }
7072 }
7073 steps.mNumStepDurations = i;
7074 }
7075
7076 @Override
7077 public DailyItem getDailyItemLocked(int daysAgo) {
7078 int index = mDailyItems.size()-1-daysAgo;
7079 return index >= 0 ? mDailyItems.get(index) : null;
7080 }
7081
7082 @Override
7083 public long getCurrentDailyStartTime() {
7084 return mDailyStartTime;
7085 }
7086
7087 @Override
7088 public long getNextMinDailyDeadline() {
7089 return mNextMinDailyDeadline;
7090 }
7091
7092 @Override
7093 public long getNextMaxDailyDeadline() {
7094 return mNextMaxDailyDeadline;
7095 }
7096
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007097 @Override
7098 public boolean startIteratingOldHistoryLocked() {
7099 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
7100 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007101 if ((mHistoryIterator = mHistory) == null) {
7102 return false;
7103 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007104 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007105 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007106 mReadOverflow = false;
7107 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007108 return true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007109 }
7110
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007111 @Override
7112 public boolean getNextOldHistoryLocked(HistoryItem out) {
7113 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
7114 if (!end) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007115 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007116 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007117 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007118 HistoryItem cur = mHistoryIterator;
7119 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007120 if (!mReadOverflow && !end) {
7121 Slog.w(TAG, "Old history ends before new history!");
7122 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007123 return false;
7124 }
7125 out.setTo(cur);
7126 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007127 if (!mReadOverflow) {
7128 if (end) {
7129 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007130 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn8c841092013-06-24 13:46:13 -07007131 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007132 pw.println("Histories differ!");
7133 pw.println("Old history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007134 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007135 pw.println("New history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007136 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false,
7137 true);
Dianne Hackborn8c841092013-06-24 13:46:13 -07007138 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007139 }
7140 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07007141 return true;
7142 }
7143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007144 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007145 public void finishIteratingOldHistoryLocked() {
7146 mIteratingHistory = false;
7147 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007148 mHistoryIterator = null;
7149 }
7150
7151 public int getHistoryTotalSize() {
7152 return MAX_HISTORY_BUFFER;
7153 }
7154
7155 public int getHistoryUsedSize() {
7156 return mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007157 }
7158
7159 @Override
7160 public boolean startIteratingHistoryLocked() {
7161 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
7162 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007163 if (mHistoryBuffer.dataSize() <= 0) {
7164 return false;
7165 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007166 mHistoryBuffer.setDataPosition(0);
7167 mReadOverflow = false;
7168 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007169 mReadHistoryStrings = new String[mHistoryTagPool.size()];
7170 mReadHistoryUids = new int[mHistoryTagPool.size()];
7171 mReadHistoryChars = 0;
7172 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
7173 final HistoryTag tag = ent.getKey();
7174 final int idx = ent.getValue();
7175 mReadHistoryStrings[idx] = tag.string;
7176 mReadHistoryUids[idx] = tag.uid;
7177 mReadHistoryChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08007178 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007179 return true;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007180 }
7181
7182 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08007183 public int getHistoryStringPoolSize() {
7184 return mReadHistoryStrings.length;
7185 }
7186
7187 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007188 public int getHistoryStringPoolBytes() {
7189 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
7190 // Each string character is 2 bytes.
7191 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
7192 }
7193
7194 @Override
7195 public String getHistoryTagPoolString(int index) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08007196 return mReadHistoryStrings[index];
7197 }
7198
7199 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08007200 public int getHistoryTagPoolUid(int index) {
7201 return mReadHistoryUids[index];
7202 }
7203
7204 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007205 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07007206 final int pos = mHistoryBuffer.dataPosition();
7207 if (pos == 0) {
7208 out.clear();
7209 }
7210 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007211 if (end) {
7212 return false;
7213 }
7214
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007215 final long lastRealtime = out.time;
7216 final long lastWalltime = out.currentTime;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007217 readHistoryDelta(mHistoryBuffer, out);
Dianne Hackborn37de0982014-05-09 09:32:18 -07007218 if (out.cmd != HistoryItem.CMD_CURRENT_TIME
7219 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
Dianne Hackborn99009ea2014-04-18 16:23:42 -07007220 out.currentTime = lastWalltime + (out.time - lastRealtime);
7221 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07007222 return true;
7223 }
7224
7225 @Override
7226 public void finishIteratingHistoryLocked() {
7227 mIteratingHistory = false;
7228 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn099bc622014-01-22 13:39:16 -08007229 mReadHistoryStrings = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007230 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007231
Dianne Hackborn32907cf2010-06-10 17:50:20 -07007232 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07007233 public long getHistoryBaseTime() {
7234 return mHistoryBaseTime;
7235 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007236
Dianne Hackbornb5e31652010-09-07 12:13:55 -07007237 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007238 public int getStartCount() {
7239 return mStartCount;
7240 }
7241
7242 public boolean isOnBattery() {
7243 return mOnBattery;
7244 }
7245
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007246 public boolean isScreenOn() {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007247 return mScreenState == Display.STATE_ON;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007248 }
7249
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007250 void initTimes(long uptime, long realtime) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08007251 mStartClockTime = System.currentTimeMillis();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007252 mOnBatteryTimeBase.init(uptime, realtime);
7253 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
Dianne Hackborn4590e522014-03-24 13:36:46 -07007254 mRealtime = 0;
7255 mUptime = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007256 mRealtimeStart = realtime;
Dianne Hackborn4590e522014-03-24 13:36:46 -07007257 mUptimeStart = uptime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007258 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007259
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007260 void initDischarge() {
7261 mLowDischargeAmountSinceCharge = 0;
7262 mHighDischargeAmountSinceCharge = 0;
7263 mDischargeAmountScreenOn = 0;
7264 mDischargeAmountScreenOnSinceCharge = 0;
7265 mDischargeAmountScreenOff = 0;
7266 mDischargeAmountScreenOffSinceCharge = 0;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007267 mDischargeStepTracker.init();
7268 mChargeStepTracker.init();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007269 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007270
7271 public void resetAllStatsCmdLocked() {
7272 resetAllStatsLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07007273 final long mSecUptime = SystemClock.uptimeMillis();
7274 long uptime = mSecUptime * 1000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007275 long mSecRealtime = SystemClock.elapsedRealtime();
7276 long realtime = mSecRealtime * 1000;
7277 mDischargeStartLevel = mHistoryCur.batteryLevel;
7278 pullPendingStateUpdatesLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07007279 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007280 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
7281 = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007282 mOnBatteryTimeBase.reset(uptime, realtime);
7283 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
7284 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007285 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007286 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
7287 mDischargeScreenOffUnplugLevel = 0;
7288 } else {
7289 mDischargeScreenOnUnplugLevel = 0;
7290 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
7291 }
7292 mDischargeAmountScreenOn = 0;
7293 mDischargeAmountScreenOff = 0;
7294 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07007295 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08007296 }
7297
7298 private void resetAllStatsLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007299 mStartCount = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007300 initTimes(SystemClock.uptimeMillis() * 1000, SystemClock.elapsedRealtime() * 1000);
7301 mScreenOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007302 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007303 mScreenBrightnessTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007304 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007305 mInteractiveTimer.reset(false);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07007306 mPowerSaveModeEnabledTimer.reset(false);
7307 mDeviceIdleModeEnabledTimer.reset(false);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07007308 mDeviceIdlingTimer.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007309 mPhoneOnTimer.reset(false);
7310 mAudioOnTimer.reset(false);
7311 mVideoOnTimer.reset(false);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07007312 mFlashlightOnTimer.reset(false);
Wink Saville52840902011-02-18 12:40:47 -08007313 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007314 mPhoneSignalStrengthsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007315 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007316 mPhoneSignalScanningTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007317 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007318 mPhoneDataConnectionsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007319 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007320 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007321 mNetworkByteActivityCounters[i].reset(false);
7322 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007323 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007324 mMobileRadioActiveTimer.reset(false);
7325 mMobileRadioActivePerAppTimer.reset(false);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007326 mMobileRadioActiveAdjustedTime.reset(false);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007327 mMobileRadioActiveUnknownTime.reset(false);
7328 mMobileRadioActiveUnknownCount.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007329 mWifiOnTimer.reset(false);
7330 mGlobalWifiRunningTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007331 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007332 mWifiStateTimer[i].reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007333 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07007334 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
7335 mWifiSupplStateTimer[i].reset(false);
7336 }
7337 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
7338 mWifiSignalStrengthsTimer[i].reset(false);
7339 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007340 mBluetoothOnTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08007341 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007342 mBluetoothStateTimer[i].reset(false);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08007343 }
Adam Lesinski33dac552015-03-09 15:24:48 -07007344 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
7345 mBluetoothActivityCounters[i].reset(false);
7346 mWifiActivityCounters[i].reset(false);
7347 }
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007348 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007349
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007350 for (int i=0; i<mUidStats.size(); i++) {
7351 if (mUidStats.valueAt(i).reset()) {
7352 mUidStats.remove(mUidStats.keyAt(i));
7353 i--;
7354 }
7355 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007356
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007357 if (mKernelWakelockStats.size() > 0) {
7358 for (SamplingTimer timer : mKernelWakelockStats.values()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007359 mOnBatteryScreenOffTimeBase.remove(timer);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007360 }
7361 mKernelWakelockStats.clear();
7362 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007363
7364 if (mWakeupReasonStats.size() > 0) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07007365 for (SamplingTimer timer : mWakeupReasonStats.values()) {
7366 mOnBatteryTimeBase.remove(timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007367 }
7368 mWakeupReasonStats.clear();
7369 }
7370
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007371 mLastHistoryStepDetails = null;
7372 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0;
7373 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0;
7374 mLastStepCpuUserTime = mCurStepCpuUserTime = 0;
7375 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0;
7376 mLastStepStatUserTime = mCurStepStatUserTime = 0;
7377 mLastStepStatSystemTime = mCurStepStatSystemTime = 0;
7378 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0;
7379 mLastStepStatIrqTime = mCurStepStatIrqTime = 0;
7380 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0;
7381 mLastStepStatIdleTime = mCurStepStatIdleTime = 0;
7382
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007383 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007384
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007385 clearHistoryLocked();
7386 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007387
Dianne Hackborn40c87252014-03-19 16:55:40 -07007388 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007389 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007390 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) {
7391 // Not recording process starts/stops.
7392 continue;
7393 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07007394 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007395 if (active == null) {
7396 continue;
7397 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07007398 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
7399 SparseIntArray uids = ent.getValue();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007400 for (int j=0; j<uids.size(); j++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07007401 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
7402 uids.keyAt(j));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007403 }
7404 }
7405 }
7406 }
7407
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007408 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08007409 if (oldScreenOn) {
7410 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
7411 if (diff > 0) {
7412 mDischargeAmountScreenOn += diff;
7413 mDischargeAmountScreenOnSinceCharge += diff;
7414 }
7415 } else {
7416 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
7417 if (diff > 0) {
7418 mDischargeAmountScreenOff += diff;
7419 mDischargeAmountScreenOffSinceCharge += diff;
7420 }
7421 }
7422 if (newScreenOn) {
7423 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
7424 mDischargeScreenOffUnplugLevel = 0;
7425 } else {
7426 mDischargeScreenOnUnplugLevel = 0;
7427 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
7428 }
7429 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007430
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007431 public void pullPendingStateUpdatesLocked() {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08007432 if (mOnBatteryInternal) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07007433 final boolean screenOn = mScreenState == Display.STATE_ON;
7434 updateDischargeScreenLevelsLocked(screenOn, screenOn);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08007435 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007436 }
7437
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007438 private String[] mMobileIfaces = EmptyArray.STRING;
7439 private String[] mWifiIfaces = EmptyArray.STRING;
7440
7441 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
7442
7443 private static final int NETWORK_STATS_LAST = 0;
7444 private static final int NETWORK_STATS_NEXT = 1;
7445 private static final int NETWORK_STATS_DELTA = 2;
7446
7447 private final NetworkStats[] mMobileNetworkStats = new NetworkStats[] {
7448 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7449 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7450 new NetworkStats(SystemClock.elapsedRealtime(), 50)
7451 };
7452
7453 private final NetworkStats[] mWifiNetworkStats = new NetworkStats[] {
7454 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7455 new NetworkStats(SystemClock.elapsedRealtime(), 50),
7456 new NetworkStats(SystemClock.elapsedRealtime(), 50)
7457 };
7458
7459 /**
7460 * Retrieves the delta of network stats for the given network ifaces. Uses networkStatsBuffer
7461 * as a buffer of NetworkStats objects to cycle through when computing deltas.
7462 */
7463 private NetworkStats getNetworkStatsDeltaLocked(String[] ifaces,
7464 NetworkStats[] networkStatsBuffer)
7465 throws IOException {
7466 if (!SystemProperties.getBoolean(NetworkManagementSocketTagger.PROP_QTAGUID_ENABLED,
7467 false)) {
7468 return null;
7469 }
7470
7471 final NetworkStats stats = mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL,
7472 ifaces, NetworkStats.TAG_NONE, networkStatsBuffer[NETWORK_STATS_NEXT]);
7473 networkStatsBuffer[NETWORK_STATS_DELTA] = NetworkStats.subtract(stats,
7474 networkStatsBuffer[NETWORK_STATS_LAST], null, null,
7475 networkStatsBuffer[NETWORK_STATS_DELTA]);
7476 networkStatsBuffer[NETWORK_STATS_NEXT] = networkStatsBuffer[NETWORK_STATS_LAST];
7477 networkStatsBuffer[NETWORK_STATS_LAST] = stats;
7478 return networkStatsBuffer[NETWORK_STATS_DELTA];
7479 }
7480
7481 /**
7482 * Distribute WiFi energy info and network traffic to apps.
7483 * @param info The energy information from the WiFi controller.
7484 */
7485 public void updateWifiStateLocked(@Nullable final WifiActivityEnergyInfo info) {
Adam Lesinskie08af192015-03-25 16:42:59 -07007486 final long elapsedRealtimeMs = SystemClock.elapsedRealtime();
7487 NetworkStats delta = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007488 try {
Adam Lesinskie08af192015-03-25 16:42:59 -07007489 if (!ArrayUtils.isEmpty(mWifiIfaces)) {
7490 delta = getNetworkStatsDeltaLocked(mWifiIfaces, mWifiNetworkStats);
7491 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007492 } catch (IOException e) {
7493 Slog.wtf(TAG, "Failed to get wifi network stats", e);
7494 return;
7495 }
7496
7497 if (!mOnBatteryInternal) {
7498 return;
7499 }
7500
Adam Lesinskie08af192015-03-25 16:42:59 -07007501 SparseLongArray rxPackets = new SparseLongArray();
7502 SparseLongArray txPackets = new SparseLongArray();
7503 long totalTxPackets = 0;
7504 long totalRxPackets = 0;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007505 if (delta != null) {
7506 final int size = delta.size();
7507 for (int i = 0; i < size; i++) {
7508 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
7509
Adam Lesinskie08af192015-03-25 16:42:59 -07007510 if (DEBUG_ENERGY) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007511 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
Adam Lesinskie08af192015-03-25 16:42:59 -07007512 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
7513 + " txPackets=" + entry.txPackets);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007514 }
7515
7516 if (entry.rxBytes == 0 || entry.txBytes == 0) {
7517 continue;
7518 }
7519
7520 final Uid u = getUidStatsLocked(mapUid(entry.uid));
7521 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
7522 entry.rxPackets);
7523 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
7524 entry.txPackets);
Adam Lesinskie08af192015-03-25 16:42:59 -07007525 rxPackets.put(u.getUid(), entry.rxPackets);
7526 txPackets.put(u.getUid(), entry.txPackets);
7527
7528 // Sum the total number of packets so that the Rx Power and Tx Power can
7529 // be evenly distributed amongst the apps.
7530 totalRxPackets += entry.rxPackets;
7531 totalTxPackets += entry.txPackets;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007532
7533 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
7534 entry.rxBytes);
7535 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
7536 entry.txBytes);
7537 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
7538 entry.rxPackets);
7539 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
7540 entry.txPackets);
7541 }
7542 }
7543
7544 if (info != null) {
Adam Lesinskie08af192015-03-25 16:42:59 -07007545 // Measured in mAms
7546 final long txTimeMs = info.getControllerTxTimeMillis();
7547 final long rxTimeMs = info.getControllerRxTimeMillis();
7548 final long idleTimeMs = info.getControllerIdleTimeMillis();
7549 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
7550
7551 long leftOverRxTimeMs = rxTimeMs;
7552
7553 if (DEBUG_ENERGY) {
7554 Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
7555 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
7556 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
7557 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
7558 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms");
7559 }
7560
7561 long totalWifiLockTimeMs = 0;
7562 long totalScanTimeMs = 0;
7563
7564 // On the first pass, collect some totals so that we can normalize power
7565 // calculations if we need to.
7566 final int uidStatsSize = mUidStats.size();
7567 for (int i = 0; i < uidStatsSize; i++) {
7568 final Uid uid = mUidStats.valueAt(i);
7569
7570 // Sum the total scan power for all apps.
7571 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
7572 elapsedRealtimeMs * 1000) / 1000;
7573
7574 // Sum the total time holding wifi lock for all apps.
7575 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
7576 elapsedRealtimeMs * 1000) / 1000;
7577 }
7578
7579 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
7580 Slog.d(TAG, " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
7581 + rxTimeMs + " ms). Normalizing scan time.");
7582 }
7583
7584 // Actually assign and distribute power usage to apps.
7585 for (int i = 0; i < uidStatsSize; i++) {
7586 final Uid uid = mUidStats.valueAt(i);
7587
7588 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
7589 elapsedRealtimeMs * 1000) / 1000;
7590 if (scanTimeSinceMarkMs > 0) {
7591 // Set the new mark so that next time we get new data since this point.
7592 uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
7593
7594 if (totalScanTimeMs > rxTimeMs) {
7595 // Our total scan time is more than the reported Rx time.
7596 // This is possible because the cost of a scan is approximate.
7597 // Let's normalize the result so that we evenly blame each app
7598 // scanning.
7599 //
7600 // This means that we may have apps that received packets not be blamed
7601 // for this, but this is fine as scans are relatively more expensive.
7602 scanTimeSinceMarkMs = (rxTimeMs * scanTimeSinceMarkMs) / totalScanTimeMs;
7603 }
7604
7605 if (DEBUG_ENERGY) {
7606 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": "
7607 + scanTimeSinceMarkMs + " ms)");
7608 }
7609 uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, scanTimeSinceMarkMs);
7610 leftOverRxTimeMs -= scanTimeSinceMarkMs;
7611 }
7612
7613 // Distribute evenly the power consumed while Idle to each app holding a WiFi
7614 // lock.
7615 final long wifiLockTimeSinceMarkMs = uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
7616 elapsedRealtimeMs * 1000) / 1000;
7617 if (wifiLockTimeSinceMarkMs > 0) {
7618 // Set the new mark so that next time we get new data since this point.
7619 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
7620
7621 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
7622 / totalWifiLockTimeMs;
7623 if (DEBUG_ENERGY) {
7624 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": "
7625 + myIdleTimeMs + " ms");
7626 }
7627 uid.noteWifiControllerActivityLocked(CONTROLLER_IDLE_TIME, myIdleTimeMs);
7628 }
7629 }
7630
7631 if (DEBUG_ENERGY) {
7632 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
7633 }
7634
7635 // Distribute the Tx power appropriately between all apps that transmitted packets.
7636 for (int i = 0; i < txPackets.size(); i++) {
7637 final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
7638 final long myTxTimeMs = (txPackets.valueAt(i) * txTimeMs) / totalTxPackets;
7639 if (DEBUG_ENERGY) {
7640 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
7641 }
7642 uid.noteWifiControllerActivityLocked(CONTROLLER_TX_TIME, myTxTimeMs);
7643 }
7644
7645 // Distribute the remaining Rx power appropriately between all apps that received
7646 // packets.
7647 for (int i = 0; i < rxPackets.size(); i++) {
7648 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i));
7649 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs) / totalRxPackets;
7650 if (DEBUG_ENERGY) {
7651 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
7652 }
7653 uid.noteWifiControllerActivityLocked(CONTROLLER_RX_TIME, myRxTimeMs);
7654 }
7655
7656 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
7657
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007658 // Update WiFi controller stats.
7659 mWifiActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
7660 info.getControllerRxTimeMillis());
7661 mWifiActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
7662 info.getControllerTxTimeMillis());
7663 mWifiActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
7664 info.getControllerIdleTimeMillis());
Adam Lesinskie08af192015-03-25 16:42:59 -07007665
7666 final double powerDrainMaMs;
7667 if (mPowerProfile.getAveragePower(
7668 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) == 0) {
7669 powerDrainMaMs = 0.0;
7670 } else {
7671 powerDrainMaMs = info.getControllerEnergyUsed()
7672 / mPowerProfile.getAveragePower(
7673 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE);
7674 }
7675 mWifiActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked((long) powerDrainMaMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007676 }
7677 }
7678
7679 /**
7680 * Distribute Cell radio energy info and network traffic to apps.
7681 */
Adam Lesinskie08af192015-03-25 16:42:59 -07007682 public void updateMobileRadioStateLocked(final long elapsedRealtimeMs) {
7683 NetworkStats delta = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007684 try {
Adam Lesinskie08af192015-03-25 16:42:59 -07007685 if (!ArrayUtils.isEmpty(mMobileIfaces)) {
7686 delta = getNetworkStatsDeltaLocked(mMobileIfaces, mMobileNetworkStats);
7687 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007688 } catch (IOException e) {
7689 Slog.wtf(TAG, "Failed to get mobile network stats", e);
7690 return;
7691 }
7692
7693 if (delta == null || !mOnBatteryInternal) {
7694 return;
7695 }
7696
Adam Lesinskie08af192015-03-25 16:42:59 -07007697 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
7698 elapsedRealtimeMs * 1000);
7699 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007700 long totalPackets = delta.getTotalPackets();
7701
7702 final int size = delta.size();
7703 for (int i = 0; i < size; i++) {
7704 final NetworkStats.Entry entry = delta.getValues(i, mTmpNetworkStatsEntry);
7705
Adam Lesinskie08af192015-03-25 16:42:59 -07007706 if (entry.rxBytes == 0 || entry.txBytes == 0) {
7707 continue;
7708 }
7709
7710 if (DEBUG_ENERGY) {
7711 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
7712 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
7713 + " txPackets=" + entry.txPackets);
7714 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007715
7716 final Uid u = getUidStatsLocked(mapUid(entry.uid));
7717 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
7718 entry.rxPackets);
7719 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
7720 entry.txPackets);
7721
7722 if (radioTime > 0) {
7723 // Distribute total radio active time in to this app.
7724 long appPackets = entry.rxPackets + entry.txPackets;
7725 long appRadioTime = (radioTime*appPackets)/totalPackets;
7726 u.noteMobileRadioActiveTimeLocked(appRadioTime);
7727 // Remove this app from the totals, so that we don't lose any time
7728 // due to rounding.
7729 radioTime -= appRadioTime;
7730 totalPackets -= appPackets;
7731 }
7732
7733 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
7734 entry.rxBytes);
7735 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
7736 entry.txBytes);
7737 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
7738 entry.rxPackets);
7739 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
7740 entry.txPackets);
7741 }
7742
7743 if (radioTime > 0) {
7744 // Whoops, there is some radio time we can't blame on an app!
7745 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
7746 mMobileRadioActiveUnknownCount.addCountLocked(1);
7747 }
7748 }
7749
7750 /**
7751 * Distribute Bluetooth energy info and network traffic to apps.
7752 * @param info The energy information from the bluetooth controller.
7753 */
7754 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
Adam Lesinskie08af192015-03-25 16:42:59 -07007755 if (info != null && mOnBatteryInternal && false) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007756 mBluetoothActivityCounters[CONTROLLER_RX_TIME].addCountLocked(
7757 info.getControllerRxTimeMillis());
7758 mBluetoothActivityCounters[CONTROLLER_TX_TIME].addCountLocked(
7759 info.getControllerTxTimeMillis());
7760 mBluetoothActivityCounters[CONTROLLER_IDLE_TIME].addCountLocked(
7761 info.getControllerIdleTimeMillis());
Adam Lesinskie08af192015-03-25 16:42:59 -07007762 mBluetoothActivityCounters[CONTROLLER_POWER_DRAIN].addCountLocked(
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007763 info.getControllerEnergyUsed());
7764 }
7765 }
7766
7767 /**
7768 * Read and distribute kernel wake lock use across apps.
7769 */
7770 public void updateKernelWakelocksLocked() {
7771 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
7772 mTmpWakelockStats);
7773 if (wakelockStats == null) {
7774 // Not crashing might make board bringup easier.
7775 Slog.w(TAG, "Couldn't get kernel wake lock stats");
7776 return;
7777 }
7778
7779 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
7780 String name = ent.getKey();
7781 KernelWakelockStats.Entry kws = ent.getValue();
7782
7783 SamplingTimer kwlt = mKernelWakelockStats.get(name);
7784 if (kwlt == null) {
7785 kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase,
7786 true /* track reported val */);
7787 mKernelWakelockStats.put(name, kwlt);
7788 }
7789 kwlt.updateCurrentReportedCount(kws.mCount);
7790 kwlt.updateCurrentReportedTotalTime(kws.mTotalTime);
7791 kwlt.setUpdateVersion(kws.mVersion);
7792 }
7793
7794 if (wakelockStats.size() != mKernelWakelockStats.size()) {
7795 // Set timers to stale if they didn't appear in /proc/wakelocks this time.
7796 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
7797 SamplingTimer st = ent.getValue();
7798 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
7799 st.setStale();
7800 }
7801 }
7802 }
7803 }
7804
Dianne Hackborn40c87252014-03-19 16:55:40 -07007805 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
7806 final int oldStatus, final int level) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007807 boolean doWrite = false;
7808 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
7809 m.arg1 = onBattery ? 1 : 0;
7810 mHandler.sendMessage(m);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007811
Dianne Hackborn40c87252014-03-19 16:55:40 -07007812 final long uptime = mSecUptime * 1000;
7813 final long realtime = mSecRealtime * 1000;
Jeff Browne95c3cd2014-05-02 16:59:26 -07007814 final boolean screenOn = mScreenState == Display.STATE_ON;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007815 if (onBattery) {
7816 // We will reset our status if we are unplugging after the
7817 // battery was last full, or the level is at 100, or
7818 // we have gone through a significant charge (from a very low
7819 // level to a now very high level).
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007820 boolean reset = false;
Dianne Hackborn9a755432014-05-15 17:05:22 -07007821 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007822 || level >= 90
Dianne Hackbornfb3809c2014-09-29 18:31:22 -07007823 || (mDischargeCurrentLevel < 20 && level >= 80)
7824 || (getHighDischargeAmountSinceCharge() >= 200
7825 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -07007826 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
Dianne Hackbornfb3809c2014-09-29 18:31:22 -07007827 + " dischargeLevel=" + mDischargeCurrentLevel
Dianne Hackborn73d6a822014-09-29 10:52:47 -07007828 + " lowAmount=" + getLowDischargeAmountSinceCharge()
7829 + " highAmount=" + getHighDischargeAmountSinceCharge());
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007830 // Before we write, collect a snapshot of the final aggregated
7831 // stats to be reported in the next checkin. Only do this if we have
7832 // a sufficient amount of data to make it interesting.
7833 if (getLowDischargeAmountSinceCharge() >= 20) {
7834 final Parcel parcel = Parcel.obtain();
7835 writeSummaryToParcel(parcel, true);
7836 BackgroundThread.getHandler().post(new Runnable() {
7837 @Override public void run() {
7838 synchronized (mCheckinFile) {
7839 FileOutputStream stream = null;
7840 try {
7841 stream = mCheckinFile.startWrite();
7842 stream.write(parcel.marshall());
7843 stream.flush();
7844 FileUtils.sync(stream);
7845 stream.close();
7846 mCheckinFile.finishWrite(stream);
7847 } catch (IOException e) {
7848 Slog.w("BatteryStats",
7849 "Error writing checkin battery statistics", e);
7850 mCheckinFile.failWrite(stream);
7851 } finally {
7852 parcel.recycle();
7853 }
7854 }
7855 }
7856 });
7857 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007858 doWrite = true;
7859 resetAllStatsLocked();
7860 mDischargeStartLevel = level;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08007861 reset = true;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007862 mDischargeStepTracker.init();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007863 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007864 mOnBattery = mOnBatteryInternal = true;
Dianne Hackborn260c5022014-04-29 11:23:16 -07007865 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07007866 mMinDischargeStepLevel = level;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007867 mDischargeStepTracker.clearTime();
7868 mDailyDischargeStepTracker.clearTime();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007869 mInitStepMode = mCurStepMode;
7870 mModStepMode = 0;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007871 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007872 mHistoryCur.batteryLevel = (byte)level;
7873 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
7874 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
7875 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007876 if (reset) {
7877 mRecordingHistory = true;
7878 startRecordingHistory(mSecRealtime, mSecUptime, reset);
7879 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07007880 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007881 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
Jeff Browne95c3cd2014-05-02 16:59:26 -07007882 if (screenOn) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007883 mDischargeScreenOnUnplugLevel = level;
7884 mDischargeScreenOffUnplugLevel = 0;
7885 } else {
7886 mDischargeScreenOnUnplugLevel = 0;
7887 mDischargeScreenOffUnplugLevel = level;
7888 }
7889 mDischargeAmountScreenOn = 0;
7890 mDischargeAmountScreenOff = 0;
Jeff Browne95c3cd2014-05-02 16:59:26 -07007891 updateTimeBasesLocked(true, !screenOn, uptime, realtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007892 } else {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007893 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborna7c837f2014-01-15 16:20:44 -08007894 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007895 mHistoryCur.batteryLevel = (byte)level;
7896 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
7897 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
7898 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07007899 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07007900 mDischargeCurrentLevel = mDischargePlugLevel = level;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007901 if (level < mDischargeUnplugLevel) {
7902 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
7903 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
7904 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07007905 updateDischargeScreenLevelsLocked(screenOn, screenOn);
7906 updateTimeBasesLocked(false, !screenOn, uptime, realtime);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08007907 mChargeStepTracker.init();
Dianne Hackborn260c5022014-04-29 11:23:16 -07007908 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -07007909 mMaxChargeStepLevel = level;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07007910 mInitStepMode = mCurStepMode;
7911 mModStepMode = 0;
Dianne Hackborn32de2f62011-03-09 14:03:35 -08007912 }
7913 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
7914 if (mFile != null) {
7915 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007916 }
7917 }
7918 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007919
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007920 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
7921 boolean reset) {
7922 mRecordingHistory = true;
7923 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborna7d0d552014-09-12 17:15:52 -07007924 mLastRecordedClockTime = mHistoryCur.currentTime;
7925 mLastRecordedClockRealtime = elapsedRealtimeMs;
Dianne Hackborn37de0982014-05-09 09:32:18 -07007926 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
7927 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
Dianne Hackborna1bd7922014-03-21 11:07:11 -07007928 mHistoryCur);
7929 mHistoryCur.currentTime = 0;
7930 if (reset) {
7931 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
7932 }
7933 }
7934
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07007935 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs,
7936 final long uptimeMs) {
7937 if (mRecordingHistory) {
7938 mHistoryCur.currentTime = currentTime;
Dianne Hackborna7d0d552014-09-12 17:15:52 -07007939 mLastRecordedClockTime = currentTime;
7940 mLastRecordedClockRealtime = elapsedRealtimeMs;
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07007941 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
7942 mHistoryCur);
7943 mHistoryCur.currentTime = 0;
7944 }
7945 }
7946
Dianne Hackborn29cd7f12015-01-08 10:37:05 -08007947 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
7948 if (mRecordingHistory) {
7949 mHistoryCur.currentTime = System.currentTimeMillis();
7950 mLastRecordedClockTime = mHistoryCur.currentTime;
7951 mLastRecordedClockRealtime = elapsedRealtimeMs;
7952 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN,
7953 mHistoryCur);
7954 mHistoryCur.currentTime = 0;
7955 }
7956 }
7957
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007958 private void scheduleSyncExternalStatsLocked() {
7959 if (mExternalSync != null) {
7960 mExternalSync.scheduleSync();
7961 }
7962 }
7963
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007964 // This should probably be exposed in the API, though it's not critical
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007965 public static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007966
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007967 public void setBatteryStateLocked(int status, int health, int plugType, int level,
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007968 int temp, int volt) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007969 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
7970 final long uptime = SystemClock.uptimeMillis();
7971 final long elapsedRealtime = SystemClock.elapsedRealtime();
7972 if (!mHaveBatteryLevel) {
7973 mHaveBatteryLevel = true;
7974 // We start out assuming that the device is plugged in (not
7975 // on battery). If our first report is now that we are indeed
7976 // plugged in, then twiddle our state to correctly reflect that
7977 // since we won't be going through the full setOnBattery().
7978 if (onBattery == mOnBattery) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07007979 if (onBattery) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007980 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -07007981 } else {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007982 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -07007983 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007984 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007985 mHistoryCur.batteryStatus = (byte)status;
7986 mHistoryCur.batteryLevel = (byte)level;
7987 mMaxChargeStepLevel = mMinDischargeStepLevel =
7988 mLastChargeStepLevel = mLastDischargeStepLevel = level;
7989 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
7990 recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
7991 }
7992 int oldStatus = mHistoryCur.batteryStatus;
7993 if (onBattery) {
7994 mDischargeCurrentLevel = level;
7995 if (!mRecordingHistory) {
7996 mRecordingHistory = true;
7997 startRecordingHistory(elapsedRealtime, uptime, true);
7998 }
7999 } else if (level < 96) {
8000 if (!mRecordingHistory) {
8001 mRecordingHistory = true;
8002 startRecordingHistory(elapsedRealtime, uptime, true);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008003 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008004 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008005 mCurrentBatteryLevel = level;
8006 if (mDischargePlugLevel < 0) {
8007 mDischargePlugLevel = level;
Marco Nelissend8593312009-04-30 14:45:06 -07008008 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008009 if (onBattery != mOnBattery) {
8010 mHistoryCur.batteryLevel = (byte)level;
8011 mHistoryCur.batteryStatus = (byte)status;
8012 mHistoryCur.batteryHealth = (byte)health;
8013 mHistoryCur.batteryPlugType = (byte)plugType;
8014 mHistoryCur.batteryTemperature = (short)temp;
8015 mHistoryCur.batteryVoltage = (char)volt;
8016 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level);
8017 } else {
8018 boolean changed = false;
8019 if (mHistoryCur.batteryLevel != level) {
8020 mHistoryCur.batteryLevel = (byte)level;
8021 changed = true;
Marco Nelissend8593312009-04-30 14:45:06 -07008022
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008023 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
8024 // which will pull external stats.
8025 scheduleSyncExternalStatsLocked();
Evan Millarc64edde2009-04-18 12:26:32 -07008026 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008027 if (mHistoryCur.batteryStatus != status) {
8028 mHistoryCur.batteryStatus = (byte)status;
8029 changed = true;
8030 }
8031 if (mHistoryCur.batteryHealth != health) {
8032 mHistoryCur.batteryHealth = (byte)health;
8033 changed = true;
8034 }
8035 if (mHistoryCur.batteryPlugType != plugType) {
8036 mHistoryCur.batteryPlugType = (byte)plugType;
8037 changed = true;
8038 }
8039 if (temp >= (mHistoryCur.batteryTemperature+10)
8040 || temp <= (mHistoryCur.batteryTemperature-10)) {
8041 mHistoryCur.batteryTemperature = (short)temp;
8042 changed = true;
8043 }
8044 if (volt > (mHistoryCur.batteryVoltage+20)
8045 || volt < (mHistoryCur.batteryVoltage-20)) {
8046 mHistoryCur.batteryVoltage = (char)volt;
8047 changed = true;
8048 }
8049 if (changed) {
8050 addHistoryRecordLocked(elapsedRealtime, uptime);
8051 }
8052 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
8053 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
8054 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
8055 if (onBattery) {
8056 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
8057 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
8058 modeBits, elapsedRealtime);
8059 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
8060 modeBits, elapsedRealtime);
8061 mLastDischargeStepLevel = level;
8062 mMinDischargeStepLevel = level;
8063 mInitStepMode = mCurStepMode;
8064 mModStepMode = 0;
8065 }
8066 } else {
8067 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
8068 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
8069 modeBits, elapsedRealtime);
8070 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
8071 modeBits, elapsedRealtime);
8072 mLastChargeStepLevel = level;
8073 mMaxChargeStepLevel = level;
8074 mInitStepMode = mCurStepMode;
8075 mModStepMode = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07008076 }
8077 }
8078 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008079 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
8080 // We don't record history while we are plugged in and fully charged.
8081 // The next time we are unplugged, history will be cleared.
8082 mRecordingHistory = DEBUG;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08008083 }
Adam Lesinski33dac552015-03-09 15:24:48 -07008084 }
8085
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008086 public long getAwakeTimeBattery() {
8087 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
8088 }
8089
8090 public long getAwakeTimePlugged() {
8091 return (SystemClock.uptimeMillis() * 1000) - getAwakeTimeBattery();
8092 }
8093
8094 @Override
8095 public long computeUptime(long curTime, int which) {
8096 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008097 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008098 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07008099 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008100 }
8101 return 0;
8102 }
8103
8104 @Override
8105 public long computeRealtime(long curTime, int which) {
8106 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008107 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008108 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -07008109 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008110 }
8111 return 0;
8112 }
8113
8114 @Override
8115 public long computeBatteryUptime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008116 return mOnBatteryTimeBase.computeUptime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 }
8118
8119 @Override
8120 public long computeBatteryRealtime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008121 return mOnBatteryTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008122 }
8123
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008124 @Override
8125 public long computeBatteryScreenOffUptime(long curTime, int which) {
8126 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
8127 }
8128
8129 @Override
8130 public long computeBatteryScreenOffRealtime(long curTime, int which) {
8131 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008132 }
8133
Dianne Hackborn260c5022014-04-29 11:23:16 -07008134 private long computeTimePerLevel(long[] steps, int numSteps) {
8135 // For now we'll do a simple average across all steps.
8136 if (numSteps <= 0) {
8137 return -1;
8138 }
8139 long total = 0;
8140 for (int i=0; i<numSteps; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008141 total += steps[i] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008142 }
8143 return total / numSteps;
8144 /*
8145 long[] buckets = new long[numSteps];
8146 int numBuckets = 0;
8147 int numToAverage = 4;
8148 int i = 0;
8149 while (i < numSteps) {
8150 long totalTime = 0;
8151 int num = 0;
8152 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008153 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008154 num++;
8155 }
8156 buckets[numBuckets] = totalTime / num;
8157 numBuckets++;
8158 numToAverage *= 2;
8159 i += num;
8160 }
8161 if (numBuckets < 1) {
8162 return -1;
8163 }
8164 long averageTime = buckets[numBuckets-1];
8165 for (i=numBuckets-2; i>=0; i--) {
8166 averageTime = (averageTime + buckets[i]) / 2;
8167 }
8168 return averageTime;
8169 */
8170 }
8171
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008172 @Override
8173 public long computeBatteryTimeRemaining(long curTime) {
8174 if (!mOnBattery) {
8175 return -1;
8176 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07008177 /* Simple implementation just looks at the average discharge per level across the
8178 entire sample period.
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008179 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2;
8180 if (discharge < 2) {
8181 return -1;
8182 }
8183 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED);
8184 if (duration < 1000*1000) {
8185 return -1;
8186 }
8187 long usPerLevel = duration/discharge;
8188 return usPerLevel * mCurrentBatteryLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -07008189 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008190 if (mDischargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008191 return -1;
8192 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008193 long msPerLevel = mDischargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -07008194 if (msPerLevel <= 0) {
8195 return -1;
8196 }
8197 return (msPerLevel * mCurrentBatteryLevel) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008198 }
8199
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008200 @Override
8201 public LevelStepTracker getDischargeLevelStepTracker() {
8202 return mDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008203 }
8204
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008205 @Override
8206 public LevelStepTracker getDailyDischargeLevelStepTracker() {
8207 return mDailyDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008208 }
8209
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008210 @Override
8211 public long computeChargeTimeRemaining(long curTime) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008212 if (mOnBattery) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008213 // Not yet working.
8214 return -1;
8215 }
Dianne Hackborn260c5022014-04-29 11:23:16 -07008216 /* Broken
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008217 int curLevel = mCurrentBatteryLevel;
8218 int plugLevel = mDischargePlugLevel;
8219 if (plugLevel < 0 || curLevel < (plugLevel+1)) {
8220 return -1;
8221 }
8222 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED);
8223 if (duration < 1000*1000) {
8224 return -1;
8225 }
8226 long usPerLevel = duration/(curLevel-plugLevel);
8227 return usPerLevel * (100-curLevel);
Dianne Hackborn260c5022014-04-29 11:23:16 -07008228 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008229 if (mChargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -07008230 return -1;
8231 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008232 long msPerLevel = mChargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -07008233 if (msPerLevel <= 0) {
8234 return -1;
8235 }
8236 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008237 }
8238
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008239 @Override
8240 public LevelStepTracker getChargeLevelStepTracker() {
8241 return mChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008242 }
8243
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008244 @Override
8245 public LevelStepTracker getDailyChargeLevelStepTracker() {
8246 return mDailyChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -07008247 }
8248
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008249 @Override
8250 public ArrayList<PackageChange> getDailyPackageChanges() {
8251 return mDailyPackageChanges;
8252 }
8253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008254 long getBatteryUptimeLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008255 return mOnBatteryTimeBase.getUptime(SystemClock.uptimeMillis() * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008256 }
8257
8258 @Override
8259 public long getBatteryUptime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008260 return mOnBatteryTimeBase.getUptime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008261 }
8262
8263 @Override
8264 public long getBatteryRealtime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008265 return mOnBatteryTimeBase.getRealtime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008266 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07008267
The Android Open Source Project10592532009-03-18 17:39:46 -07008268 @Override
Evan Millar633a1742009-04-02 16:36:33 -07008269 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07008270 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07008271 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07008272 }
8273 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008274
Evan Millar633a1742009-04-02 16:36:33 -07008275 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008276 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07008277 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008278
The Android Open Source Project10592532009-03-18 17:39:46 -07008279 @Override
Evan Millar633a1742009-04-02 16:36:33 -07008280 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -07008281 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -07008282 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -07008283 }
8284 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008285
Evan Millar633a1742009-04-02 16:36:33 -07008286 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008287 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -07008288 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008289
Amith Yamasanie43530a2009-08-21 13:11:37 -07008290 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008291 public int getLowDischargeAmountSinceCharge() {
8292 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008293 int val = mLowDischargeAmountSinceCharge;
8294 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
8295 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
8296 }
8297 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008298 }
8299 }
8300
8301 @Override
8302 public int getHighDischargeAmountSinceCharge() {
8303 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08008304 int val = mHighDischargeAmountSinceCharge;
8305 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
8306 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
8307 }
8308 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008309 }
8310 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07008311
8312 @Override
8313 public int getDischargeAmount(int which) {
8314 int dischargeAmount = which == STATS_SINCE_CHARGED
8315 ? getHighDischargeAmountSinceCharge()
8316 : (getDischargeStartLevel() - getDischargeCurrentLevel());
8317 if (dischargeAmount < 0) {
8318 dischargeAmount = 0;
8319 }
8320 return dischargeAmount;
8321 }
8322
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008323 public int getDischargeAmountScreenOn() {
8324 synchronized(this) {
8325 int val = mDischargeAmountScreenOn;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008326 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008327 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
8328 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
8329 }
8330 return val;
8331 }
8332 }
8333
8334 public int getDischargeAmountScreenOnSinceCharge() {
8335 synchronized(this) {
8336 int val = mDischargeAmountScreenOnSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008337 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008338 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
8339 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
8340 }
8341 return val;
8342 }
8343 }
8344
8345 public int getDischargeAmountScreenOff() {
8346 synchronized(this) {
8347 int val = mDischargeAmountScreenOff;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008348 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008349 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
8350 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
8351 }
8352 return val;
8353 }
8354 }
8355
8356 public int getDischargeAmountScreenOffSinceCharge() {
8357 synchronized(this) {
8358 int val = mDischargeAmountScreenOffSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -07008359 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008360 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
8361 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
8362 }
8363 return val;
8364 }
8365 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008366
8367 @Override
Amith Yamasanie43530a2009-08-21 13:11:37 -07008368 public int getCpuSpeedSteps() {
8369 return sNumSpeedSteps;
8370 }
8371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008372 /**
8373 * Retrieve the statistics object for a particular uid, creating if needed.
8374 */
8375 public Uid getUidStatsLocked(int uid) {
8376 Uid u = mUidStats.get(uid);
8377 if (u == null) {
8378 u = new Uid(uid);
8379 mUidStats.put(uid, u);
8380 }
8381 return u;
8382 }
8383
8384 /**
8385 * Remove the statistics object for a particular uid.
8386 */
8387 public void removeUidStatsLocked(int uid) {
8388 mUidStats.remove(uid);
8389 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07008390
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008391 /**
8392 * Retrieve the statistics object for a particular process, creating
8393 * if needed.
8394 */
8395 public Uid.Proc getProcessStatsLocked(int uid, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008396 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008397 Uid u = getUidStatsLocked(uid);
8398 return u.getProcessStatsLocked(name);
8399 }
8400
8401 /**
8402 * Retrieve the statistics object for a particular process, creating
8403 * if needed.
8404 */
8405 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008406 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008407 Uid u = getUidStatsLocked(uid);
8408 return u.getPackageStatsLocked(pkg);
8409 }
8410
8411 /**
8412 * Retrieve the statistics object for a particular service, creating
8413 * if needed.
8414 */
8415 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -07008416 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008417 Uid u = getUidStatsLocked(uid);
8418 return u.getServiceStatsLocked(pkg, name);
8419 }
8420
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008421 /**
8422 * Massage data to distribute any reasonable work down to more specific
8423 * owners. Must only be called on a dead BatteryStats object!
8424 */
8425 public void distributeWorkLocked(int which) {
8426 // Aggregate all CPU time associated with WIFI.
8427 Uid wifiUid = mUidStats.get(Process.WIFI_UID);
8428 if (wifiUid != null) {
8429 long uSecTime = computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000, which);
Dianne Hackborn61659e52014-07-09 16:13:01 -07008430 for (int ip=wifiUid.mProcessStats.size()-1; ip>=0; ip--) {
8431 Uid.Proc proc = wifiUid.mProcessStats.valueAt(ip);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008432 long totalRunningTime = getGlobalWifiRunningTime(uSecTime, which);
8433 for (int i=0; i<mUidStats.size(); i++) {
8434 Uid uid = mUidStats.valueAt(i);
8435 if (uid.mUid != Process.WIFI_UID) {
8436 long uidRunningTime = uid.getWifiRunningTime(uSecTime, which);
8437 if (uidRunningTime > 0) {
8438 Uid.Proc uidProc = uid.getProcessStatsLocked("*wifi*");
8439 long time = proc.getUserTime(which);
8440 time = (time*uidRunningTime)/totalRunningTime;
8441 uidProc.mUserTime += time;
8442 proc.mUserTime -= time;
8443 time = proc.getSystemTime(which);
8444 time = (time*uidRunningTime)/totalRunningTime;
8445 uidProc.mSystemTime += time;
8446 proc.mSystemTime -= time;
8447 time = proc.getForegroundTime(which);
8448 time = (time*uidRunningTime)/totalRunningTime;
8449 uidProc.mForegroundTime += time;
8450 proc.mForegroundTime -= time;
8451 for (int sb=0; sb<proc.mSpeedBins.length; sb++) {
8452 SamplingCounter sc = proc.mSpeedBins[sb];
8453 if (sc != null) {
8454 time = sc.getCountLocked(which);
8455 time = (time*uidRunningTime)/totalRunningTime;
8456 SamplingCounter uidSc = uidProc.mSpeedBins[sb];
8457 if (uidSc == null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008458 uidSc = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008459 uidProc.mSpeedBins[sb] = uidSc;
8460 }
8461 uidSc.mCount.addAndGet((int)time);
8462 sc.mCount.addAndGet((int)-time);
8463 }
8464 }
8465 totalRunningTime -= uidRunningTime;
8466 }
8467 }
8468 }
8469 }
8470 }
8471 }
8472
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008473 public void shutdownLocked() {
Dianne Hackborn29cd7f12015-01-08 10:37:05 -08008474 recordShutdownLocked(SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008475 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008476 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008477 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008478
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008479 Parcel mPendingWrite = null;
8480 final ReentrantLock mWriteLock = new ReentrantLock();
8481
8482 public void writeAsyncLocked() {
8483 writeLocked(false);
8484 }
8485
8486 public void writeSyncLocked() {
8487 writeLocked(true);
8488 }
8489
8490 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008491 if (mFile == null) {
8492 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008493 return;
8494 }
8495
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008496 if (mShuttingDown) {
8497 return;
8498 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008499
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008500 Parcel out = Parcel.obtain();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008501 writeSummaryToParcel(out, true);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008502 mLastWriteTime = SystemClock.elapsedRealtime();
8503
8504 if (mPendingWrite != null) {
8505 mPendingWrite.recycle();
8506 }
8507 mPendingWrite = out;
8508
8509 if (sync) {
8510 commitPendingDataToDisk();
8511 } else {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008512 BackgroundThread.getHandler().post(new Runnable() {
8513 @Override public void run() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008514 commitPendingDataToDisk();
8515 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008516 });
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008517 }
8518 }
8519
8520 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07008521 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008522 synchronized (this) {
8523 next = mPendingWrite;
8524 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07008525 if (next == null) {
8526 return;
8527 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008528
8529 mWriteLock.lock();
8530 }
8531
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008532 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008533 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008534 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008535 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -07008536 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008537 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008538 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008539 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008540 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -07008541 mFile.rollback();
8542 } finally {
8543 next.recycle();
8544 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -07008545 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008546 }
8547
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008548 public void readLocked() {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008549 if (mDailyFile != null) {
8550 readDailyStatsLocked();
8551 }
8552
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008553 if (mFile == null) {
8554 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008555 return;
8556 }
8557
8558 mUidStats.clear();
8559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008560 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008561 File file = mFile.chooseForRead();
8562 if (!file.exists()) {
8563 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008564 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008565 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008566
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008567 byte[] raw = BatteryStatsHelper.readFully(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008568 Parcel in = Parcel.obtain();
8569 in.unmarshall(raw, 0, raw.length);
8570 in.setDataPosition(0);
8571 stream.close();
8572
8573 readSummaryFromParcel(in);
Dianne Hackborn00e25212014-02-19 10:49:24 -08008574 } catch(Exception e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008575 Slog.e("BatteryStats", "Error reading battery statistics", e);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008576 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008577
Dianne Hackborncd0e3352014-08-07 17:08:09 -07008578 mEndPlatformVersion = Build.ID;
8579
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008580 if (mHistoryBuffer.dataPosition() > 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008581 mRecordingHistory = true;
Dianne Hackborn40c87252014-03-19 16:55:40 -07008582 final long elapsedRealtime = SystemClock.elapsedRealtime();
8583 final long uptime = SystemClock.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008584 if (USE_OLD_HISTORY) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008585 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008586 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008587 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
8588 startRecordingHistory(elapsedRealtime, uptime, false);
Dianne Hackborne8c88e62011-08-17 19:09:09 -07008589 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008590
8591 recordDailyStatsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008592 }
8593
8594 public int describeContents() {
8595 return 0;
8596 }
8597
Dianne Hackbornae384452011-06-28 12:33:48 -07008598 void readHistory(Parcel in, boolean andOldHistory) {
8599 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008600
8601 mHistoryBuffer.setDataSize(0);
8602 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008603 mHistoryTagPool.clear();
8604 mNextHistoryTagIdx = 0;
8605 mNumHistoryTagChars = 0;
Dianne Hackborn099bc622014-01-22 13:39:16 -08008606
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008607 int numTags = in.readInt();
8608 for (int i=0; i<numTags; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08008609 int idx = in.readInt();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008610 String str = in.readString();
8611 int uid = in.readInt();
8612 HistoryTag tag = new HistoryTag();
8613 tag.string = str;
8614 tag.uid = uid;
8615 tag.poolIdx = idx;
8616 mHistoryTagPool.put(tag, idx);
8617 if (idx >= mNextHistoryTagIdx) {
8618 mNextHistoryTagIdx = idx+1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08008619 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008620 mNumHistoryTagChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08008621 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008622
8623 int bufSize = in.readInt();
8624 int curPos = in.dataPosition();
8625 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
8626 Slog.w(TAG, "File corrupt: history data buffer too large " + bufSize);
8627 } else if ((bufSize&~3) != bufSize) {
8628 Slog.w(TAG, "File corrupt: history data buffer not aligned " + bufSize);
8629 } else {
8630 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
8631 + " bytes at " + curPos);
8632 mHistoryBuffer.appendFrom(in, curPos, bufSize);
8633 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008634 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008635
Dianne Hackbornae384452011-06-28 12:33:48 -07008636 if (andOldHistory) {
8637 readOldHistory(in);
8638 }
8639
8640 if (DEBUG_HISTORY) {
8641 StringBuilder sb = new StringBuilder(128);
8642 sb.append("****************** OLD mHistoryBaseTime: ");
8643 TimeUtils.formatDuration(mHistoryBaseTime, sb);
8644 Slog.i(TAG, sb.toString());
8645 }
8646 mHistoryBaseTime = historyBaseTime;
8647 if (DEBUG_HISTORY) {
8648 StringBuilder sb = new StringBuilder(128);
8649 sb.append("****************** NEW mHistoryBaseTime: ");
8650 TimeUtils.formatDuration(mHistoryBaseTime, sb);
8651 Slog.i(TAG, sb.toString());
8652 }
8653
8654 // We are just arbitrarily going to insert 1 minute from the sample of
8655 // the last run until samples in this run.
8656 if (mHistoryBaseTime > 0) {
8657 long oldnow = SystemClock.elapsedRealtime();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008658 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1;
Dianne Hackbornae384452011-06-28 12:33:48 -07008659 if (DEBUG_HISTORY) {
8660 StringBuilder sb = new StringBuilder(128);
8661 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
8662 TimeUtils.formatDuration(mHistoryBaseTime, sb);
8663 Slog.i(TAG, sb.toString());
8664 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -07008665 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008666 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008667
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008668 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07008669 if (!USE_OLD_HISTORY) {
8670 return;
8671 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008672 mHistory = mHistoryEnd = mHistoryCache = null;
8673 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -07008674 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008675 HistoryItem rec = new HistoryItem(time, in);
8676 addHistoryRecordLocked(rec);
8677 }
8678 }
8679
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008680 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) {
Dianne Hackbornae384452011-06-28 12:33:48 -07008681 if (DEBUG_HISTORY) {
8682 StringBuilder sb = new StringBuilder(128);
8683 sb.append("****************** WRITING mHistoryBaseTime: ");
8684 TimeUtils.formatDuration(mHistoryBaseTime, sb);
Dianne Hackborn40c87252014-03-19 16:55:40 -07008685 sb.append(" mLastHistoryElapsedRealtime: ");
8686 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
Dianne Hackbornae384452011-06-28 12:33:48 -07008687 Slog.i(TAG, sb.toString());
8688 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07008689 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008690 if (!inclData) {
8691 out.writeInt(0);
8692 out.writeInt(0);
8693 return;
8694 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008695 out.writeInt(mHistoryTagPool.size());
8696 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
8697 HistoryTag tag = ent.getKey();
Dianne Hackborn099bc622014-01-22 13:39:16 -08008698 out.writeInt(ent.getValue());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08008699 out.writeString(tag.string);
8700 out.writeInt(tag.uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08008701 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008702 out.writeInt(mHistoryBuffer.dataSize());
8703 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
8704 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
8705 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -07008706
8707 if (andOldHistory) {
8708 writeOldHistory(out);
8709 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008710 }
8711
8712 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -07008713 if (!USE_OLD_HISTORY) {
8714 return;
8715 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008716 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07008717 while (rec != null) {
8718 if (rec.time >= 0) rec.writeToParcel(out, 0);
8719 rec = rec.next;
8720 }
8721 out.writeLong(-1);
8722 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008723
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008724 public void readSummaryFromParcel(Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008725 final int version = in.readInt();
8726 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008727 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008728 + ", expected " + VERSION + "; erasing old stats");
8729 return;
8730 }
8731
Dianne Hackbornae384452011-06-28 12:33:48 -07008732 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008734 mStartCount = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008735 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008736 mRealtime = in.readLong();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08008737 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07008738 mStartPlatformVersion = in.readString();
8739 mEndPlatformVersion = in.readString();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008740 mOnBatteryTimeBase.readSummaryFromParcel(in);
8741 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008742 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008743 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07008744 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008745 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008746 mLowDischargeAmountSinceCharge = in.readInt();
8747 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008748 mDischargeAmountScreenOnSinceCharge = in.readInt();
8749 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008750 mDischargeStepTracker.readFromParcel(in);
8751 mChargeStepTracker.readFromParcel(in);
8752 mDailyDischargeStepTracker.readFromParcel(in);
8753 mDailyChargeStepTracker.readFromParcel(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008754 int NPKG = in.readInt();
8755 if (NPKG > 0) {
8756 mDailyPackageChanges = new ArrayList<>(NPKG);
8757 while (NPKG > 0) {
8758 NPKG--;
8759 PackageChange pc = new PackageChange();
8760 pc.mPackageName = in.readString();
8761 pc.mUpdate = in.readInt() != 0;
8762 pc.mVersionCode = in.readInt();
8763 mDailyPackageChanges.add(pc);
8764 }
8765 } else {
8766 mDailyPackageChanges = null;
8767 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008768 mDailyStartTime = in.readLong();
8769 mNextMinDailyDeadline = in.readLong();
8770 mNextMaxDailyDeadline = in.readLong();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008771
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008772 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008773
Jeff Browne95c3cd2014-05-02 16:59:26 -07008774 mScreenState = Display.STATE_UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008775 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07008776 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
8777 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
8778 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07008779 mInteractive = false;
8780 mInteractiveTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008781 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07008782 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in);
8783 mDeviceIdleModeEnabledTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008784 mDeviceIdlingTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008785 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -08008786 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07008787 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
8788 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07008789 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -07008790 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
8791 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
8792 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008793 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08008794 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
8795 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008796 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008797 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08008798 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08008799 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008800 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08008801 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
8802 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
The Android Open Source Project10592532009-03-18 17:39:46 -07008803 mWifiOn = false;
8804 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008805 mGlobalWifiRunning = false;
8806 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08008807 for (int i=0; i<NUM_WIFI_STATES; i++) {
8808 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
8809 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07008810 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
8811 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in);
8812 }
8813 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
8814 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
8815 }
The Android Open Source Project10592532009-03-18 17:39:46 -07008816 mBluetoothOn = false;
8817 mBluetoothOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08008818 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
8819 mBluetoothStateTimer[i].readSummaryFromParcelLocked(in);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08008820 }
Adam Lesinski33dac552015-03-09 15:24:48 -07008821
8822 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
8823 mBluetoothActivityCounters[i].readSummaryFromParcelLocked(in);
8824 }
8825
8826 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
8827 mWifiActivityCounters[i].readSummaryFromParcelLocked(in);
8828 }
8829
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008830 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
Dianne Hackbornabc7c492014-06-30 16:57:46 -07008831 mFlashlightOn = false;
8832 mFlashlightOnTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008833
Evan Millarc64edde2009-04-18 12:26:32 -07008834 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008835 if (NKW > 10000) {
8836 Slog.w(TAG, "File corrupt: too many kernel wake locks " + NKW);
8837 return;
8838 }
Evan Millarc64edde2009-04-18 12:26:32 -07008839 for (int ikw = 0; ikw < NKW; ikw++) {
8840 if (in.readInt() != 0) {
8841 String kwltName = in.readString();
8842 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
8843 }
8844 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07008845
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008846 int NWR = in.readInt();
8847 if (NWR > 10000) {
8848 Slog.w(TAG, "File corrupt: too many wakeup reasons " + NWR);
8849 return;
8850 }
8851 for (int iwr = 0; iwr < NWR; iwr++) {
8852 if (in.readInt() != 0) {
8853 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07008854 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008855 }
8856 }
8857
Amith Yamasanie43530a2009-08-21 13:11:37 -07008858 sNumSpeedSteps = in.readInt();
Dianne Hackborn00e25212014-02-19 10:49:24 -08008859 if (sNumSpeedSteps < 0 || sNumSpeedSteps > 100) {
8860 throw new BadParcelableException("Bad speed steps in data: " + sNumSpeedSteps);
8861 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07008862
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008863 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008864 if (NU > 10000) {
8865 Slog.w(TAG, "File corrupt: too many uids " + NU);
8866 return;
8867 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008868 for (int iu = 0; iu < NU; iu++) {
8869 int uid = in.readInt();
8870 Uid u = new Uid(uid);
8871 mUidStats.put(uid, u);
8872
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008873 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008874 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008875 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008876 }
The Android Open Source Project10592532009-03-18 17:39:46 -07008877 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008878 if (in.readInt() != 0) {
8879 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
8880 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07008881 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008882 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07008883 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008884 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07008885 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
8886 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
8887 if (in.readInt() != 0) {
8888 u.makeWifiBatchedScanBin(i, null);
8889 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
8890 }
8891 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07008892 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008893 if (in.readInt() != 0) {
8894 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
8895 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008896 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08008897 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008898 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008899 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08008900 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
8901 }
8902 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07008903 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
8904 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07008905 u.mProcessState = Uid.PROCESS_STATE_NONE;
8906 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
8907 if (in.readInt() != 0) {
8908 u.makeProcessState(i, null);
8909 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in);
8910 }
8911 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07008912 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08008913 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008914 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07008915
Dianne Hackborn617f8772009-03-31 15:04:46 -07008916 if (in.readInt() != 0) {
8917 if (u.mUserActivityCounters == null) {
8918 u.initUserActivityLocked();
8919 }
8920 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
8921 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
8922 }
8923 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008924
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008925 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08008926 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008927 u.initNetworkActivityLocked();
8928 }
8929 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08008930 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
8931 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008932 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08008933 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
8934 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008935 }
8936
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008937 int NW = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08008938 if (NW > 100) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008939 Slog.w(TAG, "File corrupt: too many wake locks " + NW);
8940 return;
8941 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008942 for (int iw = 0; iw < NW; iw++) {
8943 String wlName = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07008944 u.readWakeSummaryFromParcelLocked(wlName, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008945 }
8946
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008947 int NS = in.readInt();
8948 if (NS > 100) {
8949 Slog.w(TAG, "File corrupt: too many syncs " + NS);
8950 return;
8951 }
8952 for (int is = 0; is < NS; is++) {
8953 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07008954 u.readSyncSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008955 }
8956
8957 int NJ = in.readInt();
8958 if (NJ > 100) {
8959 Slog.w(TAG, "File corrupt: too many job timers " + NJ);
8960 return;
8961 }
8962 for (int ij = 0; ij < NJ; ij++) {
8963 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -07008964 u.readJobSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008965 }
8966
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008967 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08008968 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008969 Slog.w(TAG, "File corrupt: too many sensors " + NP);
8970 return;
8971 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008972 for (int is = 0; is < NP; is++) {
8973 int seNumber = in.readInt();
8974 if (in.readInt() != 0) {
8975 u.getSensorTimerLocked(seNumber, true)
8976 .readSummaryFromParcelLocked(in);
8977 }
8978 }
8979
8980 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08008981 if (NP > 1000) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008982 Slog.w(TAG, "File corrupt: too many processes " + NP);
8983 return;
8984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008985 for (int ip = 0; ip < NP; ip++) {
8986 String procName = in.readString();
8987 Uid.Proc p = u.getProcessStatsLocked(procName);
8988 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008989 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -07008990 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008991 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008992 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt();
8993 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008994 int NSB = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08008995 if (NSB > 100) {
8996 Slog.w(TAG, "File corrupt: too many speed bins " + NSB);
8997 return;
8998 }
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07008999 p.mSpeedBins = new SamplingCounter[NSB];
9000 for (int i=0; i<NSB; i++) {
9001 if (in.readInt() != 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009002 p.mSpeedBins[i] = new SamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009003 p.mSpeedBins[i].readSummaryFromParcelLocked(in);
9004 }
9005 }
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009006 if (!p.readExcessivePowerFromParcelLocked(in)) {
9007 return;
9008 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009009 }
9010
9011 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009012 if (NP > 10000) {
9013 Slog.w(TAG, "File corrupt: too many packages " + NP);
9014 return;
9015 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009016 for (int ip = 0; ip < NP; ip++) {
9017 String pkgName = in.readString();
9018 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009019 final int NWA = in.readInt();
9020 if (NWA > 1000) {
9021 Slog.w(TAG, "File corrupt: too many wakeup alarms " + NWA);
9022 return;
9023 }
9024 p.mWakeupAlarms.clear();
9025 for (int iwa=0; iwa<NWA; iwa++) {
9026 String tag = in.readString();
9027 Counter c = new Counter(mOnBatteryTimeBase);
9028 c.readSummaryFromParcelLocked(in);
9029 p.mWakeupAlarms.put(tag, c);
9030 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009031 NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08009032 if (NS > 1000) {
9033 Slog.w(TAG, "File corrupt: too many services " + NS);
9034 return;
9035 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009036 for (int is = 0; is < NS; is++) {
9037 String servName = in.readString();
9038 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
9039 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009040 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009041 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009042 }
9043 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009044 }
9045 }
9046
9047 /**
9048 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
9049 * disk. This format does not allow a lossless round-trip.
9050 *
9051 * @param out the Parcel to be written to.
9052 */
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009053 public void writeSummaryToParcel(Parcel out, boolean inclHistory) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009054 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009055
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009056 // Pull the clock time. This may update the time and make a new history entry
9057 // if we had originally pulled a time before the RTC was set.
9058 long startClockTime = getStartClockTime();
9059
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009060 final long NOW_SYS = SystemClock.uptimeMillis() * 1000;
9061 final long NOWREAL_SYS = SystemClock.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009062
9063 out.writeInt(VERSION);
9064
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009065 writeHistory(out, inclHistory, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009066
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009067 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009068 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009069 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009070 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009071 out.writeString(mStartPlatformVersion);
9072 out.writeString(mEndPlatformVersion);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009073 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
9074 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009075 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009076 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07009077 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009078 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborne4a59512010-12-07 11:08:07 -08009079 out.writeInt(getLowDischargeAmountSinceCharge());
9080 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009081 out.writeInt(getDischargeAmountScreenOnSinceCharge());
9082 out.writeInt(getDischargeAmountScreenOffSinceCharge());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009083 mDischargeStepTracker.writeToParcel(out);
9084 mChargeStepTracker.writeToParcel(out);
9085 mDailyDischargeStepTracker.writeToParcel(out);
9086 mDailyChargeStepTracker.writeToParcel(out);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009087 if (mDailyPackageChanges != null) {
9088 final int NPKG = mDailyPackageChanges.size();
9089 out.writeInt(NPKG);
9090 for (int i=0; i<NPKG; i++) {
9091 PackageChange pc = mDailyPackageChanges.get(i);
9092 out.writeString(pc.mPackageName);
9093 out.writeInt(pc.mUpdate ? 1 : 0);
9094 out.writeInt(pc.mVersionCode);
9095 }
9096 } else {
9097 out.writeInt(0);
9098 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009099 out.writeLong(mDailyStartTime);
9100 out.writeLong(mNextMinDailyDeadline);
9101 out.writeLong(mNextMaxDailyDeadline);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009102
9103 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009104 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009105 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009106 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009107 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009108 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9109 mDeviceIdleModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009110 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009111 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Wink Saville52840902011-02-18 12:40:47 -08009112 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009113 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009114 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009115 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009116 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009117 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009118 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009119 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009120 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
9121 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009122 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009123 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9124 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009125 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009126 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
9127 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009128 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9129 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009130 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009131 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009132 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009133 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9134 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9135 }
9136 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9137 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9138 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009139 mBluetoothOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009140 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009141 mBluetoothStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009142 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009143 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9144 mBluetoothActivityCounters[i].writeSummaryFromParcelLocked(out);
9145 }
9146 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9147 mWifiActivityCounters[i].writeSummaryFromParcelLocked(out);
9148 }
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009149 out.writeInt(mNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009150 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009151
Evan Millarc64edde2009-04-18 12:26:32 -07009152 out.writeInt(mKernelWakelockStats.size());
9153 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
9154 Timer kwlt = ent.getValue();
9155 if (kwlt != null) {
9156 out.writeInt(1);
9157 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009158 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9159 } else {
9160 out.writeInt(0);
9161 }
9162 }
9163
9164 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009165 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
9166 SamplingTimer timer = ent.getValue();
9167 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009168 out.writeInt(1);
9169 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009170 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Evan Millarc64edde2009-04-18 12:26:32 -07009171 } else {
9172 out.writeInt(0);
9173 }
9174 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009175
Amith Yamasanie43530a2009-08-21 13:11:37 -07009176 out.writeInt(sNumSpeedSteps);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009177 final int NU = mUidStats.size();
9178 out.writeInt(NU);
9179 for (int iu = 0; iu < NU; iu++) {
9180 out.writeInt(mUidStats.keyAt(iu));
9181 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009182
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009183 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009184 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009185 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009186 } else {
9187 out.writeInt(0);
9188 }
9189 if (u.mFullWifiLockTimer != null) {
9190 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009191 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009192 } else {
9193 out.writeInt(0);
9194 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07009195 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009196 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009197 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009198 } else {
9199 out.writeInt(0);
9200 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07009201 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
9202 if (u.mWifiBatchedScanTimer[i] != null) {
9203 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009204 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Robert Greenwalta029ea12013-09-25 16:38:12 -07009205 } else {
9206 out.writeInt(0);
9207 }
9208 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009209 if (u.mWifiMulticastTimer != null) {
9210 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009211 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009212 } else {
9213 out.writeInt(0);
9214 }
9215 if (u.mAudioTurnedOnTimer != null) {
9216 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009217 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009218 } else {
9219 out.writeInt(0);
9220 }
9221 if (u.mVideoTurnedOnTimer != null) {
9222 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009223 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009224 } else {
9225 out.writeInt(0);
9226 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009227 if (u.mForegroundActivityTimer != null) {
9228 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009229 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07009230 } else {
9231 out.writeInt(0);
9232 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07009233 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
9234 if (u.mProcessStateTimer[i] != null) {
9235 out.writeInt(1);
9236 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9237 } else {
9238 out.writeInt(0);
9239 }
9240 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009241 if (u.mVibratorOnTimer != null) {
9242 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009243 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08009244 } else {
9245 out.writeInt(0);
9246 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009247
Dianne Hackborn617f8772009-03-31 15:04:46 -07009248 if (u.mUserActivityCounters == null) {
9249 out.writeInt(0);
9250 } else {
9251 out.writeInt(1);
9252 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
9253 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
9254 }
9255 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009256
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009257 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009258 out.writeInt(0);
9259 } else {
9260 out.writeInt(1);
9261 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009262 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
9263 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009264 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009265 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
9266 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009267 }
9268
Dianne Hackbornd953c532014-08-16 18:17:38 -07009269 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
9270 int NW = wakeStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009271 out.writeInt(NW);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009272 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009273 out.writeString(wakeStats.keyAt(iw));
9274 Uid.Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009275 if (wl.mTimerFull != null) {
9276 out.writeInt(1);
9277 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9278 } else {
9279 out.writeInt(0);
9280 }
9281 if (wl.mTimerPartial != null) {
9282 out.writeInt(1);
9283 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9284 } else {
9285 out.writeInt(0);
9286 }
9287 if (wl.mTimerWindow != null) {
9288 out.writeInt(1);
9289 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9290 } else {
9291 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009292 }
9293 }
9294
Dianne Hackbornd953c532014-08-16 18:17:38 -07009295 final ArrayMap<String, StopwatchTimer> syncStats = u.mSyncStats.getMap();
9296 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009297 out.writeInt(NS);
9298 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009299 out.writeString(syncStats.keyAt(is));
9300 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009301 }
9302
Dianne Hackbornd953c532014-08-16 18:17:38 -07009303 final ArrayMap<String, StopwatchTimer> jobStats = u.mJobStats.getMap();
9304 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009305 out.writeInt(NJ);
9306 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07009307 out.writeString(jobStats.keyAt(ij));
9308 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009309 }
9310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009311 int NSE = u.mSensorStats.size();
9312 out.writeInt(NSE);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009313 for (int ise=0; ise<NSE; ise++) {
9314 out.writeInt(u.mSensorStats.keyAt(ise));
9315 Uid.Sensor se = u.mSensorStats.valueAt(ise);
9316 if (se.mTimer != null) {
9317 out.writeInt(1);
9318 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
9319 } else {
9320 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009321 }
9322 }
9323
9324 int NP = u.mProcessStats.size();
9325 out.writeInt(NP);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009326 for (int ip=0; ip<NP; ip++) {
9327 out.writeString(u.mProcessStats.keyAt(ip));
9328 Uid.Proc ps = u.mProcessStats.valueAt(ip);
9329 out.writeLong(ps.mUserTime);
9330 out.writeLong(ps.mSystemTime);
9331 out.writeLong(ps.mForegroundTime);
9332 out.writeInt(ps.mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009333 out.writeInt(ps.mNumCrashes);
9334 out.writeInt(ps.mNumAnrs);
Dianne Hackborn61659e52014-07-09 16:13:01 -07009335 final int N = ps.mSpeedBins.length;
9336 out.writeInt(N);
9337 for (int i=0; i<N; i++) {
9338 if (ps.mSpeedBins[i] != null) {
9339 out.writeInt(1);
9340 ps.mSpeedBins[i].writeSummaryFromParcelLocked(out);
9341 } else {
9342 out.writeInt(0);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009343 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009344 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07009345 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009346 }
9347
9348 NP = u.mPackageStats.size();
9349 out.writeInt(NP);
9350 if (NP > 0) {
9351 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
9352 : u.mPackageStats.entrySet()) {
9353 out.writeString(ent.getKey());
9354 Uid.Pkg ps = ent.getValue();
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009355 final int NWA = ps.mWakeupAlarms.size();
9356 out.writeInt(NWA);
9357 for (int iwa=0; iwa<NWA; iwa++) {
9358 out.writeString(ps.mWakeupAlarms.keyAt(iwa));
9359 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out);
9360 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009361 NS = ps.mServiceStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009362 out.writeInt(NS);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07009363 for (int is=0; is<NS; is++) {
9364 out.writeString(ps.mServiceStats.keyAt(is));
9365 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
9366 long time = ss.getStartTimeToNowLocked(
9367 mOnBatteryTimeBase.getUptime(NOW_SYS));
9368 out.writeLong(time);
9369 out.writeInt(ss.mStarts);
9370 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009371 }
9372 }
9373 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009374 }
9375 }
9376
9377 public void readFromParcel(Parcel in) {
9378 readFromParcelLocked(in);
9379 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009381 void readFromParcelLocked(Parcel in) {
9382 int magic = in.readInt();
9383 if (magic != MAGIC) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -07009384 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009385 }
9386
Dianne Hackbornae384452011-06-28 12:33:48 -07009387 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009389 mStartCount = in.readInt();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009390 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009391 mStartPlatformVersion = in.readString();
9392 mEndPlatformVersion = in.readString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009393 mUptime = in.readLong();
9394 mUptimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009395 mRealtime = in.readLong();
9396 mRealtimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009397 mOnBattery = in.readInt() != 0;
9398 mOnBatteryInternal = false; // we are no longer really running.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009399 mOnBatteryTimeBase.readFromParcel(in);
9400 mOnBatteryScreenOffTimeBase.readFromParcel(in);
9401
Jeff Browne95c3cd2014-05-02 16:59:26 -07009402 mScreenState = Display.STATE_UNKNOWN;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009403 mScreenOnTimer = new StopwatchTimer(null, -1, null, mOnBatteryTimeBase, in);
9404 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
9405 mScreenBrightnessTimer[i] = new StopwatchTimer(null, -100-i, null, mOnBatteryTimeBase,
9406 in);
9407 }
Dianne Hackborn29325132014-05-21 15:01:03 -07009408 mInteractive = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009409 mInteractiveTimer = new StopwatchTimer(null, -10, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009410 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009411 mPowerSaveModeEnabledTimer = new StopwatchTimer(null, -2, null, mOnBatteryTimeBase, in);
9412 mDeviceIdleModeEnabledTimer = new StopwatchTimer(null, -11, null, mOnBatteryTimeBase, in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009413 mDeviceIdlingTimer = new StopwatchTimer(null, -12, null, mOnBatteryTimeBase, in);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009414 mPhoneOnTimer = new StopwatchTimer(null, -3, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009415 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
9416 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(null, -200-i,
9417 null, mOnBatteryTimeBase, in);
9418 }
9419 mPhoneSignalScanningTimer = new StopwatchTimer(null, -200+1, null, mOnBatteryTimeBase, in);
9420 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
9421 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(null, -300-i,
9422 null, mOnBatteryTimeBase, in);
9423 }
9424 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
9425 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9426 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9427 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009428 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009429 mMobileRadioActiveTimer = new StopwatchTimer(null, -400, null, mOnBatteryTimeBase, in);
9430 mMobileRadioActivePerAppTimer = new StopwatchTimer(null, -401, null, mOnBatteryTimeBase,
9431 in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009432 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009433 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
9434 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
9435 mWifiOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009436 mWifiOnTimer = new StopwatchTimer(null, -4, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009437 mGlobalWifiRunning = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009438 mGlobalWifiRunningTimer = new StopwatchTimer(null, -5, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009439 for (int i=0; i<NUM_WIFI_STATES; i++) {
9440 mWifiStateTimer[i] = new StopwatchTimer(null, -600-i,
9441 null, mOnBatteryTimeBase, in);
9442 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009443 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9444 mWifiSupplStateTimer[i] = new StopwatchTimer(null, -700-i,
9445 null, mOnBatteryTimeBase, in);
9446 }
9447 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9448 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(null, -800-i,
9449 null, mOnBatteryTimeBase, in);
9450 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009451 mBluetoothOn = false;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009452 mBluetoothOnTimer = new StopwatchTimer(null, -6, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009453 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
9454 mBluetoothStateTimer[i] = new StopwatchTimer(null, -500-i,
9455 null, mOnBatteryTimeBase, in);
9456 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009457
9458 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9459 mBluetoothActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9460 }
9461
9462 for (int i = 0; i < NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9463 mWifiActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
9464 }
9465
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009466 mNumConnectivityChange = in.readInt();
9467 mLoadedNumConnectivityChange = in.readInt();
9468 mUnpluggedNumConnectivityChange = in.readInt();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07009469 mAudioOnNesting = 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009470 mAudioOnTimer = new StopwatchTimer(null, -7, null, mOnBatteryTimeBase);
Dianne Hackborn10eaa852014-07-22 22:54:55 -07009471 mVideoOnNesting = 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07009472 mVideoOnTimer = new StopwatchTimer(null, -8, null, mOnBatteryTimeBase);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009473 mFlashlightOn = false;
9474 mFlashlightOnTimer = new StopwatchTimer(null, -9, null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009475 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009476 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -07009477 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009478 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009479 mLowDischargeAmountSinceCharge = in.readInt();
9480 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009481 mDischargeAmountScreenOn = in.readInt();
9482 mDischargeAmountScreenOnSinceCharge = in.readInt();
9483 mDischargeAmountScreenOff = in.readInt();
9484 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009485 mDischargeStepTracker.readFromParcel(in);
9486 mChargeStepTracker.readFromParcel(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009487 mLastWriteTime = in.readLong();
9488
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07009489 mBluetoothPingCount = in.readInt();
9490 mBluetoothPingStart = -1;
9491
Evan Millarc64edde2009-04-18 12:26:32 -07009492 mKernelWakelockStats.clear();
9493 int NKW = in.readInt();
9494 for (int ikw = 0; ikw < NKW; ikw++) {
9495 if (in.readInt() != 0) {
9496 String wakelockName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009497 SamplingTimer kwlt = new SamplingTimer(mOnBatteryScreenOffTimeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07009498 mKernelWakelockStats.put(wakelockName, kwlt);
9499 }
9500 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009501
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009502 mWakeupReasonStats.clear();
9503 int NWR = in.readInt();
9504 for (int iwr = 0; iwr < NWR; iwr++) {
9505 if (in.readInt() != 0) {
9506 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009507 SamplingTimer timer = new SamplingTimer(mOnBatteryTimeBase, in);
9508 mWakeupReasonStats.put(reasonName, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009509 }
9510 }
9511
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009512 mPartialTimers.clear();
9513 mFullTimers.clear();
9514 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009515 mWifiRunningTimers.clear();
9516 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -07009517 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -07009518 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009519 mWifiMulticastTimers.clear();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07009520 mAudioTurnedOnTimers.clear();
9521 mVideoTurnedOnTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009522
Amith Yamasanie43530a2009-08-21 13:11:37 -07009523 sNumSpeedSteps = in.readInt();
9524
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009525 int numUids = in.readInt();
9526 mUidStats.clear();
9527 for (int i = 0; i < numUids; i++) {
9528 int uid = in.readInt();
9529 Uid u = new Uid(uid);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009530 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009531 mUidStats.append(uid, u);
9532 }
9533 }
9534
9535 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009536 writeToParcelLocked(out, true, flags);
9537 }
9538
9539 public void writeToParcelWithoutUids(Parcel out, int flags) {
9540 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009541 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009542
9543 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009544 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009545 // Need to update with current kernel wake lock counts.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009546 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009547
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009548 // Pull the clock time. This may update the time and make a new history entry
9549 // if we had originally pulled a time before the RTC was set.
9550 long startClockTime = getStartClockTime();
9551
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009552 final long uSecUptime = SystemClock.uptimeMillis() * 1000;
9553 final long uSecRealtime = SystemClock.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009554 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
9555 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009556
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009557 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009558
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009559 writeHistory(out, true, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009560
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009561 out.writeInt(mStartCount);
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009562 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009563 out.writeString(mStartPlatformVersion);
9564 out.writeString(mEndPlatformVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009565 out.writeLong(mUptime);
9566 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009567 out.writeLong(mRealtime);
9568 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009569 out.writeInt(mOnBattery ? 1 : 0);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009570 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
9571 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
9572
9573 mScreenOnTimer.writeToParcel(out, uSecRealtime);
9574 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
9575 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
9576 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009577 mInteractiveTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009578 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime);
9579 mDeviceIdleModeEnabledTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009580 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009581 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
9582 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
9583 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
9584 }
9585 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
9586 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
9587 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
9588 }
9589 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
9590 mNetworkByteActivityCounters[i].writeToParcel(out);
9591 mNetworkPacketActivityCounters[i].writeToParcel(out);
9592 }
9593 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
9594 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009595 mMobileRadioActiveAdjustedTime.writeToParcel(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009596 mMobileRadioActiveUnknownTime.writeToParcel(out);
9597 mMobileRadioActiveUnknownCount.writeToParcel(out);
9598 mWifiOnTimer.writeToParcel(out, uSecRealtime);
9599 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
9600 for (int i=0; i<NUM_WIFI_STATES; i++) {
9601 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
9602 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009603 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9604 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime);
9605 }
9606 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9607 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
9608 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009609 mBluetoothOnTimer.writeToParcel(out, uSecRealtime);
9610 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
9611 mBluetoothStateTimer[i].writeToParcel(out, uSecRealtime);
9612 }
Adam Lesinski33dac552015-03-09 15:24:48 -07009613 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9614 mBluetoothActivityCounters[i].writeToParcel(out);
9615 }
9616 for (int i=0; i< NUM_CONTROLLER_ACTIVITY_TYPES; i++) {
9617 mWifiActivityCounters[i].writeToParcel(out);
9618 }
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009619 out.writeInt(mNumConnectivityChange);
9620 out.writeInt(mLoadedNumConnectivityChange);
9621 out.writeInt(mUnpluggedNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009622 mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009623 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009624 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -07009625 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009626 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009627 out.writeInt(mLowDischargeAmountSinceCharge);
9628 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009629 out.writeInt(mDischargeAmountScreenOn);
9630 out.writeInt(mDischargeAmountScreenOnSinceCharge);
9631 out.writeInt(mDischargeAmountScreenOff);
9632 out.writeInt(mDischargeAmountScreenOffSinceCharge);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009633 mDischargeStepTracker.writeToParcel(out);
9634 mChargeStepTracker.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009635 out.writeLong(mLastWriteTime);
9636
Amith Yamasani3f7e35c2009-07-13 16:02:45 -07009637 out.writeInt(getBluetoothPingCount());
Amith Yamasani3718aaa2009-06-09 06:32:35 -07009638
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009639 if (inclUids) {
9640 out.writeInt(mKernelWakelockStats.size());
9641 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
9642 SamplingTimer kwlt = ent.getValue();
9643 if (kwlt != null) {
9644 out.writeInt(1);
9645 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009646 kwlt.writeToParcel(out, uSecRealtime);
9647 } else {
9648 out.writeInt(0);
9649 }
9650 }
9651 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009652 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
9653 SamplingTimer timer = ent.getValue();
9654 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009655 out.writeInt(1);
9656 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009657 timer.writeToParcel(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009658 } else {
9659 out.writeInt(0);
9660 }
Evan Millarc64edde2009-04-18 12:26:32 -07009661 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009662 } else {
9663 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -07009664 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07009665
9666 out.writeInt(sNumSpeedSteps);
9667
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009668 if (inclUids) {
9669 int size = mUidStats.size();
9670 out.writeInt(size);
9671 for (int i = 0; i < size; i++) {
9672 out.writeInt(mUidStats.keyAt(i));
9673 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009674
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009675 uid.writeToParcelLocked(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07009676 }
9677 } else {
9678 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009679 }
9680 }
9681
9682 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
9683 new Parcelable.Creator<BatteryStatsImpl>() {
9684 public BatteryStatsImpl createFromParcel(Parcel in) {
9685 return new BatteryStatsImpl(in);
9686 }
9687
9688 public BatteryStatsImpl[] newArray(int size) {
9689 return new BatteryStatsImpl[size];
9690 }
9691 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009692
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009693 public void prepareForDumpLocked() {
9694 // Need to retrieve current kernel wake lock stats before printing.
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009695 pullPendingStateUpdatesLocked();
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07009696
9697 // Pull the clock time. This may update the time and make a new history entry
9698 // if we had originally pulled a time before the RTC was set.
9699 getStartClockTime();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009700 }
9701
Dianne Hackbornc51cf032014-03-02 19:08:15 -08009702 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009703 if (DEBUG) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009704 pw.println("mOnBatteryTimeBase:");
9705 mOnBatteryTimeBase.dump(pw, " ");
9706 pw.println("mOnBatteryScreenOffTimeBase:");
9707 mOnBatteryScreenOffTimeBase.dump(pw, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009708 Printer pr = new PrintWriterPrinter(pw);
9709 pr.println("*** Screen timer:");
9710 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07009711 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009712 pr.println("*** Screen brightness #" + i + ":");
9713 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -07009714 }
Jeff Browne95c3cd2014-05-02 16:59:26 -07009715 pr.println("*** Interactive timer:");
9716 mInteractiveTimer.logState(pr, " ");
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009717 pr.println("*** Power save mode timer:");
9718 mPowerSaveModeEnabledTimer.logState(pr, " ");
9719 pr.println("*** Device idle mode timer:");
9720 mDeviceIdleModeEnabledTimer.logState(pr, " ");
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009721 pr.println("*** Device idling timer:");
9722 mDeviceIdlingTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009723 pr.println("*** Phone timer:");
9724 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -08009725 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3251b902014-06-20 14:40:53 -07009726 pr.println("*** Phone signal strength #" + i + ":");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009727 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07009728 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07009729 pr.println("*** Signal scanning :");
9730 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07009731 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009732 pr.println("*** Data connection type #" + i + ":");
9733 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -07009734 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009735 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009736 pr.println("*** Mobile network active timer:");
9737 mMobileRadioActiveTimer.logState(pr, " ");
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009738 pr.println("*** Mobile network active adjusted timer:");
9739 mMobileRadioActiveAdjustedTime.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009740 pr.println("*** Wifi timer:");
9741 mWifiOnTimer.logState(pr, " ");
9742 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07009743 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009744 for (int i=0; i<NUM_WIFI_STATES; i++) {
9745 pr.println("*** Wifi state #" + i + ":");
9746 mWifiStateTimer[i].logState(pr, " ");
9747 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009748 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9749 pr.println("*** Wifi suppl state #" + i + ":");
9750 mWifiSupplStateTimer[i].logState(pr, " ");
9751 }
9752 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9753 pr.println("*** Wifi signal strength #" + i + ":");
9754 mWifiSignalStrengthsTimer[i].logState(pr, " ");
9755 }
Dianne Hackborn1d442e02009-04-20 18:14:05 -07009756 pr.println("*** Bluetooth timer:");
9757 mBluetoothOnTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009758 for (int i=0; i< NUM_BLUETOOTH_STATES; i++) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009759 pr.println("*** Bluetooth active type #" + i + ":");
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009760 mBluetoothStateTimer[i].logState(pr, " ");
Dianne Hackborne13c4c02014-02-11 17:18:35 -08009761 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009762 pr.println("*** Flashlight timer:");
9763 mFlashlightOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009764 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08009765 super.dumpLocked(context, pw, flags, reqUid, histStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009766 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009767}