blob: 398fb25202d5fe6cadf546908764899027fd0486 [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
Sudheer Shanka9b735c52017-05-09 18:26:18 -070019import android.annotation.NonNull;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070020import android.annotation.Nullable;
Dianne Hackborn61659e52014-07-09 16:13:01 -070021import android.app.ActivityManager;
Adam Lesinski33dac552015-03-09 15:24:48 -070022import android.bluetooth.BluetoothActivityEnergyInfo;
Adam Lesinski50e47602015-12-04 17:04:54 -080023import android.bluetooth.UidTraffic;
Dianne Hackborna7c837f2014-01-15 16:20:44 -080024import android.content.Context;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070025import android.content.Intent;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070026import android.net.ConnectivityManager;
27import android.net.NetworkStats;
Adam Lesinski33dac552015-03-09 15:24:48 -070028import android.net.wifi.WifiActivityEnergyInfo;
Dianne Hackborn3251b902014-06-20 14:40:53 -070029import android.net.wifi.WifiManager;
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;
Adam Lesinskie1f480d2017-02-15 18:51:23 -080035import android.os.IBatteryPropertiesRegistrar;
Jeff Brown6f357d32014-01-15 20:40:55 -080036import android.os.Looper;
Dianne Hackborn0d903a82010-09-07 23:51:03 -070037import android.os.Message;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.os.Parcel;
39import android.os.ParcelFormatException;
40import android.os.Parcelable;
Evan Millarc64edde2009-04-18 12:26:32 -070041import android.os.Process;
Adam Lesinskie1f480d2017-02-15 18:51:23 -080042import android.os.RemoteException;
43import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.os.SystemClock;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070045import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070046import android.os.WorkSource;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070047import android.telephony.DataConnectionRealTimeInfo;
Adam Lesinski21f76aa2016-01-25 12:27:06 -080048import android.telephony.ModemActivityInfo;
Amith Yamasanif37447b2009-10-08 18:28:01 -070049import android.telephony.ServiceState;
Wink Savillee9b06d72009-05-18 21:47:50 -070050import android.telephony.SignalStrength;
Dianne Hackborn627bba72009-03-24 22:32:56 -070051import android.telephony.TelephonyManager;
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -070052import android.text.TextUtils;
Dianne Hackborn61659e52014-07-09 16:13:01 -070053import android.util.ArrayMap;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.util.Log;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070055import android.util.LogWriter;
James Carr3a226052016-07-01 14:49:52 -070056import android.util.LongSparseArray;
57import android.util.LongSparseLongArray;
Dianne Hackbornd953c532014-08-16 18:17:38 -070058import android.util.MutableInt;
Adam Lesinski14ae39a2017-05-26 11:50:40 -070059import android.util.Pools;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070060import android.util.PrintWriterPrinter;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080061import android.util.Printer;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070062import android.util.Slog;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080063import android.util.SparseArray;
Dianne Hackborn099bc622014-01-22 13:39:16 -080064import android.util.SparseIntArray;
Adam Lesinskie08af192015-03-25 16:42:59 -070065import android.util.SparseLongArray;
Dianne Hackbornae384452011-06-28 12:33:48 -070066import android.util.TimeUtils;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080067import android.util.Xml;
Jeff Browne95c3cd2014-05-02 16:59:26 -070068import android.view.Display;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080069
Adam Lesinski14ae39a2017-05-26 11:50:40 -070070import com.android.internal.annotations.GuardedBy;
Adam Lesinski98f0d462016-04-19 16:46:20 -070071import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070072import com.android.internal.net.NetworkStatsFactory;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080073import com.android.internal.util.ArrayUtils;
Dianne Hackborn8c841092013-06-24 13:46:13 -070074import com.android.internal.util.FastPrintWriter;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080075import com.android.internal.util.FastXmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070076import com.android.internal.util.JournaledFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080077import com.android.internal.util.XmlUtils;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070078
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070079import libcore.util.EmptyArray;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080080import org.xmlpull.v1.XmlPullParser;
81import org.xmlpull.v1.XmlPullParserException;
82import org.xmlpull.v1.XmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070083
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080084import java.io.ByteArrayOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080085import java.io.File;
86import java.io.FileInputStream;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080087import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088import java.io.FileOutputStream;
89import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070090import java.io.PrintWriter;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +010091import java.nio.charset.StandardCharsets;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080092import java.util.ArrayList;
Sudheer Shanka9b735c52017-05-09 18:26:18 -070093import java.util.Arrays;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080094import java.util.Calendar;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070096import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097import java.util.Map;
Adam Lesinskib3a1bad2017-05-26 11:50:40 -070098import java.util.concurrent.Future;
Christopher Tate4cee7252010-03-19 14:50:40 -070099import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -0700100import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800101
102/**
103 * All information we are collecting about things that can happen that impact
104 * battery life. All times are represented in microseconds except where indicated
105 * otherwise.
106 */
Joe Onoratoabded112016-02-08 16:49:39 -0800107public class BatteryStatsImpl extends BatteryStats {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 private static final String TAG = "BatteryStatsImpl";
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800109 private static final boolean DEBUG = false;
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700110 public static final boolean DEBUG_ENERGY = false;
Adam Lesinski50e47602015-12-04 17:04:54 -0800111 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY;
James Carr3a226052016-07-01 14:49:52 -0700112 private static final boolean DEBUG_MEMORY = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700113 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -0700114 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700115
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700116 // TODO: remove "tcp" from network methods, since we measure total stats.
117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800118 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700119 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120
121 // Current on-disk Parcel version
Sudheer Shanka2fc52d42017-06-16 17:29:19 -0700122 private static final int VERSION = 162 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700123
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700124 // Maximum number of items we will record in the history.
Narayan Kamathb59b7c32017-06-12 14:11:03 +0100125 private static final int MAX_HISTORY_ITEMS;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700126
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700127 // No, really, THIS is the maximum number of items we will record in the history.
Narayan Kamathb59b7c32017-06-12 14:11:03 +0100128 private static final int MAX_MAX_HISTORY_ITEMS;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700129
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800130 // The maximum number of names wakelocks we will keep track of
131 // per uid; once the limit is reached, we batch the remaining wakelocks
132 // in to one common name.
Narayan Kamathb59b7c32017-06-12 14:11:03 +0100133 private static final int MAX_WAKELOCKS_PER_UID;
134
135 static final int MAX_HISTORY_BUFFER; // 256KB
136 static final int MAX_MAX_HISTORY_BUFFER; // 320KB
137
138 static {
139 if (ActivityManager.isLowRamDeviceStatic()) {
140 MAX_HISTORY_ITEMS = 800;
141 MAX_MAX_HISTORY_ITEMS = 1200;
142 MAX_WAKELOCKS_PER_UID = 40;
143 MAX_HISTORY_BUFFER = 96*1024; // 96KB
144 MAX_MAX_HISTORY_BUFFER = 128*1024; // 128KB
145 } else {
146 MAX_HISTORY_ITEMS = 2000;
147 MAX_MAX_HISTORY_ITEMS = 3000;
148 MAX_WAKELOCKS_PER_UID = 100;
149 MAX_HISTORY_BUFFER = 256*1024; // 256KB
150 MAX_MAX_HISTORY_BUFFER = 320*1024; // 256KB
151 }
152 }
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700153
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800154 // Number of transmit power states the Wifi controller can be in.
155 private static final int NUM_WIFI_TX_LEVELS = 1;
156
157 // Number of transmit power states the Bluetooth controller can be in.
158 private static final int NUM_BT_TX_LEVELS = 1;
159
Joe Onoratoabded112016-02-08 16:49:39 -0800160 protected Clocks mClocks;
161
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700162 private final JournaledFile mFile;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700163 public final AtomicFile mCheckinFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800164 public final AtomicFile mDailyFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800165
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700166 static final int MSG_UPDATE_WAKELOCKS = 1;
167 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700168 static final int MSG_REPORT_CHARGING = 3;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700169 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700170
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700171 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
172 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
173
Adam Lesinski06af1fa2015-05-05 17:35:35 -0700174 private final KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
Adam Lesinski6832f392015-09-05 18:05:40 -0700175 private KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
Sudheer Shanka9b735c52017-05-09 18:26:18 -0700176 private final KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader =
177 new KernelUidCpuFreqTimeReader();
Adam Lesinski06af1fa2015-05-05 17:35:35 -0700178
James Carr3a226052016-07-01 14:49:52 -0700179 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats
180 = new KernelMemoryBandwidthStats();
181 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>();
182 public LongSparseArray<SamplingTimer> getKernelMemoryStats() {
183 return mKernelMemoryStats;
184 }
185
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700186 public interface BatteryCallback {
187 public void batteryNeedsCpuUpdate();
188 public void batteryPowerChanged(boolean onBattery);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700189 public void batterySendBroadcast(Intent intent);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700190 }
191
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700192 public interface PlatformIdleStateCallback {
193 public String getPlatformLowPowerStats();
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +0000194 public String getSubsystemLowPowerStats();
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700195 }
196
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700197 public static abstract class UserInfoProvider {
198 private int[] userIds;
199 protected abstract @Nullable int[] getUserIds();
200 private final void refreshUserIds() {
201 userIds = getUserIds();
202 }
203 private final boolean exists(int userId) {
204 return userIds != null ? ArrayUtils.contains(userIds, userId) : true;
205 }
206 }
207
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700208 private final PlatformIdleStateCallback mPlatformIdleStateCallback;
209
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700210 final class MyHandler extends Handler {
Jeff Brown6f357d32014-01-15 20:40:55 -0800211 public MyHandler(Looper looper) {
212 super(looper, null, true);
213 }
214
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700215 @Override
216 public void handleMessage(Message msg) {
217 BatteryCallback cb = mCallback;
218 switch (msg.what) {
219 case MSG_UPDATE_WAKELOCKS:
Adam Lesinski72478f02015-06-17 15:39:43 -0700220 synchronized (BatteryStatsImpl.this) {
Sudheer Shanka671985f2017-05-19 11:33:42 -0700221 updateCpuTimeLocked(false /* updateCpuFreqData */);
Adam Lesinski72478f02015-06-17 15:39:43 -0700222 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700223 if (cb != null) {
224 cb.batteryNeedsCpuUpdate();
225 }
226 break;
227 case MSG_REPORT_POWER_CHANGE:
228 if (cb != null) {
229 cb.batteryPowerChanged(msg.arg1 != 0);
230 }
231 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700232 case MSG_REPORT_CHARGING:
233 if (cb != null) {
234 final String action;
235 synchronized (BatteryStatsImpl.this) {
236 action = mCharging ? BatteryManager.ACTION_CHARGING
237 : BatteryManager.ACTION_DISCHARGING;
238 }
239 Intent intent = new Intent(action);
240 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
241 cb.batterySendBroadcast(intent);
242 }
243 break;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700244 }
245 }
246 }
247
Joe Onoratoabded112016-02-08 16:49:39 -0800248 public interface Clocks {
249 public long elapsedRealtime();
250 public long uptimeMillis();
251 }
252
253 public static class SystemClocks implements Clocks {
254 public long elapsedRealtime() {
255 return SystemClock.elapsedRealtime();
256 }
257
258 public long uptimeMillis() {
259 return SystemClock.uptimeMillis();
260 }
261 }
262
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700263 public interface ExternalStatsSync {
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700264 int UPDATE_CPU = 0x01;
265 int UPDATE_WIFI = 0x02;
266 int UPDATE_RADIO = 0x04;
267 int UPDATE_BT = 0x08;
268 int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT;
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800269
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700270 Future<?> scheduleSync(String reason, int flags);
271 Future<?> scheduleCpuSyncDueToRemovedUid(int uid);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700272 }
273
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700274 public final MyHandler mHandler;
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700275 private ExternalStatsSync mExternalSync = null;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700276 private UserInfoProvider mUserInfoProvider = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700277
278 private BatteryCallback mCallback;
279
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -0800281 * Mapping isolated uids to the actual owning app uid.
282 */
283 final SparseIntArray mIsolatedUids = new SparseIntArray();
284
285 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286 * The statistics we have collected organized by uids.
287 */
Adam Lesinski50e47602015-12-04 17:04:54 -0800288 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289
290 // A set of pools of currently active timers. When a timer is queried, we will divide the
291 // elapsed time by the number of active timers to arrive at that timer's share of the time.
292 // In order to do this, we must refresh each timer whenever the number of active timers
293 // changes.
Adam Lesinskie08af192015-03-25 16:42:59 -0700294 final ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
295 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
296 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
Jeff Brown6a8bd7b2015-06-19 15:07:51 -0700297 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>();
Adam Lesinskie08af192015-03-25 16:42:59 -0700298 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
299 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
300 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
301 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
302 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
303 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
304 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
305 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700306 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>();
307 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>();
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800308 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800309
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700310 // Last partial timers we use for distributing CPU usage.
Adam Lesinskie08af192015-03-25 16:42:59 -0700311 final ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 // These are the objects that will want to do something when the device
314 // is unplugged from power.
Joe Onoratoabded112016-02-08 16:49:39 -0800315 protected final TimeBase mOnBatteryTimeBase = new TimeBase();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800316
317 // These are the objects that will want to do something when the device
318 // is unplugged from power *and* the screen is off.
319 final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
320
321 // Set to true when we want to distribute CPU across wakelocks for the next
322 // CPU update, even if we aren't currently running wake locks.
323 boolean mDistributeWakelockCpu;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700324
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700325 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700326
Dianne Hackborn37de0982014-05-09 09:32:18 -0700327 final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800328
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700329 long mHistoryBaseTime;
330 boolean mHaveBatteryLevel = false;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700331 boolean mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700332 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700333
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700334 final Parcel mHistoryBuffer = Parcel.obtain();
335 final HistoryItem mHistoryLastWritten = new HistoryItem();
336 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700337 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700338 final HistoryItem mHistoryAddTmp = new HistoryItem();
Adam Lesinskie08af192015-03-25 16:42:59 -0700339 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
Dianne Hackborn099bc622014-01-22 13:39:16 -0800340 String[] mReadHistoryStrings;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800341 int[] mReadHistoryUids;
342 int mReadHistoryChars;
343 int mNextHistoryTagIdx = 0;
344 int mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700345 int mHistoryBufferLastPos = -1;
346 boolean mHistoryOverflow = false;
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700347 int mActiveHistoryStates = 0xffffffff;
348 int mActiveHistoryStates2 = 0xffffffff;
Dianne Hackborn40c87252014-03-19 16:55:40 -0700349 long mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700350 long mTrackRunningHistoryElapsedRealtime = 0;
351 long mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700352
353 final HistoryItem mHistoryCur = new HistoryItem();
354
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700355 HistoryItem mHistory;
356 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700357 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700358 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700359
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800360 // Used by computeHistoryStepDetails
361 HistoryStepDetails mLastHistoryStepDetails = null;
362 byte mLastHistoryStepLevel = 0;
363 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
364 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails();
365 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700366
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800367 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700368 * Total time (in milliseconds) spent executing in user code.
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800369 */
370 long mLastStepCpuUserTime;
371 long mCurStepCpuUserTime;
372 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700373 * Total time (in milliseconds) spent executing in kernel code.
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800374 */
375 long mLastStepCpuSystemTime;
376 long mCurStepCpuSystemTime;
377 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700378 * Times from /proc/stat (but measured in milliseconds).
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800379 */
380 long mLastStepStatUserTime;
381 long mLastStepStatSystemTime;
382 long mLastStepStatIOWaitTime;
383 long mLastStepStatIrqTime;
384 long mLastStepStatSoftIrqTime;
385 long mLastStepStatIdleTime;
386 long mCurStepStatUserTime;
387 long mCurStepStatSystemTime;
388 long mCurStepStatIOWaitTime;
389 long mCurStepStatIrqTime;
390 long mCurStepStatSoftIrqTime;
391 long mCurStepStatIdleTime;
392
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700393 private HistoryItem mHistoryIterator;
394 private boolean mReadOverflow;
395 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700396
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397 int mStartCount;
398
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800399 long mStartClockTime;
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700400 String mStartPlatformVersion;
401 String mEndPlatformVersion;
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800402
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 long mUptime;
404 long mUptimeStart;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800405 long mRealtime;
406 long mRealtimeStart;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700407
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800408 int mWakeLockNesting;
409 boolean mWakeLockImportant;
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700410 public boolean mRecordAllHistory;
Dianne Hackborn9a755432014-05-15 17:05:22 -0700411 boolean mNoAutoReset;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800412
Jeff Browne95c3cd2014-05-02 16:59:26 -0700413 int mScreenState = Display.STATE_UNKNOWN;
Evan Millarc64edde2009-04-18 12:26:32 -0700414 StopwatchTimer mScreenOnTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700415
Dianne Hackborn617f8772009-03-31 15:04:46 -0700416 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700417 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700418
Amith Yamasani674c9bb2017-02-01 09:45:17 -0800419 boolean mPretendScreenOff;
420
Jeff Browne95c3cd2014-05-02 16:59:26 -0700421 boolean mInteractive;
422 StopwatchTimer mInteractiveTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700423
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700424 boolean mPowerSaveModeEnabled;
425 StopwatchTimer mPowerSaveModeEnabledTimer;
426
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700427 boolean mDeviceIdling;
428 StopwatchTimer mDeviceIdlingTimer;
429
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700430 boolean mDeviceLightIdling;
431 StopwatchTimer mDeviceLightIdlingTimer;
432
433 int mDeviceIdleMode;
434 long mLastIdleTimeStart;
435 long mLongestLightIdleTime;
436 long mLongestFullIdleTime;
437 StopwatchTimer mDeviceIdleModeLightTimer;
438 StopwatchTimer mDeviceIdleModeFullTimer;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700439
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800440 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700441 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700442
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700443 int mAudioOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700444 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700445
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700446 int mVideoOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700447 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700448
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700449 int mFlashlightOnNesting;
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700450 StopwatchTimer mFlashlightOnTimer;
451
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700452 int mCameraOnNesting;
453 StopwatchTimer mCameraOnTimer;
454
Dianne Hackborn627bba72009-03-24 22:32:56 -0700455 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800456 int mPhoneSignalStrengthBinRaw = -1;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700457 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800458 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700459
460 StopwatchTimer mPhoneSignalScanningTimer;
461
Dianne Hackborn627bba72009-03-24 22:32:56 -0700462 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700463 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700464 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700465
Dianne Hackborn57ed6a62013-12-09 18:15:56 -0800466 final LongSamplingCounter[] mNetworkByteActivityCounters =
467 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
468 final LongSamplingCounter[] mNetworkPacketActivityCounters =
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700469 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
470
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800471 /**
472 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device.
473 */
474 ControllerActivityCounterImpl mWifiActivity;
Adam Lesinski33dac552015-03-09 15:24:48 -0700475
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800476 /**
477 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device.
478 */
479 ControllerActivityCounterImpl mBluetoothActivity;
480
481 /**
482 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device.
483 */
484 ControllerActivityCounterImpl mModemActivity;
485
486 /**
487 * Whether the device supports WiFi controller energy reporting. This is set to true on
488 * the first WiFi energy report. See {@link #mWifiActivity}.
489 */
490 boolean mHasWifiReporting = false;
491
492 /**
493 * Whether the device supports Bluetooth controller energy reporting. This is set to true on
494 * the first Bluetooth energy report. See {@link #mBluetoothActivity}.
495 */
496 boolean mHasBluetoothReporting = false;
497
498 /**
499 * Whether the device supports Modem controller energy reporting. This is set to true on
500 * the first Modem energy report. See {@link #mModemActivity}.
501 */
502 boolean mHasModemReporting = false;
Adam Lesinski33dac552015-03-09 15:24:48 -0700503
The Android Open Source Project10592532009-03-18 17:39:46 -0700504 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700505 StopwatchTimer mWifiOnTimer;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700506
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700507 boolean mGlobalWifiRunning;
508 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700509
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800510 int mWifiState = -1;
511 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
512
Dianne Hackborn3251b902014-06-20 14:40:53 -0700513 int mWifiSupplState = -1;
514 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES];
515
516 int mWifiSignalStrengthBin = -1;
517 final StopwatchTimer[] mWifiSignalStrengthsTimer =
518 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS];
519
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800520 int mBluetoothScanNesting;
Bookatz867c0d72017-03-07 18:23:42 -0800521 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
522 protected StopwatchTimer mBluetoothScanTimer;
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800523
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700524 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackbornf7097a52014-05-13 09:56:14 -0700525 long mMobileRadioActiveStartTime;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800526 StopwatchTimer mMobileRadioActiveTimer;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800527 StopwatchTimer mMobileRadioActivePerAppTimer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700528 LongSamplingCounter mMobileRadioActiveAdjustedTime;
Dianne Hackbornd45665b2014-02-26 12:35:32 -0800529 LongSamplingCounter mMobileRadioActiveUnknownTime;
530 LongSamplingCounter mMobileRadioActiveUnknownCount;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800531
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700532 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
533
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800534 /**
535 * These provide time bases that discount the time the device is plugged
536 * in to power.
537 */
538 boolean mOnBattery;
539 boolean mOnBatteryInternal;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700540
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700541 /**
542 * External reporting of whether the device is actually charging.
543 */
544 boolean mCharging = true;
545 int mLastChargingStateLevel;
546
The Android Open Source Project10592532009-03-18 17:39:46 -0700547 /*
548 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
549 */
Evan Millar633a1742009-04-02 16:36:33 -0700550 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700551 int mDischargeUnplugLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700552 int mDischargePlugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700553 int mDischargeCurrentLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700554 int mCurrentBatteryLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700555 int mLowDischargeAmountSinceCharge;
556 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800557 int mDischargeScreenOnUnplugLevel;
558 int mDischargeScreenOffUnplugLevel;
559 int mDischargeAmountScreenOn;
560 int mDischargeAmountScreenOnSinceCharge;
561 int mDischargeAmountScreenOff;
562 int mDischargeAmountScreenOffSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700563
Adam Lesinski3ee3f632016-06-08 13:55:55 -0700564 private LongSamplingCounter mDischargeScreenOffCounter;
565 private LongSamplingCounter mDischargeCounter;
566
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700567 static final int MAX_LEVEL_STEPS = 200;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700568
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700569 int mInitStepMode = 0;
570 int mCurStepMode = 0;
571 int mModStepMode = 0;
572
Dianne Hackborn260c5022014-04-29 11:23:16 -0700573 int mLastDischargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700574 int mMinDischargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800575 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
576 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700577 ArrayList<PackageChange> mDailyPackageChanges;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700578
579 int mLastChargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700580 int mMaxChargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800581 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
582 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
583
584 static final int MAX_DAILY_ITEMS = 10;
585
586 long mDailyStartTime = 0;
587 long mNextMinDailyDeadline = 0;
588 long mNextMaxDailyDeadline = 0;
589
590 final ArrayList<DailyItem> mDailyItems = new ArrayList<>();
Dianne Hackborn260c5022014-04-29 11:23:16 -0700591
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800592 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700593
Amith Yamasanif37447b2009-10-08 18:28:01 -0700594 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800595 private int mPhoneServiceStateRaw = -1;
596 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700597
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800598 private int mNumConnectivityChange;
599 private int mLoadedNumConnectivityChange;
600 private int mUnpluggedNumConnectivityChange;
601
Adam Lesinskif9b20a92016-06-17 17:30:01 -0700602 private int mEstimatedBatteryCapacity = -1;
603
Jocelyn Dangc627d102017-04-14 13:15:14 -0700604 private int mMinLearnedBatteryCapacity = -1;
605 private int mMaxLearnedBatteryCapacity = -1;
Adam Lesinski041d9172016-12-12 12:03:56 -0800606
Sudheer Shanka9b735c52017-05-09 18:26:18 -0700607 private long[] mCpuFreqs;
608
Adam Lesinskie08af192015-03-25 16:42:59 -0700609 private PowerProfile mPowerProfile;
610
Evan Millarc64edde2009-04-18 12:26:32 -0700611 /*
612 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
613 */
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700614 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700615
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700616 public Map<String, ? extends Timer> getKernelWakelockStats() {
Evan Millarc64edde2009-04-18 12:26:32 -0700617 return mKernelWakelockStats;
618 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700619
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700620 String mLastWakeupReason = null;
621 long mLastWakeupUptimeMs = 0;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700622 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700623
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700624 public Map<String, ? extends Timer> getWakeupReasonStats() {
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700625 return mWakeupReasonStats;
626 }
627
Adam Lesinski3ee3f632016-06-08 13:55:55 -0700628 @Override
629 public LongCounter getDischargeScreenOffCoulombCounter() {
630 return mDischargeScreenOffCounter;
631 }
632
633 @Override
634 public LongCounter getDischargeCoulombCounter() {
635 return mDischargeCounter;
636 }
637
Adam Lesinskif9b20a92016-06-17 17:30:01 -0700638 @Override
639 public int getEstimatedBatteryCapacity() {
640 return mEstimatedBatteryCapacity;
641 }
642
Jocelyn Dangc627d102017-04-14 13:15:14 -0700643 @Override
644 public int getMinLearnedBatteryCapacity() {
645 return mMinLearnedBatteryCapacity;
646 }
647
648 @Override
649 public int getMaxLearnedBatteryCapacity() {
650 return mMaxLearnedBatteryCapacity;
651 }
652
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800653 public BatteryStatsImpl() {
Joe Onoratoabded112016-02-08 16:49:39 -0800654 this(new SystemClocks());
655 }
656
657 public BatteryStatsImpl(Clocks clocks) {
658 init(clocks);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700659 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700660 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800661 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700662 mHandler = null;
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700663 mPlatformIdleStateCallback = null;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700664 mUserInfoProvider = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700665 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800666 }
667
Joe Onoratoabded112016-02-08 16:49:39 -0800668 private void init(Clocks clocks) {
669 mClocks = clocks;
Joe Onoratoabded112016-02-08 16:49:39 -0800670 }
671
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700672 public interface TimeBaseObs {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800673 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
674 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
675 }
676
Joe Onoratoabded112016-02-08 16:49:39 -0800677 // methods are protected not private to be VisibleForTesting
678 public static class TimeBase {
679 protected final ArrayList<TimeBaseObs> mObservers = new ArrayList<>();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800680
Joe Onoratoabded112016-02-08 16:49:39 -0800681 protected long mUptime;
682 protected long mRealtime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800683
Joe Onoratoabded112016-02-08 16:49:39 -0800684 protected boolean mRunning;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800685
Joe Onoratoabded112016-02-08 16:49:39 -0800686 protected long mPastUptime;
687 protected long mUptimeStart;
688 protected long mPastRealtime;
689 protected long mRealtimeStart;
690 protected long mUnpluggedUptime;
691 protected long mUnpluggedRealtime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800692
693 public void dump(PrintWriter pw, String prefix) {
694 StringBuilder sb = new StringBuilder(128);
695 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
696 sb.setLength(0);
697 sb.append(prefix);
698 sb.append("mUptime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700699 formatTimeMs(sb, mUptime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800700 pw.println(sb.toString());
701 sb.setLength(0);
702 sb.append(prefix);
703 sb.append("mRealtime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700704 formatTimeMs(sb, mRealtime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800705 pw.println(sb.toString());
706 sb.setLength(0);
707 sb.append(prefix);
708 sb.append("mPastUptime=");
709 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
710 formatTimeMs(sb, mUptimeStart / 1000);
711 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
712 pw.println(sb.toString());
713 sb.setLength(0);
714 sb.append(prefix);
715 sb.append("mPastRealtime=");
716 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
717 formatTimeMs(sb, mRealtimeStart / 1000);
718 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
719 pw.println(sb.toString());
720 }
721
722 public void add(TimeBaseObs observer) {
723 mObservers.add(observer);
724 }
725
726 public void remove(TimeBaseObs observer) {
727 if (!mObservers.remove(observer)) {
728 Slog.wtf(TAG, "Removed unknown observer: " + observer);
729 }
730 }
731
Joe Onoratoabded112016-02-08 16:49:39 -0800732 public boolean hasObserver(TimeBaseObs observer) {
733 return mObservers.contains(observer);
734 }
735
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800736 public void init(long uptime, long realtime) {
737 mRealtime = 0;
738 mUptime = 0;
739 mPastUptime = 0;
740 mPastRealtime = 0;
741 mUptimeStart = uptime;
742 mRealtimeStart = realtime;
743 mUnpluggedUptime = getUptime(mUptimeStart);
744 mUnpluggedRealtime = getRealtime(mRealtimeStart);
745 }
746
747 public void reset(long uptime, long realtime) {
748 if (!mRunning) {
749 mPastUptime = 0;
750 mPastRealtime = 0;
751 } else {
752 mUptimeStart = uptime;
753 mRealtimeStart = realtime;
Joe Onoratoabded112016-02-08 16:49:39 -0800754 // TODO: Since mUptimeStart was just reset and we are running, getUptime will
755 // just return mPastUptime. Also, are we sure we don't want to reset that?
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800756 mUnpluggedUptime = getUptime(uptime);
Joe Onoratoabded112016-02-08 16:49:39 -0800757 // TODO: likewise.
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800758 mUnpluggedRealtime = getRealtime(realtime);
759 }
760 }
761
762 public long computeUptime(long curTime, int which) {
763 switch (which) {
764 case STATS_SINCE_CHARGED:
765 return mUptime + getUptime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800766 case STATS_CURRENT:
767 return getUptime(curTime);
768 case STATS_SINCE_UNPLUGGED:
769 return getUptime(curTime) - mUnpluggedUptime;
770 }
771 return 0;
772 }
773
774 public long computeRealtime(long curTime, int which) {
775 switch (which) {
776 case STATS_SINCE_CHARGED:
777 return mRealtime + getRealtime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800778 case STATS_CURRENT:
779 return getRealtime(curTime);
780 case STATS_SINCE_UNPLUGGED:
781 return getRealtime(curTime) - mUnpluggedRealtime;
782 }
783 return 0;
784 }
785
786 public long getUptime(long curTime) {
787 long time = mPastUptime;
788 if (mRunning) {
789 time += curTime - mUptimeStart;
790 }
791 return time;
792 }
793
794 public long getRealtime(long curTime) {
795 long time = mPastRealtime;
796 if (mRunning) {
797 time += curTime - mRealtimeStart;
798 }
799 return time;
800 }
801
802 public long getUptimeStart() {
803 return mUptimeStart;
804 }
805
806 public long getRealtimeStart() {
807 return mRealtimeStart;
808 }
809
810 public boolean isRunning() {
811 return mRunning;
812 }
813
814 public boolean setRunning(boolean running, long uptime, long realtime) {
815 if (mRunning != running) {
816 mRunning = running;
817 if (running) {
818 mUptimeStart = uptime;
819 mRealtimeStart = realtime;
820 long batteryUptime = mUnpluggedUptime = getUptime(uptime);
821 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
822
823 for (int i = mObservers.size() - 1; i >= 0; i--) {
824 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
825 }
826 } else {
827 mPastUptime += uptime - mUptimeStart;
828 mPastRealtime += realtime - mRealtimeStart;
829
830 long batteryUptime = getUptime(uptime);
831 long batteryRealtime = getRealtime(realtime);
832
833 for (int i = mObservers.size() - 1; i >= 0; i--) {
834 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
835 }
836 }
837 return true;
838 }
839 return false;
840 }
841
842 public void readSummaryFromParcel(Parcel in) {
843 mUptime = in.readLong();
844 mRealtime = in.readLong();
845 }
846
847 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
848 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
849 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
850 }
851
852 public void readFromParcel(Parcel in) {
853 mRunning = false;
854 mUptime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800855 mPastUptime = in.readLong();
856 mUptimeStart = in.readLong();
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700857 mRealtime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800858 mPastRealtime = in.readLong();
859 mRealtimeStart = in.readLong();
860 mUnpluggedUptime = in.readLong();
861 mUnpluggedRealtime = in.readLong();
862 }
863
864 public void writeToParcel(Parcel out, long uptime, long realtime) {
865 final long runningUptime = getUptime(uptime);
866 final long runningRealtime = getRealtime(realtime);
867 out.writeLong(mUptime);
868 out.writeLong(runningUptime);
869 out.writeLong(mUptimeStart);
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700870 out.writeLong(mRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800871 out.writeLong(runningRealtime);
872 out.writeLong(mRealtimeStart);
873 out.writeLong(mUnpluggedUptime);
874 out.writeLong(mUnpluggedRealtime);
875 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700877
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700879 * State for keeping track of counting information.
880 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800881 public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
Christopher Tate4cee7252010-03-19 14:50:40 -0700882 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800883 final TimeBase mTimeBase;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700884 int mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700885 int mUnpluggedCount;
886 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700887
Bookatz8c6f3c52017-05-24 12:00:17 -0700888 public Counter(TimeBase timeBase, Parcel in) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800889 mTimeBase = timeBase;
Christopher Tate4cee7252010-03-19 14:50:40 -0700890 mPluggedCount = in.readInt();
891 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700892 mLoadedCount = in.readInt();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700893 mUnpluggedCount = in.readInt();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800894 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700895 }
896
Bookatz8c6f3c52017-05-24 12:00:17 -0700897 public Counter(TimeBase timeBase) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800898 mTimeBase = timeBase;
899 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700900 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700901
Dianne Hackborn617f8772009-03-31 15:04:46 -0700902 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700903 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700904 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700905 out.writeInt(mUnpluggedCount);
906 }
907
Bookatz8c6f3c52017-05-24 12:00:17 -0700908 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800909 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700910 mUnpluggedCount = mPluggedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700911 }
912
Bookatz8c6f3c52017-05-24 12:00:17 -0700913 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800914 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700915 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700916 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700917
Dianne Hackborn617f8772009-03-31 15:04:46 -0700918 /**
919 * Writes a possibly null Counter to a Parcel.
920 *
921 * @param out the Parcel to be written to.
922 * @param counter a Counter, or null.
923 */
924 public static void writeCounterToParcel(Parcel out, Counter counter) {
925 if (counter == null) {
926 out.writeInt(0); // indicates null
927 return;
928 }
929 out.writeInt(1); // indicates non-null
930
931 counter.writeToParcel(out);
932 }
933
934 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700935 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700936 int val = mCount.get();
937 if (which == STATS_SINCE_UNPLUGGED) {
938 val -= mUnpluggedCount;
939 } else if (which != STATS_SINCE_CHARGED) {
940 val -= mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700941 }
942
943 return val;
944 }
945
946 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700947 pw.println(prefix + "mCount=" + mCount.get()
Bookatz8c6f3c52017-05-24 12:00:17 -0700948 + " mLoadedCount=" + mLoadedCount
Dianne Hackborn617f8772009-03-31 15:04:46 -0700949 + " mUnpluggedCount=" + mUnpluggedCount
950 + " mPluggedCount=" + mPluggedCount);
951 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700952
Bookatz8c6f3c52017-05-24 12:00:17 -0700953 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
954 public void stepAtomic() {
955 if (mTimeBase.isRunning()) {
956 mCount.incrementAndGet();
957 }
Dianne Hackborn617f8772009-03-31 15:04:46 -0700958 }
959
Bookatz4ebc0642017-05-11 12:21:19 -0700960 void addAtomic(int delta) {
Bookatz8c6f3c52017-05-24 12:00:17 -0700961 if (mTimeBase.isRunning()) {
962 mCount.addAndGet(delta);
963 }
Bookatz4ebc0642017-05-11 12:21:19 -0700964 }
965
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700966 /**
967 * Clear state of this counter.
968 */
969 void reset(boolean detachIfReset) {
970 mCount.set(0);
Bookatz8c6f3c52017-05-24 12:00:17 -0700971 mLoadedCount = mPluggedCount = mUnpluggedCount = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700972 if (detachIfReset) {
973 detach();
974 }
975 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700976
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700977 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800978 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700979 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700980
Bookatz8c6f3c52017-05-24 12:00:17 -0700981 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
982 public void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700983 int count = mCount.get();
984 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700985 }
986
Bookatz8c6f3c52017-05-24 12:00:17 -0700987 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
988 public void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700989 mLoadedCount = in.readInt();
990 mCount.set(mLoadedCount);
Christopher Tate4cee7252010-03-19 14:50:40 -0700991 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700992 }
993 }
Amith Yamasanie43530a2009-08-21 13:11:37 -0700994
Sudheer Shanka59f5c002017-05-15 10:57:15 -0700995 @VisibleForTesting
Sudheer Shanka9b735c52017-05-09 18:26:18 -0700996 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs {
997 final TimeBase mTimeBase;
Sudheer Shanka59f5c002017-05-15 10:57:15 -0700998 public long[] mCounts;
999 public long[] mLoadedCounts;
1000 public long[] mUnpluggedCounts;
1001 public long[] mPluggedCounts;
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001002
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001003 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001004 mTimeBase = timeBase;
1005 mPluggedCounts = in.createLongArray();
1006 mCounts = copyArray(mPluggedCounts, mCounts);
1007 mLoadedCounts = in.createLongArray();
1008 mUnpluggedCounts = in.createLongArray();
1009 timeBase.add(this);
1010 }
1011
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001012 public LongSamplingCounterArray(TimeBase timeBase) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001013 mTimeBase = timeBase;
1014 timeBase.add(this);
1015 }
1016
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001017 private void writeToParcel(Parcel out) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001018 out.writeLongArray(mCounts);
1019 out.writeLongArray(mLoadedCounts);
1020 out.writeLongArray(mUnpluggedCounts);
1021 }
1022
1023 @Override
1024 public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) {
1025 mUnpluggedCounts = copyArray(mPluggedCounts, mUnpluggedCounts);
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001026 }
1027
1028 @Override
1029 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1030 mPluggedCounts = copyArray(mCounts, mPluggedCounts);
1031 }
1032
1033 @Override
1034 public long[] getCountsLocked(int which) {
1035 long[] val = copyArray(mTimeBase.isRunning() ? mCounts : mPluggedCounts, null);
1036 if (which == STATS_SINCE_UNPLUGGED) {
1037 subtract(val, mUnpluggedCounts);
1038 } else if (which != STATS_SINCE_CHARGED) {
1039 subtract(val, mLoadedCounts);
1040 }
1041 return val;
1042 }
1043
1044 @Override
1045 public void logState(Printer pw, String prefix) {
1046 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)
1047 + " mLoadedCounts=" + Arrays.toString(mLoadedCounts)
1048 + " mUnpluggedCounts=" + Arrays.toString(mUnpluggedCounts)
1049 + " mPluggedCounts=" + Arrays.toString(mPluggedCounts));
1050 }
1051
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001052 public void addCountLocked(long[] counts) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001053 if (counts == null) {
1054 return;
1055 }
Bookatz8c6f3c52017-05-24 12:00:17 -07001056 if (mTimeBase.isRunning()) {
1057 if (mCounts == null) {
1058 mCounts = new long[counts.length];
1059 }
1060 for (int i = 0; i < counts.length; ++i) {
1061 mCounts[i] += counts[i];
1062 }
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001063 }
1064 }
1065
1066 /**
1067 * Clear state of this counter.
1068 */
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001069 public void reset(boolean detachIfReset) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001070 fillArray(mCounts, 0);
1071 fillArray(mLoadedCounts, 0);
1072 fillArray(mPluggedCounts, 0);
1073 fillArray(mUnpluggedCounts, 0);
1074 if (detachIfReset) {
1075 detach();
1076 }
1077 }
1078
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001079 public void detach() {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001080 mTimeBase.remove(this);
1081 }
1082
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001083 private void writeSummaryToParcelLocked(Parcel out) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001084 out.writeLongArray(mCounts);
1085 }
1086
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001087 private void readSummaryFromParcelLocked(Parcel in) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001088 mCounts = in.createLongArray();
1089 mLoadedCounts = copyArray(mCounts, mLoadedCounts);
1090 mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
1091 mPluggedCounts = copyArray(mCounts, mPluggedCounts);
1092 }
1093
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001094 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) {
1095 if (counterArray != null) {
1096 out.writeInt(1);
1097 counterArray.writeToParcel(out);
1098 } else {
1099 out.writeInt(0);
1100 }
1101 }
1102
1103 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) {
1104 if (in.readInt() != 0) {
1105 return new LongSamplingCounterArray(timeBase, in);
1106 } else {
1107 return null;
1108 }
1109 }
1110
1111 public static void writeSummaryToParcelLocked(Parcel out,
1112 LongSamplingCounterArray counterArray) {
1113 if (counterArray != null) {
1114 out.writeInt(1);
1115 counterArray.writeSummaryToParcelLocked(out);
1116 } else {
1117 out.writeInt(0);
1118 }
1119 }
1120
1121 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in,
1122 TimeBase timeBase) {
1123 if (in.readInt() != 0) {
1124 final LongSamplingCounterArray counterArray
1125 = new LongSamplingCounterArray(timeBase);
1126 counterArray.readSummaryFromParcelLocked(in);
1127 return counterArray;
1128 } else {
1129 return null;
1130 }
1131 }
1132
Bookatz8c6f3c52017-05-24 12:00:17 -07001133 private static void fillArray(long[] a, long val) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001134 if (a != null) {
1135 Arrays.fill(a, val);
1136 }
1137 }
1138
Bookatz8c6f3c52017-05-24 12:00:17 -07001139 private static void subtract(@NonNull long[] val, long[] toSubtract) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001140 if (toSubtract == null) {
1141 return;
1142 }
1143 for (int i = 0; i < val.length; i++) {
1144 val[i] -= toSubtract[i];
1145 }
1146 }
1147
Bookatz8c6f3c52017-05-24 12:00:17 -07001148 private static long[] copyArray(long[] src, long[] dest) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001149 if (src == null) {
1150 return null;
1151 } else {
1152 if (dest == null) {
1153 dest = new long[src.length];
1154 }
1155 System.arraycopy(src, 0, dest, 0, src.length);
1156 return dest;
1157 }
1158 }
1159 }
1160
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001161 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001162 final TimeBase mTimeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001163 long mCount;
1164 long mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001165 long mUnpluggedCount;
1166 long mPluggedCount;
1167
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001168 LongSamplingCounter(TimeBase timeBase, Parcel in) {
1169 mTimeBase = timeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001170 mPluggedCount = in.readLong();
1171 mCount = mPluggedCount;
1172 mLoadedCount = in.readLong();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001173 mUnpluggedCount = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001174 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001175 }
1176
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001177 LongSamplingCounter(TimeBase timeBase) {
1178 mTimeBase = timeBase;
1179 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001180 }
1181
1182 public void writeToParcel(Parcel out) {
1183 out.writeLong(mCount);
1184 out.writeLong(mLoadedCount);
1185 out.writeLong(mUnpluggedCount);
1186 }
1187
1188 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001189 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001190 mUnpluggedCount = mPluggedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001191 }
1192
1193 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001194 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001195 mPluggedCount = mCount;
1196 }
1197
1198 public long getCountLocked(int which) {
Adam Lesinski3ee3f632016-06-08 13:55:55 -07001199 long val = mTimeBase.isRunning() ? mCount : mPluggedCount;
Dianne Hackborn4590e522014-03-24 13:36:46 -07001200 if (which == STATS_SINCE_UNPLUGGED) {
1201 val -= mUnpluggedCount;
1202 } else if (which != STATS_SINCE_CHARGED) {
1203 val -= mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001204 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001205 return val;
1206 }
1207
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001208 @Override
1209 public void logState(Printer pw, String prefix) {
1210 pw.println(prefix + "mCount=" + mCount
Adam Lesinski3ee3f632016-06-08 13:55:55 -07001211 + " mLoadedCount=" + mLoadedCount
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001212 + " mUnpluggedCount=" + mUnpluggedCount
1213 + " mPluggedCount=" + mPluggedCount);
1214 }
1215
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001216 void addCountLocked(long count) {
Bookatz8c6f3c52017-05-24 12:00:17 -07001217 if (mTimeBase.isRunning()) {
1218 mCount += count;
1219 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001220 }
1221
1222 /**
1223 * Clear state of this counter.
1224 */
1225 void reset(boolean detachIfReset) {
1226 mCount = 0;
Adam Lesinski3ee3f632016-06-08 13:55:55 -07001227 mLoadedCount = mPluggedCount = mUnpluggedCount = 0;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001228 if (detachIfReset) {
1229 detach();
1230 }
1231 }
1232
1233 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001234 mTimeBase.remove(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001235 }
1236
1237 void writeSummaryFromParcelLocked(Parcel out) {
1238 out.writeLong(mCount);
1239 }
1240
1241 void readSummaryFromParcelLocked(Parcel in) {
1242 mLoadedCount = in.readLong();
1243 mCount = mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001244 mUnpluggedCount = mPluggedCount = mLoadedCount;
1245 }
1246 }
1247
Dianne Hackborn617f8772009-03-31 15:04:46 -07001248 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 * State for keeping track of timing information.
1250 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001251 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
Joe Onoratoabded112016-02-08 16:49:39 -08001252 protected final Clocks mClocks;
1253 protected final int mType;
1254 protected final TimeBase mTimeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001255
Joe Onoratoabded112016-02-08 16:49:39 -08001256 protected int mCount;
1257 protected int mLoadedCount;
1258 protected int mLastCount;
1259 protected int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261 // Times are in microseconds for better accuracy when dividing by the
1262 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 /**
1265 * The total time we have accumulated since the start of the original
1266 * boot, to the last time something interesting happened in the
1267 * current run.
1268 */
Joe Onoratoabded112016-02-08 16:49:39 -08001269 protected long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 /**
1272 * The total time we loaded for the previous runs. Subtract this from
1273 * mTotalTime to find the time for the current run of the system.
1274 */
Joe Onoratoabded112016-02-08 16:49:39 -08001275 protected long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001276
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 /**
1278 * The run time of the last run of the system, as loaded from the
1279 * saved data.
1280 */
Joe Onoratoabded112016-02-08 16:49:39 -08001281 protected long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283 /**
1284 * The value of mTotalTime when unplug() was last called. Subtract
1285 * this from mTotalTime to find the time since the last unplug from
1286 * power.
1287 */
Joe Onoratoabded112016-02-08 16:49:39 -08001288 protected long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001289
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001290 /**
Adam Lesinskie08af192015-03-25 16:42:59 -07001291 * The total time this timer has been running until the latest mark has been set.
1292 * Subtract this from mTotalTime to get the time spent running since the mark was set.
1293 */
Joe Onoratoabded112016-02-08 16:49:39 -08001294 protected long mTimeBeforeMark;
Adam Lesinskie08af192015-03-25 16:42:59 -07001295
1296 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001297 * Constructs from a parcel.
1298 * @param type
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001299 * @param timeBase
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001300 * @param in
1301 */
Joe Onoratoabded112016-02-08 16:49:39 -08001302 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) {
1303 mClocks = clocks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001304 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001305 mTimeBase = timeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001306
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 mCount = in.readInt();
1308 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001309 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001310 mUnpluggedCount = in.readInt();
1311 mTotalTime = in.readLong();
1312 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001313 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 mUnpluggedTime = in.readLong();
Adam Lesinskie08af192015-03-25 16:42:59 -07001315 mTimeBeforeMark = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001316 timeBase.add(this);
Dianne Hackborn29325132014-05-21 15:01:03 -07001317 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001318 }
1319
Joe Onoratoabded112016-02-08 16:49:39 -08001320 public Timer(Clocks clocks, int type, TimeBase timeBase) {
1321 mClocks = clocks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001322 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001323 mTimeBase = timeBase;
1324 timeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325 }
Evan Millarc64edde2009-04-18 12:26:32 -07001326
1327 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001328
Evan Millarc64edde2009-04-18 12:26:32 -07001329 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001330
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001331 /**
1332 * Clear state of this timer. Returns true if the timer is inactive
1333 * so can be completely dropped.
1334 */
Joe Onoratoabded112016-02-08 16:49:39 -08001335 public boolean reset(boolean detachIfReset) {
Adam Lesinskie08af192015-03-25 16:42:59 -07001336 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001337 mCount = mLoadedCount = mLastCount = 0;
1338 if (detachIfReset) {
1339 detach();
1340 }
1341 return true;
1342 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001343
Joe Onoratoabded112016-02-08 16:49:39 -08001344 public void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001345 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001346 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001347
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001348 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
Dianne Hackborn29325132014-05-21 15:01:03 -07001349 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
1350 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
Adam Lesinski98f0d462016-04-19 16:46:20 -07001351 out.writeInt(computeCurrentCountLocked());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001353 out.writeInt(mUnpluggedCount);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001354 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001355 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001356 out.writeLong(mUnpluggedTime);
Adam Lesinskie08af192015-03-25 16:42:59 -07001357 out.writeLong(mTimeBeforeMark);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 }
1359
Adam Lesinskie08af192015-03-25 16:42:59 -07001360 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001361 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001362 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001363 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001364 + " old mUnpluggedTime=" + mUnpluggedTime
1365 + " old mUnpluggedCount=" + mUnpluggedCount);
1366 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001367 mUnpluggedTime = computeRunTimeLocked(baseRealtime);
Adam Lesinski98f0d462016-04-19 16:46:20 -07001368 mUnpluggedCount = computeCurrentCountLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 if (DEBUG && mType < 0) {
1370 Log.v(TAG, "unplug #" + mType
1371 + ": new mUnpluggedTime=" + mUnpluggedTime
1372 + " new mUnpluggedCount=" + mUnpluggedCount);
1373 }
1374 }
1375
Adam Lesinskie08af192015-03-25 16:42:59 -07001376 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001377 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001378 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001379 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
Evan Millarc64edde2009-04-18 12:26:32 -07001380 + " old mTotalTime=" + mTotalTime);
1381 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001382 mTotalTime = computeRunTimeLocked(baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001383 mCount = computeCurrentCountLocked();
1384 if (DEBUG && mType < 0) {
1385 Log.v(TAG, "plug #" + mType
1386 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 }
1388 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001389
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 /**
1391 * Writes a possibly null Timer to a Parcel.
1392 *
1393 * @param out the Parcel to be written to.
1394 * @param timer a Timer, or null.
1395 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001396 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001397 if (timer == null) {
1398 out.writeInt(0); // indicates null
1399 return;
1400 }
1401 out.writeInt(1); // indicates non-null
1402
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001403 timer.writeToParcel(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001404 }
1405
1406 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001407 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001408 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1409 if (which == STATS_SINCE_UNPLUGGED) {
1410 val -= mUnpluggedTime;
1411 } else if (which != STATS_SINCE_CHARGED) {
1412 val -= mLoadedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001413 }
1414
1415 return val;
1416 }
1417
1418 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001419 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001420 int val = computeCurrentCountLocked();
1421 if (which == STATS_SINCE_UNPLUGGED) {
1422 val -= mUnpluggedCount;
1423 } else if (which != STATS_SINCE_CHARGED) {
1424 val -= mLoadedCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 }
1426
1427 return val;
1428 }
1429
Adam Lesinskie08af192015-03-25 16:42:59 -07001430 @Override
1431 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) {
1432 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1433 return val - mTimeBeforeMark;
1434 }
1435
1436 @Override
Dianne Hackborn627bba72009-03-24 22:32:56 -07001437 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001438 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001439 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
1440 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001441 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001442 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001443 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001444 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001445 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001446
1447
Joe Onoratoabded112016-02-08 16:49:39 -08001448 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001449 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1450 out.writeLong(runTime);
Adam Lesinski98f0d462016-04-19 16:46:20 -07001451 out.writeInt(computeCurrentCountLocked());
Evan Millarc64edde2009-04-18 12:26:32 -07001452 }
1453
Joe Onoratoabded112016-02-08 16:49:39 -08001454 public void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001455 // Multiply by 1000 for backwards compatibility
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001456 mTotalTime = mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001457 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001458 mUnpluggedTime = mTotalTime;
1459 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001460 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001461 mUnpluggedCount = mCount;
Adam Lesinskie08af192015-03-25 16:42:59 -07001462
1463 // When reading the summary, we set the mark to be the latest information.
1464 mTimeBeforeMark = mTotalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001465 }
1466 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001467
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001468 /**
1469 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)}
1470 * method. The state of the timer according to its {@link TimeBase} will determine how much
1471 * of the value is recorded.
1472 *
1473 * If the value being recorded resets, {@link #endSample()} can be called in order to
1474 * account for the change. If the value passed in to {@link #update(long, int)} decreased
1475 * between calls, the {@link #endSample()} is automatically called and the new value is
1476 * expected to increase monotonically from that point on.
1477 */
Joe Onoratoabded112016-02-08 16:49:39 -08001478 public static class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001479
Evan Millarc64edde2009-04-18 12:26:32 -07001480 /**
1481 * The most recent reported count from /proc/wakelocks.
1482 */
1483 int mCurrentReportedCount;
1484
1485 /**
1486 * The reported count from /proc/wakelocks when unplug() was last
1487 * called.
1488 */
1489 int mUnpluggedReportedCount;
1490
1491 /**
1492 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001493 */
Evan Millarc64edde2009-04-18 12:26:32 -07001494 long mCurrentReportedTotalTime;
1495
1496
1497 /**
1498 * The reported total_time from /proc/wakelocks when unplug() was last
1499 * called.
1500 */
1501 long mUnpluggedReportedTotalTime;
1502
1503 /**
1504 * Whether we are currently in a discharge cycle.
1505 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001506 boolean mTimeBaseRunning;
Evan Millarc64edde2009-04-18 12:26:32 -07001507
1508 /**
1509 * Whether we are currently recording reported values.
1510 */
1511 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001512
Evan Millarc64edde2009-04-18 12:26:32 -07001513 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001514 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -07001515 */
1516 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001517
Adam Lesinski98f0d462016-04-19 16:46:20 -07001518 @VisibleForTesting
1519 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) {
Joe Onoratoabded112016-02-08 16:49:39 -08001520 super(clocks, 0, timeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07001521 mCurrentReportedCount = in.readInt();
1522 mUnpluggedReportedCount = in.readInt();
1523 mCurrentReportedTotalTime = in.readLong();
1524 mUnpluggedReportedTotalTime = in.readLong();
1525 mTrackingReportedValues = in.readInt() == 1;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001526 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001527 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001528
Adam Lesinski98f0d462016-04-19 16:46:20 -07001529 @VisibleForTesting
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001530 public SamplingTimer(Clocks clocks, TimeBase timeBase) {
Joe Onoratoabded112016-02-08 16:49:39 -08001531 super(clocks, 0, timeBase);
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001532 mTrackingReportedValues = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001533 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001534 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001535
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001536 /**
1537 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to
1538 * be less than the values used for a previous invocation.
1539 */
1540 public void endSample() {
1541 mTotalTime = computeRunTimeLocked(0 /* unused by us */);
1542 mCount = computeCurrentCountLocked();
1543 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0;
1544 mUnpluggedReportedCount = mCurrentReportedCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001545 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001546
Evan Millarc64edde2009-04-18 12:26:32 -07001547 public void setUpdateVersion(int version) {
1548 mUpdateVersion = version;
1549 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001550
Evan Millarc64edde2009-04-18 12:26:32 -07001551 public int getUpdateVersion() {
1552 return mUpdateVersion;
1553 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001554
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001555 /**
1556 * Updates the current recorded values. These are meant to be monotonically increasing
1557 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}.
1558 *
1559 * If the values being recorded have been reset, the monotonically increasing requirement
1560 * will be broken. In this case, {@link #endSample()} is automatically called and
1561 * the total value of totalTime and count are recorded, starting a new monotonically
1562 * increasing sample.
1563 *
1564 * @param totalTime total time of sample in microseconds.
1565 * @param count total number of times the event being sampled occurred.
1566 */
1567 public void update(long totalTime, int count) {
1568 if (mTimeBaseRunning && !mTrackingReportedValues) {
Evan Millarc64edde2009-04-18 12:26:32 -07001569 // Updating the reported value for the first time.
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001570 mUnpluggedReportedTotalTime = totalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001571 mUnpluggedReportedCount = count;
Evan Millarc64edde2009-04-18 12:26:32 -07001572 }
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001573
1574 mTrackingReportedValues = true;
1575
1576 if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) {
1577 endSample();
1578 }
1579
1580 mCurrentReportedTotalTime = totalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001581 mCurrentReportedCount = count;
1582 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001583
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001584 /**
1585 * Adds deltaTime and deltaCount to the current sample.
1586 *
1587 * @param deltaTime additional time recorded since the last sampled event, in microseconds.
1588 * @param deltaCount additional number of times the event being sampled occurred.
1589 */
1590 public void add(long deltaTime, int deltaCount) {
1591 update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount);
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001592 }
1593
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001594 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001595 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1596 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001597 if (mTrackingReportedValues) {
1598 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
1599 mUnpluggedReportedCount = mCurrentReportedCount;
1600 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001601 mTimeBaseRunning = true;
Evan Millarc64edde2009-04-18 12:26:32 -07001602 }
1603
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001604 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001605 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1606 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1607 mTimeBaseRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001608 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001609
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001610 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001611 public void logState(Printer pw, String prefix) {
1612 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001613 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -07001614 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
1615 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
1616 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
1617 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001618
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001619 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001620 protected long computeRunTimeLocked(long curBatteryRealtime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001621 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001622 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
1623 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001624
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001625 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001626 protected int computeCurrentCountLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001627 return mCount + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001628 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
1629 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001630
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001631 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001632 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1633 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001634 out.writeInt(mCurrentReportedCount);
1635 out.writeInt(mUnpluggedReportedCount);
1636 out.writeLong(mCurrentReportedTotalTime);
1637 out.writeLong(mUnpluggedReportedTotalTime);
1638 out.writeInt(mTrackingReportedValues ? 1 : 0);
1639 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001640
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001641 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08001642 public boolean reset(boolean detachIfReset) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001643 super.reset(detachIfReset);
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001644 mTrackingReportedValues = false;
1645 mUnpluggedReportedTotalTime = 0;
1646 mUnpluggedReportedCount = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001647 return true;
1648 }
Evan Millarc64edde2009-04-18 12:26:32 -07001649 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001650
Evan Millarc64edde2009-04-18 12:26:32 -07001651 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001652 * A timer that increments in batches. It does not run for durations, but just jumps
1653 * for a pre-determined amount.
1654 */
Joe Onoratoabded112016-02-08 16:49:39 -08001655 public static class BatchTimer extends Timer {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001656 final Uid mUid;
1657
1658 /**
1659 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
1660 */
1661 long mLastAddedTime;
1662
1663 /**
1664 * The last duration that we added to the timer. This is in microseconds.
1665 */
1666 long mLastAddedDuration;
1667
1668 /**
1669 * Whether we are currently in a discharge cycle.
1670 */
1671 boolean mInDischarge;
1672
Joe Onoratoabded112016-02-08 16:49:39 -08001673 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) {
1674 super(clocks, type, timeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001675 mUid = uid;
1676 mLastAddedTime = in.readLong();
1677 mLastAddedDuration = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001678 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001679 }
1680
Joe Onoratoabded112016-02-08 16:49:39 -08001681 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) {
1682 super(clocks, type, timeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001683 mUid = uid;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001684 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001685 }
1686
1687 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001688 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1689 super.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001690 out.writeLong(mLastAddedTime);
1691 out.writeLong(mLastAddedDuration);
1692 }
1693
1694 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001695 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Joe Onoratoabded112016-02-08 16:49:39 -08001696 recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001697 mInDischarge = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001698 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001699 }
1700
1701 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001702 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001703 recomputeLastDuration(elapsedRealtime, false);
1704 mInDischarge = true;
1705 // If we are still within the last added duration, then re-added whatever remains.
1706 if (mLastAddedTime == elapsedRealtime) {
1707 mTotalTime += mLastAddedDuration;
1708 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001709 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001710 }
1711
1712 @Override
1713 public void logState(Printer pw, String prefix) {
1714 super.logState(pw, prefix);
1715 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
1716 + " mLastAddedDuration=" + mLastAddedDuration);
1717 }
1718
1719 private long computeOverage(long curTime) {
1720 if (mLastAddedTime > 0) {
1721 return mLastTime + mLastAddedDuration - curTime;
1722 }
1723 return 0;
1724 }
1725
1726 private void recomputeLastDuration(long curTime, boolean abort) {
1727 final long overage = computeOverage(curTime);
1728 if (overage > 0) {
1729 // Aborting before the duration ran out -- roll back the remaining
1730 // duration. Only do this if currently discharging; otherwise we didn't
1731 // actually add the time.
1732 if (mInDischarge) {
1733 mTotalTime -= overage;
1734 }
1735 if (abort) {
1736 mLastAddedTime = 0;
1737 } else {
1738 mLastAddedTime = curTime;
1739 mLastAddedDuration -= overage;
1740 }
1741 }
1742 }
1743
1744 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
Joe Onoratoabded112016-02-08 16:49:39 -08001745 final long now = mClocks.elapsedRealtime() * 1000;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001746 recomputeLastDuration(now, true);
1747 mLastAddedTime = now;
1748 mLastAddedDuration = durationMillis * 1000;
1749 if (mInDischarge) {
1750 mTotalTime += mLastAddedDuration;
1751 mCount++;
1752 }
1753 }
1754
1755 public void abortLastDuration(BatteryStatsImpl stats) {
Joe Onoratoabded112016-02-08 16:49:39 -08001756 final long now = mClocks.elapsedRealtime() * 1000;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001757 recomputeLastDuration(now, true);
1758 }
1759
1760 @Override
1761 protected int computeCurrentCountLocked() {
1762 return mCount;
1763 }
1764
1765 @Override
1766 protected long computeRunTimeLocked(long curBatteryRealtime) {
Joe Onoratoabded112016-02-08 16:49:39 -08001767 final long overage = computeOverage(mClocks.elapsedRealtime() * 1000);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001768 if (overage > 0) {
1769 return mTotalTime = overage;
1770 }
1771 return mTotalTime;
1772 }
1773
1774 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08001775 public boolean reset(boolean detachIfReset) {
1776 final long now = mClocks.elapsedRealtime() * 1000;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001777 recomputeLastDuration(now, true);
1778 boolean stillActive = mLastAddedTime == now;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001779 super.reset(!stillActive && detachIfReset);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001780 return !stillActive;
1781 }
1782 }
1783
Joe Onorato92fd23f2016-07-25 11:18:42 -07001784
1785 /**
1786 * A StopwatchTimer that also tracks the total and max individual
1787 * time spent active according to the given timebase. Whereas
1788 * StopwatchTimer apportions the time amongst all in the pool,
1789 * the total and max durations are not apportioned.
1790 */
1791 public static class DurationTimer extends StopwatchTimer {
1792 /**
1793 * The time (in ms) that the timer was last acquired or the time base
1794 * last (re-)started. Increasing the nesting depth does not reset this time.
1795 *
1796 * -1 if the timer is currently not running or the time base is not running.
1797 *
1798 * If written to a parcel, the start time is reset, as is mNesting in the base class
1799 * StopwatchTimer.
1800 */
1801 long mStartTimeMs = -1;
1802
1803 /**
Bookatz867c0d72017-03-07 18:23:42 -08001804 * The longest time period (in ms) that the timer has been active. Not pooled.
Joe Onorato92fd23f2016-07-25 11:18:42 -07001805 */
1806 long mMaxDurationMs;
1807
1808 /**
Bookatz867c0d72017-03-07 18:23:42 -08001809 * The time (in ms) that that the timer has been active since most recent
1810 * stopRunningLocked() or reset(). Not pooled.
Joe Onorato92fd23f2016-07-25 11:18:42 -07001811 */
1812 long mCurrentDurationMs;
1813
Bookatz867c0d72017-03-07 18:23:42 -08001814 /**
1815 * The total time (in ms) that that the timer has been active since most recent reset()
1816 * prior to the current startRunningLocked. This is the sum of all past currentDurations
1817 * (but not including the present currentDuration) since reset. Not pooled.
1818 */
1819 long mTotalDurationMs;
1820
Joe Onorato92fd23f2016-07-25 11:18:42 -07001821 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
1822 TimeBase timeBase, Parcel in) {
1823 super(clocks, uid, type, timerPool, timeBase, in);
1824 mMaxDurationMs = in.readLong();
Bookatz867c0d72017-03-07 18:23:42 -08001825 mTotalDurationMs = in.readLong();
Joe Onorato92fd23f2016-07-25 11:18:42 -07001826 }
1827
1828 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
1829 TimeBase timeBase) {
1830 super(clocks, uid, type, timerPool, timeBase);
1831 }
1832
1833 @Override
1834 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1835 super.writeToParcel(out, elapsedRealtimeUs);
Kweku Adams47db5a82016-12-09 19:04:50 -08001836 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000));
Bookatz867c0d72017-03-07 18:23:42 -08001837 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000));
Joe Onorato92fd23f2016-07-25 11:18:42 -07001838 }
1839
1840 /**
1841 * Write the summary to the parcel.
1842 *
1843 * Since the time base is probably meaningless after we come back, reading
1844 * from this will have the effect of stopping the timer. So here all we write
Bookatz867c0d72017-03-07 18:23:42 -08001845 * is the max and total durations.
Joe Onorato92fd23f2016-07-25 11:18:42 -07001846 */
1847 @Override
1848 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
1849 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
Kweku Adams47db5a82016-12-09 19:04:50 -08001850 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000));
Bookatz867c0d72017-03-07 18:23:42 -08001851 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000));
Joe Onorato92fd23f2016-07-25 11:18:42 -07001852 }
1853
1854 /**
1855 * Read the summary parcel.
1856 *
1857 * Has the side effect of stopping the timer.
1858 */
1859 @Override
1860 public void readSummaryFromParcelLocked(Parcel in) {
1861 super.readSummaryFromParcelLocked(in);
1862 mMaxDurationMs = in.readLong();
Bookatz867c0d72017-03-07 18:23:42 -08001863 mTotalDurationMs = in.readLong();
Joe Onorato92fd23f2016-07-25 11:18:42 -07001864 mStartTimeMs = -1;
1865 mCurrentDurationMs = 0;
1866 }
1867
1868 /**
1869 * The TimeBase time started (again).
1870 *
1871 * If the timer is also running, store the start time.
1872 */
1873 public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) {
1874 super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime);
1875 if (mNesting > 0) {
Kweku Adams47db5a82016-12-09 19:04:50 -08001876 mStartTimeMs = baseRealtime / 1000;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001877 }
1878 }
1879
1880 /**
1881 * The TimeBase stopped running.
1882 *
1883 * If the timer is running, add the duration into mCurrentDurationMs.
1884 */
1885 @Override
Kweku Adams47db5a82016-12-09 19:04:50 -08001886 public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) {
1887 super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs);
Joe Onorato92fd23f2016-07-25 11:18:42 -07001888 if (mNesting > 0) {
Kweku Adams47db5a82016-12-09 19:04:50 -08001889 // baseRealtimeUs has already been converted to the timebase's realtime.
1890 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001891 }
1892 mStartTimeMs = -1;
1893 }
1894
1895 @Override
1896 public void logState(Printer pw, String prefix) {
1897 super.logState(pw, prefix);
1898 }
1899
1900 @Override
1901 public void startRunningLocked(long elapsedRealtimeMs) {
1902 super.startRunningLocked(elapsedRealtimeMs);
1903 if (mNesting == 1 && mTimeBase.isRunning()) {
1904 // Just started
Kweku Adams47db5a82016-12-09 19:04:50 -08001905 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001906 }
1907 }
1908
1909 /**
1910 * Decrements the mNesting ref-count on this timer.
1911 *
1912 * If it actually stopped (mNesting went to 0), then possibly update
1913 * mMaxDuration if the current duration was the longest ever.
1914 */
1915 @Override
1916 public void stopRunningLocked(long elapsedRealtimeMs) {
Kweku Adams47db5a82016-12-09 19:04:50 -08001917 if (mNesting == 1) {
Joe Onorato92fd23f2016-07-25 11:18:42 -07001918 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs);
Bookatz867c0d72017-03-07 18:23:42 -08001919 mTotalDurationMs += durationMs;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001920 if (durationMs > mMaxDurationMs) {
1921 mMaxDurationMs = durationMs;
1922 }
1923 mStartTimeMs = -1;
1924 mCurrentDurationMs = 0;
1925 }
Kweku Adams47db5a82016-12-09 19:04:50 -08001926 // super method decrements mNesting, which getCurrentDurationMsLocked relies on,
1927 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked.
1928 super.stopRunningLocked(elapsedRealtimeMs);
Joe Onorato92fd23f2016-07-25 11:18:42 -07001929 }
1930
1931 @Override
1932 public boolean reset(boolean detachIfReset) {
1933 boolean result = super.reset(detachIfReset);
1934 mMaxDurationMs = 0;
Bookatz867c0d72017-03-07 18:23:42 -08001935 mTotalDurationMs = 0;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001936 mCurrentDurationMs = 0;
1937 if (mNesting > 0) {
1938 mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime()*1000) / 1000;
1939 } else {
1940 mStartTimeMs = -1;
1941 }
1942 return result;
1943 }
1944
1945 /**
1946 * Returns the max duration that this timer has ever seen.
1947 *
1948 * Note that this time is NOT split between the timers in the timer group that
1949 * this timer is attached to. It is the TOTAL time.
1950 */
1951 @Override
1952 public long getMaxDurationMsLocked(long elapsedRealtimeMs) {
1953 if (mNesting > 0) {
1954 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs);
1955 if (durationMs > mMaxDurationMs) {
1956 return durationMs;
1957 }
1958 }
1959 return mMaxDurationMs;
1960 }
1961
1962 /**
1963 * Returns the time since the timer was started.
Bookatz867c0d72017-03-07 18:23:42 -08001964 * Returns 0 if the timer is not currently running.
Joe Onorato92fd23f2016-07-25 11:18:42 -07001965 *
1966 * Note that this time is NOT split between the timers in the timer group that
1967 * this timer is attached to. It is the TOTAL time.
1968 */
1969 @Override
1970 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) {
1971 long durationMs = mCurrentDurationMs;
Kweku Adams47db5a82016-12-09 19:04:50 -08001972 if (mNesting > 0 && mTimeBase.isRunning()) {
1973 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs*1000)/1000)
1974 - mStartTimeMs;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001975 }
1976 return durationMs;
1977 }
Bookatz867c0d72017-03-07 18:23:42 -08001978
1979 /**
1980 * Returns the total cumulative duration that this timer has been on since reset().
1981 * If mTimerPool == null, this should be the same
1982 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000.
1983 *
1984 * Note that this time is NOT split between the timers in the timer group that
1985 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null,
1986 * the result will not be equivalent to getTotalTimeLocked.
1987 */
1988 @Override
1989 public long getTotalDurationMsLocked(long elapsedRealtimeMs) {
1990 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs);
1991 }
Joe Onorato92fd23f2016-07-25 11:18:42 -07001992 }
1993
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001994 /**
Evan Millarc64edde2009-04-18 12:26:32 -07001995 * State for keeping track of timing information.
1996 */
Joe Onoratoabded112016-02-08 16:49:39 -08001997 public static class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07001998 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07001999 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002000
Evan Millarc64edde2009-04-18 12:26:32 -07002001 int mNesting;
2002
Evan Millarc64edde2009-04-18 12:26:32 -07002003 /**
2004 * The last time at which we updated the timer. If mNesting is > 0,
2005 * subtract this from the current battery time to find the amount of
2006 * time we have been running since we last computed an update.
2007 */
2008 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002009
Evan Millarc64edde2009-04-18 12:26:32 -07002010 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002011 * The total time at which the timer was acquired, to determine if it
Bookatzceebafe2017-04-06 11:59:13 -07002012 * was actually held for an interesting duration. If time base was not running when timer
2013 * was acquired, will be -1.
Evan Millarc64edde2009-04-18 12:26:32 -07002014 */
Bookatzceebafe2017-04-06 11:59:13 -07002015 long mAcquireTime = -1;
Evan Millarc64edde2009-04-18 12:26:32 -07002016
Amith Yamasanif37447b2009-10-08 18:28:01 -07002017 long mTimeout;
2018
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002019 /**
2020 * For partial wake locks, keep track of whether we are in the list
2021 * to consume CPU cycles.
2022 */
2023 boolean mInList;
2024
Joe Onoratoabded112016-02-08 16:49:39 -08002025 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002026 TimeBase timeBase, Parcel in) {
Joe Onoratoabded112016-02-08 16:49:39 -08002027 super(clocks, type, timeBase, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002028 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07002029 mTimerPool = timerPool;
2030 mUpdateTime = in.readLong();
2031 }
2032
Joe Onoratoabded112016-02-08 16:49:39 -08002033 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002034 TimeBase timeBase) {
Joe Onoratoabded112016-02-08 16:49:39 -08002035 super(clocks, type, timeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002036 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07002037 mTimerPool = timerPool;
2038 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002039
Joe Onoratoabded112016-02-08 16:49:39 -08002040 public void setTimeout(long timeout) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07002041 mTimeout = timeout;
2042 }
2043
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002044 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
2045 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07002046 out.writeLong(mUpdateTime);
2047 }
2048
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002049 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07002050 if (mNesting > 0) {
2051 if (DEBUG && mType < 0) {
2052 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
2053 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002054 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
2055 mUpdateTime = baseRealtime;
Evan Millarc64edde2009-04-18 12:26:32 -07002056 if (DEBUG && mType < 0) {
2057 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
2058 }
2059 }
2060 }
2061
2062 public void logState(Printer pw, String prefix) {
2063 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002064 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002065 + " mAcquireTime=" + mAcquireTime);
2066 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002067
Joe Onoratoabded112016-02-08 16:49:39 -08002068 public void startRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002069 if (mNesting++ == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002070 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08002071 mUpdateTime = batteryRealtime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072 if (mTimerPool != null) {
2073 // Accumulate time to all currently active timers before adding
2074 // this new one to the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002075 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002076 // Add this timer to the active pool
2077 mTimerPool.add(this);
2078 }
Bookatzceebafe2017-04-06 11:59:13 -07002079 if (mTimeBase.isRunning()) {
2080 // Increment the count
2081 mCount++;
2082 mAcquireTime = mTotalTime;
2083 } else {
2084 mAcquireTime = -1;
2085 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002086 if (DEBUG && mType < 0) {
2087 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
2088 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
2089 + " mAcquireTime=" + mAcquireTime);
2090 }
2091 }
2092 }
2093
Joe Onoratoabded112016-02-08 16:49:39 -08002094 public boolean isRunningLocked() {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002095 return mNesting > 0;
2096 }
2097
Joe Onoratoabded112016-02-08 16:49:39 -08002098 public void stopRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002099 // Ignore attempt to stop a timer that isn't running
2100 if (mNesting == 0) {
2101 return;
2102 }
2103 if (--mNesting == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002104 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002105 if (mTimerPool != null) {
2106 // Accumulate time to all active counters, scaled by the total
2107 // active in the pool, before taking this one out of the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002108 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 // Remove this timer from the active pool
2110 mTimerPool.remove(this);
2111 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002112 mNesting = 1;
2113 mTotalTime = computeRunTimeLocked(batteryRealtime);
2114 mNesting = 0;
2115 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002117 if (DEBUG && mType < 0) {
2118 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
2119 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
2120 + " mAcquireTime=" + mAcquireTime);
2121 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002122
Bookatzceebafe2017-04-06 11:59:13 -07002123 if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002124 // If there was no change in the time, then discard this
2125 // count. A somewhat cheezy strategy, but hey.
2126 mCount--;
2127 }
2128 }
2129 }
2130
Joe Onoratoabded112016-02-08 16:49:39 -08002131 public void stopAllRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07002132 if (mNesting > 0) {
2133 mNesting = 1;
2134 stopRunningLocked(elapsedRealtimeMs);
2135 }
2136 }
2137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002138 // Update the total time for all other running Timers with the same type as this Timer
2139 // due to a change in timer count
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002140 private static long refreshTimersLocked(long batteryRealtime,
2141 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08002142 long selfTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002143 final int N = pool.size();
2144 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07002145 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002146 long heldTime = batteryRealtime - t.mUpdateTime;
2147 if (heldTime > 0) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08002148 final long myTime = heldTime / N;
2149 if (t == self) {
2150 selfTime = myTime;
2151 }
2152 t.mTotalTime += myTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002153 }
2154 t.mUpdateTime = batteryRealtime;
2155 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08002156 return selfTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002157 }
2158
Evan Millarc64edde2009-04-18 12:26:32 -07002159 @Override
2160 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07002161 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
2162 curBatteryRealtime = mUpdateTime + mTimeout;
2163 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002164 return mTotalTime + (mNesting > 0
2165 ? (curBatteryRealtime - mUpdateTime)
2166 / (mTimerPool != null ? mTimerPool.size() : 1)
2167 : 0);
2168 }
2169
Evan Millarc64edde2009-04-18 12:26:32 -07002170 @Override
2171 protected int computeCurrentCountLocked() {
2172 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 }
2174
Adam Lesinskie08af192015-03-25 16:42:59 -07002175 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08002176 public boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002177 boolean canDetach = mNesting <= 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002178 super.reset(canDetach && detachIfReset);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002179 if (mNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08002180 mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002181 }
Bookatzceebafe2017-04-06 11:59:13 -07002182 mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later.
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002183 return canDetach;
2184 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002185
Adam Lesinskie08af192015-03-25 16:42:59 -07002186 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08002187 public void detach() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002188 super.detach();
2189 if (mTimerPool != null) {
2190 mTimerPool.remove(this);
2191 }
2192 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002193
Adam Lesinskie08af192015-03-25 16:42:59 -07002194 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08002195 public void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07002196 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002197 mNesting = 0;
2198 }
Adam Lesinskie08af192015-03-25 16:42:59 -07002199
2200 /**
2201 * Set the mark so that we can query later for the total time the timer has
2202 * accumulated since this point. The timer can be running or not.
2203 *
2204 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds.
2205 */
2206 public void setMark(long elapsedRealtimeMs) {
2207 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
2208 if (mNesting > 0) {
2209 // We are running.
2210 if (mTimerPool != null) {
2211 refreshTimersLocked(batteryRealtime, mTimerPool, this);
2212 } else {
2213 mTotalTime += batteryRealtime - mUpdateTime;
2214 mUpdateTime = batteryRealtime;
2215 }
2216 }
2217 mTimeBeforeMark = mTotalTime;
2218 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002219 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002220
Bookatz867c0d72017-03-07 18:23:42 -08002221 /**
2222 * State for keeping track of two DurationTimers with different TimeBases, presumably where one
2223 * TimeBase is effectively a subset of the other.
2224 */
Bookatzaa4594a2017-03-24 12:39:56 -07002225 public static class DualTimer extends DurationTimer {
2226 // This class both is a DurationTimer and also holds a second DurationTimer.
2227 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a
2228 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for
2229 // STATS_SINCE_CHARGED).
Bookatz867c0d72017-03-07 18:23:42 -08002230 // mSubTimer typically tracks only part of the total time, such as background time, as
2231 // determined by a subTimeBase. It is NOT pooled.
2232 private final DurationTimer mSubTimer;
2233
2234 /**
Bookatzaa4594a2017-03-24 12:39:56 -07002235 * Creates a DualTimer to hold a main timer (this) and a mSubTimer.
2236 * The main timer (this) is based on the given timeBase and timerPool.
Bookatz867c0d72017-03-07 18:23:42 -08002237 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if
Bookatzaa4594a2017-03-24 12:39:56 -07002238 * the main timer is.
Bookatz867c0d72017-03-07 18:23:42 -08002239 */
2240 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2241 TimeBase timeBase, TimeBase subTimeBase, Parcel in) {
Bookatzaa4594a2017-03-24 12:39:56 -07002242 super(clocks, uid, type, timerPool, timeBase, in);
Bookatz867c0d72017-03-07 18:23:42 -08002243 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in);
2244 }
2245
2246 /**
Bookatzaa4594a2017-03-24 12:39:56 -07002247 * Creates a DualTimer to hold a main timer (this) and a mSubTimer.
2248 * The main timer (this) is based on the given timeBase and timerPool.
Bookatz867c0d72017-03-07 18:23:42 -08002249 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if
Bookatzaa4594a2017-03-24 12:39:56 -07002250 * the main timer is.
Bookatz867c0d72017-03-07 18:23:42 -08002251 */
2252 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2253 TimeBase timeBase, TimeBase subTimeBase) {
Bookatzaa4594a2017-03-24 12:39:56 -07002254 super(clocks, uid, type, timerPool, timeBase);
Bookatz867c0d72017-03-07 18:23:42 -08002255 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase);
2256 }
2257
Bookatz867c0d72017-03-07 18:23:42 -08002258 /** Get the secondary timer. */
Bookatzaa4594a2017-03-24 12:39:56 -07002259 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002260 public DurationTimer getSubTimer() {
2261 return mSubTimer;
2262 }
2263
Bookatzaa4594a2017-03-24 12:39:56 -07002264 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002265 public void startRunningLocked(long elapsedRealtimeMs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002266 super.startRunningLocked(elapsedRealtimeMs);
Bookatz867c0d72017-03-07 18:23:42 -08002267 mSubTimer.startRunningLocked(elapsedRealtimeMs);
2268 }
2269
Bookatzaa4594a2017-03-24 12:39:56 -07002270 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002271 public void stopRunningLocked(long elapsedRealtimeMs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002272 super.stopRunningLocked(elapsedRealtimeMs);
Bookatz867c0d72017-03-07 18:23:42 -08002273 mSubTimer.stopRunningLocked(elapsedRealtimeMs);
2274 }
2275
Bookatzaa4594a2017-03-24 12:39:56 -07002276 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002277 public void stopAllRunningLocked(long elapsedRealtimeMs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002278 super.stopAllRunningLocked(elapsedRealtimeMs);
Bookatz867c0d72017-03-07 18:23:42 -08002279 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs);
2280 }
2281
Bookatzaa4594a2017-03-24 12:39:56 -07002282 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002283 public boolean reset(boolean detachIfReset) {
2284 boolean active = false;
Bookatz4a3eda92017-04-10 13:10:46 -07002285 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach().
2286 active |= !mSubTimer.reset(false);
Bookatzaa4594a2017-03-24 12:39:56 -07002287 active |= !super.reset(detachIfReset);
Bookatz867c0d72017-03-07 18:23:42 -08002288 return !active;
2289 }
2290
Bookatzaa4594a2017-03-24 12:39:56 -07002291 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002292 public void detach() {
Bookatz867c0d72017-03-07 18:23:42 -08002293 mSubTimer.detach();
Bookatz4a3eda92017-04-10 13:10:46 -07002294 super.detach();
Bookatz867c0d72017-03-07 18:23:42 -08002295 }
2296
Bookatzaa4594a2017-03-24 12:39:56 -07002297 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002298 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002299 super.writeToParcel(out, elapsedRealtimeUs);
Bookatz867c0d72017-03-07 18:23:42 -08002300 mSubTimer.writeToParcel(out, elapsedRealtimeUs);
2301 }
2302
Bookatzaa4594a2017-03-24 12:39:56 -07002303 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002304 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002305 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
Bookatz867c0d72017-03-07 18:23:42 -08002306 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
2307 }
2308
Bookatzaa4594a2017-03-24 12:39:56 -07002309 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002310 public void readSummaryFromParcelLocked(Parcel in) {
Bookatzaa4594a2017-03-24 12:39:56 -07002311 super.readSummaryFromParcelLocked(in);
Bookatz867c0d72017-03-07 18:23:42 -08002312 mSubTimer.readSummaryFromParcelLocked(in);
2313 }
2314 }
2315
2316
Dianne Hackbornd953c532014-08-16 18:17:38 -07002317 public abstract class OverflowArrayMap<T> {
2318 private static final String OVERFLOW_NAME = "*overflow*";
2319
Dianne Hackborn657153b2016-07-29 14:54:14 -07002320 final int mUid;
Dianne Hackbornd953c532014-08-16 18:17:38 -07002321 final ArrayMap<String, T> mMap = new ArrayMap<>();
2322 T mCurOverflow;
2323 ArrayMap<String, MutableInt> mActiveOverflow;
Dianne Hackborn657153b2016-07-29 14:54:14 -07002324 long mLastOverflowTime;
2325 long mLastOverflowFinishTime;
2326 long mLastClearTime;
2327 long mLastCleanupTime;
Dianne Hackbornd953c532014-08-16 18:17:38 -07002328
Dianne Hackborn657153b2016-07-29 14:54:14 -07002329 public OverflowArrayMap(int uid) {
2330 mUid = uid;
Dianne Hackbornd953c532014-08-16 18:17:38 -07002331 }
2332
2333 public ArrayMap<String, T> getMap() {
2334 return mMap;
2335 }
2336
2337 public void clear() {
Dianne Hackborn657153b2016-07-29 14:54:14 -07002338 mLastClearTime = SystemClock.elapsedRealtime();
Dianne Hackbornd953c532014-08-16 18:17:38 -07002339 mMap.clear();
2340 mCurOverflow = null;
2341 mActiveOverflow = null;
2342 }
2343
2344 public void add(String name, T obj) {
Joe Onorato388fc332016-04-12 17:06:47 -07002345 if (name == null) {
2346 name = "";
2347 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07002348 mMap.put(name, obj);
2349 if (OVERFLOW_NAME.equals(name)) {
2350 mCurOverflow = obj;
2351 }
2352 }
2353
2354 public void cleanup() {
Dianne Hackborn657153b2016-07-29 14:54:14 -07002355 mLastCleanupTime = SystemClock.elapsedRealtime();
Dianne Hackbornd953c532014-08-16 18:17:38 -07002356 if (mActiveOverflow != null) {
2357 if (mActiveOverflow.size() == 0) {
2358 mActiveOverflow = null;
2359 }
2360 }
2361 if (mActiveOverflow == null) {
2362 // There is no currently active overflow, so we should no longer have
2363 // an overflow entry.
2364 if (mMap.containsKey(OVERFLOW_NAME)) {
2365 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry "
2366 + mMap.get(OVERFLOW_NAME));
2367 mMap.remove(OVERFLOW_NAME);
2368 }
2369 mCurOverflow = null;
2370 } else {
2371 // There is currently active overflow, so we should still have an overflow entry.
2372 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) {
2373 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur="
2374 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME));
2375 }
2376 }
2377 }
2378
2379 public T startObject(String name) {
Joe Onorato388fc332016-04-12 17:06:47 -07002380 if (name == null) {
2381 name = "";
2382 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07002383 T obj = mMap.get(name);
2384 if (obj != null) {
2385 return obj;
2386 }
2387
2388 // No object exists for the given name, but do we currently have it
2389 // running as part of the overflow?
2390 if (mActiveOverflow != null) {
2391 MutableInt over = mActiveOverflow.get(name);
2392 if (over != null) {
2393 // We are already actively counting this name in the overflow object.
2394 obj = mCurOverflow;
2395 if (obj == null) {
2396 // Shouldn't be here, but we'll try to recover.
2397 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow");
2398 obj = mCurOverflow = instantiateObject();
2399 mMap.put(OVERFLOW_NAME, obj);
2400 }
2401 over.value++;
2402 return obj;
2403 }
2404 }
2405
2406 // No object exists for given name nor in the overflow; we need to make
2407 // a new one.
2408 final int N = mMap.size();
2409 if (N >= MAX_WAKELOCKS_PER_UID) {
2410 // Went over the limit on number of objects to track; this one goes
2411 // in to the overflow.
2412 obj = mCurOverflow;
2413 if (obj == null) {
2414 // Need to start overflow now...
2415 obj = mCurOverflow = instantiateObject();
2416 mMap.put(OVERFLOW_NAME, obj);
2417 }
2418 if (mActiveOverflow == null) {
2419 mActiveOverflow = new ArrayMap<>();
2420 }
2421 mActiveOverflow.put(name, new MutableInt(1));
Dianne Hackborn657153b2016-07-29 14:54:14 -07002422 mLastOverflowTime = SystemClock.elapsedRealtime();
Dianne Hackbornd953c532014-08-16 18:17:38 -07002423 return obj;
2424 }
2425
2426 // Normal case where we just need to make a new object.
2427 obj = instantiateObject();
2428 mMap.put(name, obj);
2429 return obj;
2430 }
2431
2432 public T stopObject(String name) {
Joe Onorato388fc332016-04-12 17:06:47 -07002433 if (name == null) {
2434 name = "";
2435 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07002436 T obj = mMap.get(name);
2437 if (obj != null) {
2438 return obj;
2439 }
2440
2441 // No object exists for the given name, but do we currently have it
2442 // running as part of the overflow?
2443 if (mActiveOverflow != null) {
2444 MutableInt over = mActiveOverflow.get(name);
2445 if (over != null) {
2446 // We are already actively counting this name in the overflow object.
2447 obj = mCurOverflow;
2448 if (obj != null) {
2449 over.value--;
2450 if (over.value <= 0) {
2451 mActiveOverflow.remove(name);
Dianne Hackborn657153b2016-07-29 14:54:14 -07002452 mLastOverflowFinishTime = SystemClock.elapsedRealtime();
Dianne Hackbornd953c532014-08-16 18:17:38 -07002453 }
2454 return obj;
2455 }
2456 }
2457 }
2458
2459 // Huh, they are stopping an active operation but we can't find one!
2460 // That's not good.
Dianne Hackborn657153b2016-07-29 14:54:14 -07002461 StringBuilder sb = new StringBuilder();
2462 sb.append("Unable to find object for ");
2463 sb.append(name);
2464 sb.append(" in uid ");
2465 sb.append(mUid);
2466 sb.append(" mapsize=");
2467 sb.append(mMap.size());
2468 sb.append(" activeoverflow=");
2469 sb.append(mActiveOverflow);
2470 sb.append(" curoverflow=");
2471 sb.append(mCurOverflow);
2472 long now = SystemClock.elapsedRealtime();
2473 if (mLastOverflowTime != 0) {
2474 sb.append(" lastOverflowTime=");
2475 TimeUtils.formatDuration(mLastOverflowTime-now, sb);
2476 }
2477 if (mLastOverflowFinishTime != 0) {
2478 sb.append(" lastOverflowFinishTime=");
2479 TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb);
2480 }
2481 if (mLastClearTime != 0) {
2482 sb.append(" lastClearTime=");
2483 TimeUtils.formatDuration(mLastClearTime-now, sb);
2484 }
2485 if (mLastCleanupTime != 0) {
2486 sb.append(" lastCleanupTime=");
2487 TimeUtils.formatDuration(mLastCleanupTime-now, sb);
2488 }
2489 Slog.wtf(TAG, sb.toString());
Dianne Hackbornd953c532014-08-16 18:17:38 -07002490 return null;
2491 }
2492
2493 public abstract T instantiateObject();
2494 }
2495
Adam Lesinski21f76aa2016-01-25 12:27:06 -08002496 public static class ControllerActivityCounterImpl extends ControllerActivityCounter
2497 implements Parcelable {
2498 private final LongSamplingCounter mIdleTimeMillis;
2499 private final LongSamplingCounter mRxTimeMillis;
2500 private final LongSamplingCounter[] mTxTimeMillis;
2501 private final LongSamplingCounter mPowerDrainMaMs;
2502
2503 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) {
2504 mIdleTimeMillis = new LongSamplingCounter(timeBase);
2505 mRxTimeMillis = new LongSamplingCounter(timeBase);
2506 mTxTimeMillis = new LongSamplingCounter[numTxStates];
2507 for (int i = 0; i < numTxStates; i++) {
2508 mTxTimeMillis[i] = new LongSamplingCounter(timeBase);
2509 }
2510 mPowerDrainMaMs = new LongSamplingCounter(timeBase);
2511 }
2512
2513 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) {
2514 mIdleTimeMillis = new LongSamplingCounter(timeBase, in);
2515 mRxTimeMillis = new LongSamplingCounter(timeBase, in);
2516 final int recordedTxStates = in.readInt();
2517 if (recordedTxStates != numTxStates) {
2518 throw new ParcelFormatException("inconsistent tx state lengths");
2519 }
2520
2521 mTxTimeMillis = new LongSamplingCounter[numTxStates];
2522 for (int i = 0; i < numTxStates; i++) {
2523 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in);
2524 }
2525 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in);
2526 }
2527
2528 public void readSummaryFromParcel(Parcel in) {
2529 mIdleTimeMillis.readSummaryFromParcelLocked(in);
2530 mRxTimeMillis.readSummaryFromParcelLocked(in);
2531 final int recordedTxStates = in.readInt();
2532 if (recordedTxStates != mTxTimeMillis.length) {
2533 throw new ParcelFormatException("inconsistent tx state lengths");
2534 }
2535 for (LongSamplingCounter counter : mTxTimeMillis) {
2536 counter.readSummaryFromParcelLocked(in);
2537 }
2538 mPowerDrainMaMs.readSummaryFromParcelLocked(in);
2539 }
2540
2541 @Override
2542 public int describeContents() {
2543 return 0;
2544 }
2545
2546 public void writeSummaryToParcel(Parcel dest) {
2547 mIdleTimeMillis.writeSummaryFromParcelLocked(dest);
2548 mRxTimeMillis.writeSummaryFromParcelLocked(dest);
2549 dest.writeInt(mTxTimeMillis.length);
2550 for (LongSamplingCounter counter : mTxTimeMillis) {
2551 counter.writeSummaryFromParcelLocked(dest);
2552 }
2553 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest);
2554 }
2555
2556 @Override
2557 public void writeToParcel(Parcel dest, int flags) {
2558 mIdleTimeMillis.writeToParcel(dest);
2559 mRxTimeMillis.writeToParcel(dest);
2560 dest.writeInt(mTxTimeMillis.length);
2561 for (LongSamplingCounter counter : mTxTimeMillis) {
2562 counter.writeToParcel(dest);
2563 }
2564 mPowerDrainMaMs.writeToParcel(dest);
2565 }
2566
2567 public void reset(boolean detachIfReset) {
2568 mIdleTimeMillis.reset(detachIfReset);
2569 mRxTimeMillis.reset(detachIfReset);
2570 for (LongSamplingCounter counter : mTxTimeMillis) {
2571 counter.reset(detachIfReset);
2572 }
2573 mPowerDrainMaMs.reset(detachIfReset);
2574 }
2575
2576 public void detach() {
2577 mIdleTimeMillis.detach();
2578 mRxTimeMillis.detach();
2579 for (LongSamplingCounter counter : mTxTimeMillis) {
2580 counter.detach();
2581 }
2582 mPowerDrainMaMs.detach();
2583 }
2584
2585 /**
2586 * @return a LongSamplingCounter, measuring time spent in the idle state in
2587 * milliseconds.
2588 */
2589 @Override
2590 public LongSamplingCounter getIdleTimeCounter() {
Roshan Pius81643302016-03-14 16:45:55 -07002591 return mIdleTimeMillis;
Adam Lesinski21f76aa2016-01-25 12:27:06 -08002592 }
2593
2594 /**
2595 * @return a LongSamplingCounter, measuring time spent in the receive state in
2596 * milliseconds.
2597 */
2598 @Override
2599 public LongSamplingCounter getRxTimeCounter() {
2600 return mRxTimeMillis;
2601 }
2602
2603 /**
2604 * @return a LongSamplingCounter[], measuring time spent in various transmit states in
2605 * milliseconds.
2606 */
2607 @Override
2608 public LongSamplingCounter[] getTxTimeCounters() {
2609 return mTxTimeMillis;
2610 }
2611
2612 /**
2613 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS).
2614 */
2615 @Override
2616 public LongSamplingCounter getPowerCounter() {
2617 return mPowerDrainMaMs;
2618 }
2619 }
2620
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002621 /*
2622 * Get the wakeup reason counter, and create a new one if one
2623 * doesn't already exist.
2624 */
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002625 public SamplingTimer getWakeupReasonTimerLocked(String name) {
2626 SamplingTimer timer = mWakeupReasonStats.get(name);
2627 if (timer == null) {
Adam Lesinski757c6ea2016-04-21 09:55:41 -07002628 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase);
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002629 mWakeupReasonStats.put(name, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002630 }
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002631 return timer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002632 }
2633
Evan Millarc64edde2009-04-18 12:26:32 -07002634 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002635 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07002636 * doesn't already exist.
2637 */
2638 public SamplingTimer getKernelWakelockTimerLocked(String name) {
2639 SamplingTimer kwlt = mKernelWakelockStats.get(name);
2640 if (kwlt == null) {
Adam Lesinski757c6ea2016-04-21 09:55:41 -07002641 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase);
Evan Millarc64edde2009-04-18 12:26:32 -07002642 mKernelWakelockStats.put(name, kwlt);
2643 }
2644 return kwlt;
2645 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002646
James Carr3a226052016-07-01 14:49:52 -07002647 public SamplingTimer getKernelMemoryTimerLocked(long bucket) {
2648 SamplingTimer kmt = mKernelMemoryStats.get(bucket);
2649 if (kmt == null) {
2650 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase);
2651 mKernelMemoryStats.put(bucket, kmt);
2652 }
2653 return kmt;
2654 }
2655
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002656 private int writeHistoryTag(HistoryTag tag) {
2657 Integer idxObj = mHistoryTagPool.get(tag);
2658 int idx;
2659 if (idxObj != null) {
2660 idx = idxObj;
2661 } else {
2662 idx = mNextHistoryTagIdx;
2663 HistoryTag key = new HistoryTag();
2664 key.setTo(tag);
2665 tag.poolIdx = idx;
2666 mHistoryTagPool.put(key, idx);
2667 mNextHistoryTagIdx++;
2668 mNumHistoryTagChars += key.string.length() + 1;
2669 }
2670 return idx;
2671 }
2672
2673 private void readHistoryTag(int index, HistoryTag tag) {
2674 tag.string = mReadHistoryStrings[index];
2675 tag.uid = mReadHistoryUids[index];
2676 tag.poolIdx = index;
2677 }
2678
Adam Lesinski926969b2016-04-28 17:31:12 -07002679 /*
2680 The history delta format uses flags to denote further data in subsequent ints in the parcel.
2681
2682 There is always the first token, which may contain the delta time, or an indicator of
2683 the length of the time (int or long) following this token.
2684
2685 First token: always present,
2686 31 23 15 7 0
2687 â–ˆM|L|K|J|I|H|G|Fâ–ˆE|D|C|B|A|T|T|Tâ–ˆT|T|T|T|T|T|T|Tâ–ˆT|T|T|T|T|T|T|Tâ–ˆ
2688
2689 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately
2690 follows containing the time, and 0x7ffff indicates a long immediately follows with the
2691 delta time.
2692 A: battery level changed and an int follows with battery data.
2693 B: state changed and an int follows with state change data.
2694 C: state2 has changed and an int follows with state2 change data.
2695 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows.
2696 E: event data has changed and an event struct follows.
2697 F: battery charge in coulombs has changed and an int with the charge follows.
2698 G: state flag denoting that the mobile radio was active.
2699 H: state flag denoting that the wifi radio was active.
2700 I: state flag denoting that a wifi scan occurred.
2701 J: state flag denoting that a wifi full lock was held.
2702 K: state flag denoting that the gps was on.
2703 L: state flag denoting that a wakelock was held.
2704 M: state flag denoting that the cpu was running.
2705
2706 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows
2707 with the time delta.
2708
2709 Battery level int: if A in the first token is set,
2710 31 23 15 7 0
2711 â–ˆL|L|L|L|L|L|L|Tâ–ˆT|T|T|T|T|T|T|Tâ–ˆT|V|V|V|V|V|V|Vâ–ˆV|V|V|V|V|V|V|Dâ–ˆ
2712
2713 D: indicates that extra history details follow.
2714 V: the battery voltage.
2715 T: the battery temperature.
2716 L: the battery level (out of 100).
2717
2718 State change int: if B in the first token is set,
2719 31 23 15 7 0
2720 â–ˆS|S|S|H|H|H|P|Pâ–ˆF|E|D|C|B| | |Aâ–ˆ | | | | | | | â–ˆ | | | | | | | â–ˆ
2721
2722 A: wifi multicast was on.
2723 B: battery was plugged in.
2724 C: screen was on.
2725 D: phone was scanning for signal.
2726 E: audio was on.
2727 F: a sensor was active.
2728
2729 State2 change int: if C in the first token is set,
2730 31 23 15 7 0
2731 â–ˆM|L|K|J|I|H|H|Gâ–ˆF|E|D|C| | | | â–ˆ | | | | | | | â–ˆ |B|B|B|A|A|A|Aâ–ˆ
2732
2733 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}.
2734 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4.
2735 C: a bluetooth scan was active.
2736 D: the camera was active.
2737 E: bluetooth was on.
2738 F: a phone call was active.
2739 G: the device was charging.
2740 H: 2 bits indicating the device-idle (doze) state: off, light, full
2741 I: the flashlight was on.
2742 J: wifi was on.
2743 K: wifi was running.
2744 L: video was playing.
2745 M: power save mode was on.
2746
2747 Wakelock/wakereason struct: if D in the first token is set,
2748 TODO(adamlesinski): describe wakelock/wakereason struct.
2749
2750 Event struct: if E in the first token is set,
2751 TODO(adamlesinski): describe the event struct.
2752
2753 History step details struct: if D in the battery level int is set,
2754 TODO(adamlesinski): describe the history step details struct.
2755
2756 Battery charge int: if F in the first token is set, an int representing the battery charge
2757 in coulombs follows.
2758 */
2759
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002760 // Part of initial delta int that specifies the time delta.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002761 static final int DELTA_TIME_MASK = 0x7ffff;
2762 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
2763 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
2764 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002765 // Flag in delta int: a new battery level int follows.
Adam Lesinski926969b2016-04-28 17:31:12 -07002766 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002767 // Flag in delta int: a new full state and battery status int follows.
Adam Lesinski926969b2016-04-28 17:31:12 -07002768 static final int DELTA_STATE_FLAG = 0x00100000;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002769 // Flag in delta int: a new full state2 int follows.
Adam Lesinski926969b2016-04-28 17:31:12 -07002770 static final int DELTA_STATE2_FLAG = 0x00200000;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002771 // Flag in delta int: contains a wakelock or wakeReason tag.
Adam Lesinski926969b2016-04-28 17:31:12 -07002772 static final int DELTA_WAKELOCK_FLAG = 0x00400000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002773 // Flag in delta int: contains an event description.
Adam Lesinski926969b2016-04-28 17:31:12 -07002774 static final int DELTA_EVENT_FLAG = 0x00800000;
Adam Lesinskia8018ac2016-05-03 10:18:10 -07002775 // Flag in delta int: contains the battery charge count in uAh.
2776 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002777 // These upper bits are the frequently changing state bits.
Adam Lesinski926969b2016-04-28 17:31:12 -07002778 static final int DELTA_STATE_MASK = 0xfe000000;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002779
2780 // These are the pieces of battery state that are packed in to the upper bits of
2781 // the state int that have been packed in to the first delta int. They must fit
Adam Lesinski926969b2016-04-28 17:31:12 -07002782 // in STATE_BATTERY_MASK.
2783 static final int STATE_BATTERY_MASK = 0xff000000;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002784 static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
2785 static final int STATE_BATTERY_STATUS_SHIFT = 29;
2786 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
2787 static final int STATE_BATTERY_HEALTH_SHIFT = 26;
2788 static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
2789 static final int STATE_BATTERY_PLUG_SHIFT = 24;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002790
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002791 // We use the low bit of the battery state int to indicate that we have full details
2792 // from a battery level change.
2793 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001;
2794
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002795 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002796 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002797 dest.writeInt(DELTA_TIME_ABS);
2798 cur.writeToParcel(dest, 0);
2799 return;
2800 }
2801
2802 final long deltaTime = cur.time - last.time;
2803 final int lastBatteryLevelInt = buildBatteryLevelInt(last);
2804 final int lastStateInt = buildStateInt(last);
2805
2806 int deltaTimeToken;
2807 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
2808 deltaTimeToken = DELTA_TIME_LONG;
2809 } else if (deltaTime >= DELTA_TIME_ABS) {
2810 deltaTimeToken = DELTA_TIME_INT;
2811 } else {
2812 deltaTimeToken = (int)deltaTime;
2813 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002814 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002815 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel
2816 ? BATTERY_DELTA_LEVEL_FLAG : 0;
2817 final boolean computeStepDetails = includeStepDetails != 0
2818 || mLastHistoryStepDetails == null;
2819 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002820 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
2821 if (batteryLevelIntChanged) {
2822 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
2823 }
2824 final int stateInt = buildStateInt(cur);
2825 final boolean stateIntChanged = stateInt != lastStateInt;
2826 if (stateIntChanged) {
2827 firstToken |= DELTA_STATE_FLAG;
2828 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002829 final boolean state2IntChanged = cur.states2 != last.states2;
2830 if (state2IntChanged) {
2831 firstToken |= DELTA_STATE2_FLAG;
2832 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002833 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002834 firstToken |= DELTA_WAKELOCK_FLAG;
2835 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002836 if (cur.eventCode != HistoryItem.EVENT_NONE) {
2837 firstToken |= DELTA_EVENT_FLAG;
2838 }
Adam Lesinski926969b2016-04-28 17:31:12 -07002839
Adam Lesinskia8018ac2016-05-03 10:18:10 -07002840 final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh;
2841 if (batteryChargeChanged) {
2842 firstToken |= DELTA_BATTERY_CHARGE_FLAG;
Adam Lesinski926969b2016-04-28 17:31:12 -07002843 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002844 dest.writeInt(firstToken);
2845 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
2846 + " deltaTime=" + deltaTime);
2847
2848 if (deltaTimeToken >= DELTA_TIME_INT) {
2849 if (deltaTimeToken == DELTA_TIME_INT) {
2850 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
2851 dest.writeInt((int)deltaTime);
2852 } else {
2853 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
2854 dest.writeLong(deltaTime);
2855 }
2856 }
2857 if (batteryLevelIntChanged) {
2858 dest.writeInt(batteryLevelInt);
2859 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
2860 + Integer.toHexString(batteryLevelInt)
2861 + " batteryLevel=" + cur.batteryLevel
2862 + " batteryTemp=" + cur.batteryTemperature
2863 + " batteryVolt=" + (int)cur.batteryVoltage);
2864 }
2865 if (stateIntChanged) {
2866 dest.writeInt(stateInt);
2867 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
2868 + Integer.toHexString(stateInt)
2869 + " batteryStatus=" + cur.batteryStatus
2870 + " batteryHealth=" + cur.batteryHealth
2871 + " batteryPlugType=" + cur.batteryPlugType
2872 + " states=0x" + Integer.toHexString(cur.states));
2873 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002874 if (state2IntChanged) {
2875 dest.writeInt(cur.states2);
2876 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
2877 + Integer.toHexString(cur.states2));
2878 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002879 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
2880 int wakeLockIndex;
2881 int wakeReasonIndex;
2882 if (cur.wakelockTag != null) {
2883 wakeLockIndex = writeHistoryTag(cur.wakelockTag);
2884 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
2885 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
2886 } else {
2887 wakeLockIndex = 0xffff;
2888 }
2889 if (cur.wakeReasonTag != null) {
2890 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
2891 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
2892 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
2893 } else {
2894 wakeReasonIndex = 0xffff;
2895 }
2896 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002897 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002898 if (cur.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002899 int index = writeHistoryTag(cur.eventTag);
2900 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002901 dest.writeInt(codeAndIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002902 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
2903 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
2904 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002905 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002906 if (computeStepDetails) {
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07002907 if (mPlatformIdleStateCallback != null) {
2908 mCurHistoryStepDetails.statPlatformIdleState =
2909 mPlatformIdleStateCallback.getPlatformLowPowerStats();
2910 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" +
2911 mCurHistoryStepDetails.statPlatformIdleState);
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +00002912
2913 mCurHistoryStepDetails.statSubsystemPowerState =
2914 mPlatformIdleStateCallback.getSubsystemLowPowerStats();
2915 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" +
2916 mCurHistoryStepDetails.statSubsystemPowerState);
2917
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07002918 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002919 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
2920 if (includeStepDetails != 0) {
2921 mCurHistoryStepDetails.writeToParcel(dest);
2922 }
2923 cur.stepDetails = mCurHistoryStepDetails;
2924 mLastHistoryStepDetails = mCurHistoryStepDetails;
2925 } else {
2926 cur.stepDetails = null;
2927 }
2928 if (mLastHistoryStepLevel < cur.batteryLevel) {
2929 mLastHistoryStepDetails = null;
2930 }
2931 mLastHistoryStepLevel = cur.batteryLevel;
Adam Lesinski926969b2016-04-28 17:31:12 -07002932
Adam Lesinskia8018ac2016-05-03 10:18:10 -07002933 if (batteryChargeChanged) {
2934 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh);
2935 dest.writeInt(cur.batteryChargeUAh);
Adam Lesinski926969b2016-04-28 17:31:12 -07002936 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002937 }
2938
2939 private int buildBatteryLevelInt(HistoryItem h) {
2940 return ((((int)h.batteryLevel)<<25)&0xfe000000)
Adam Lesinski3944c812015-11-13 15:54:59 -08002941 | ((((int)h.batteryTemperature)<<15)&0x01ff8000)
2942 | ((((int)h.batteryVoltage)<<1)&0x00007ffe);
2943 }
2944
2945 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) {
2946 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25);
2947 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15);
2948 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002949 }
2950
2951 private int buildStateInt(HistoryItem h) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002952 int plugType = 0;
2953 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
2954 plugType = 1;
2955 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
2956 plugType = 2;
2957 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
2958 plugType = 3;
2959 }
2960 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
2961 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
2962 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
Adam Lesinski926969b2016-04-28 17:31:12 -07002963 | (h.states&(~STATE_BATTERY_MASK));
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002964 }
2965
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002966 private void computeHistoryStepDetails(final HistoryStepDetails out,
2967 final HistoryStepDetails last) {
2968 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out;
2969
2970 // Perform a CPU update right after we do this collection, so we have started
2971 // collecting good data for the next step.
2972 requestImmediateCpuUpdate();
2973
2974 if (last == null) {
2975 // We are not generating a delta, so all we need to do is reset the stats
2976 // we will later be doing a delta from.
2977 final int NU = mUidStats.size();
2978 for (int i=0; i<NU; i++) {
2979 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
2980 uid.mLastStepUserTime = uid.mCurStepUserTime;
2981 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
2982 }
2983 mLastStepCpuUserTime = mCurStepCpuUserTime;
2984 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
2985 mLastStepStatUserTime = mCurStepStatUserTime;
2986 mLastStepStatSystemTime = mCurStepStatSystemTime;
2987 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
2988 mLastStepStatIrqTime = mCurStepStatIrqTime;
2989 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
2990 mLastStepStatIdleTime = mCurStepStatIdleTime;
2991 tmp.clear();
2992 return;
2993 }
2994 if (DEBUG) {
2995 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys="
2996 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime
2997 + " irq=" + mLastStepStatIrqTime + " sirq="
2998 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime);
2999 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys="
3000 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime
3001 + " irq=" + mCurStepStatIrqTime + " sirq="
3002 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime);
3003 }
3004 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime);
3005 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime);
3006 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime);
3007 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime);
3008 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime);
3009 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime);
3010 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime);
3011 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime);
3012 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1;
3013 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0;
3014 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0;
3015 final int NU = mUidStats.size();
3016 for (int i=0; i<NU; i++) {
3017 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3018 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime);
3019 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime);
3020 final int totalTime = totalUTime + totalSTime;
3021 uid.mLastStepUserTime = uid.mCurStepUserTime;
3022 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
3023 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) {
3024 continue;
3025 }
3026 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) {
3027 out.appCpuUid3 = uid.mUid;
3028 out.appCpuUTime3 = totalUTime;
3029 out.appCpuSTime3 = totalSTime;
3030 } else {
3031 out.appCpuUid3 = out.appCpuUid2;
3032 out.appCpuUTime3 = out.appCpuUTime2;
3033 out.appCpuSTime3 = out.appCpuSTime2;
3034 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) {
3035 out.appCpuUid2 = uid.mUid;
3036 out.appCpuUTime2 = totalUTime;
3037 out.appCpuSTime2 = totalSTime;
3038 } else {
3039 out.appCpuUid2 = out.appCpuUid1;
3040 out.appCpuUTime2 = out.appCpuUTime1;
3041 out.appCpuSTime2 = out.appCpuSTime1;
3042 out.appCpuUid1 = uid.mUid;
3043 out.appCpuUTime1 = totalUTime;
3044 out.appCpuSTime1 = totalSTime;
3045 }
3046 }
3047 }
3048 mLastStepCpuUserTime = mCurStepCpuUserTime;
3049 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
3050 mLastStepStatUserTime = mCurStepStatUserTime;
3051 mLastStepStatSystemTime = mCurStepStatSystemTime;
3052 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
3053 mLastStepStatIrqTime = mCurStepStatIrqTime;
3054 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
3055 mLastStepStatIdleTime = mCurStepStatIdleTime;
3056 }
3057
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003058 public void readHistoryDelta(Parcel src, HistoryItem cur) {
3059 int firstToken = src.readInt();
3060 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003061 cur.cmd = HistoryItem.CMD_UPDATE;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003062 cur.numReadInts = 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003063 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
3064 + " deltaTimeToken=" + deltaTimeToken);
3065
3066 if (deltaTimeToken < DELTA_TIME_ABS) {
3067 cur.time += deltaTimeToken;
3068 } else if (deltaTimeToken == DELTA_TIME_ABS) {
3069 cur.time = src.readLong();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003070 cur.numReadInts += 2;
3071 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003072 cur.readFromParcel(src);
3073 return;
3074 } else if (deltaTimeToken == DELTA_TIME_INT) {
3075 int delta = src.readInt();
3076 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003077 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003078 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
3079 } else {
3080 long delta = src.readLong();
3081 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
3082 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003083 cur.numReadInts += 2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003084 }
3085
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003086 final int batteryLevelInt;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003087 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003088 batteryLevelInt = src.readInt();
Adam Lesinski3944c812015-11-13 15:54:59 -08003089 readBatteryLevelInt(batteryLevelInt, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003090 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003091 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
3092 + Integer.toHexString(batteryLevelInt)
3093 + " batteryLevel=" + cur.batteryLevel
3094 + " batteryTemp=" + cur.batteryTemperature
3095 + " batteryVolt=" + (int)cur.batteryVoltage);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003096 } else {
3097 batteryLevelInt = 0;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003098 }
3099
3100 if ((firstToken&DELTA_STATE_FLAG) != 0) {
3101 int stateInt = src.readInt();
Adam Lesinski926969b2016-04-28 17:31:12 -07003102 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08003103 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
3104 & STATE_BATTERY_STATUS_MASK);
3105 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
3106 & STATE_BATTERY_HEALTH_MASK);
3107 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
3108 & STATE_BATTERY_PLUG_MASK);
3109 switch (cur.batteryPlugType) {
3110 case 1:
3111 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
3112 break;
3113 case 2:
3114 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
3115 break;
3116 case 3:
3117 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
3118 break;
3119 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003120 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003121 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
3122 + Integer.toHexString(stateInt)
3123 + " batteryStatus=" + cur.batteryStatus
3124 + " batteryHealth=" + cur.batteryHealth
3125 + " batteryPlugType=" + cur.batteryPlugType
3126 + " states=0x" + Integer.toHexString(cur.states));
3127 } else {
Adam Lesinski926969b2016-04-28 17:31:12 -07003128 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK));
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003129 }
3130
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003131 if ((firstToken&DELTA_STATE2_FLAG) != 0) {
3132 cur.states2 = src.readInt();
3133 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
3134 + Integer.toHexString(cur.states2));
3135 }
3136
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003137 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003138 int indexes = src.readInt();
3139 int wakeLockIndex = indexes&0xffff;
3140 int wakeReasonIndex = (indexes>>16)&0xffff;
3141 if (wakeLockIndex != 0xffff) {
3142 cur.wakelockTag = cur.localWakelockTag;
3143 readHistoryTag(wakeLockIndex, cur.wakelockTag);
3144 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
3145 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
3146 } else {
3147 cur.wakelockTag = null;
3148 }
3149 if (wakeReasonIndex != 0xffff) {
3150 cur.wakeReasonTag = cur.localWakeReasonTag;
3151 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
3152 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
3153 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
3154 } else {
3155 cur.wakeReasonTag = null;
3156 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003157 cur.numReadInts += 1;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003158 } else {
3159 cur.wakelockTag = null;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003160 cur.wakeReasonTag = null;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003161 }
3162
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003163 if ((firstToken&DELTA_EVENT_FLAG) != 0) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003164 cur.eventTag = cur.localEventTag;
3165 final int codeAndIndex = src.readInt();
Dianne Hackborn099bc622014-01-22 13:39:16 -08003166 cur.eventCode = (codeAndIndex&0xffff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003167 final int index = ((codeAndIndex>>16)&0xffff);
3168 readHistoryTag(index, cur.eventTag);
3169 cur.numReadInts += 1;
3170 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
3171 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
3172 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003173 } else {
3174 cur.eventCode = HistoryItem.EVENT_NONE;
3175 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003176
3177 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) {
3178 cur.stepDetails = mReadHistoryStepDetails;
3179 cur.stepDetails.readFromParcel(src);
3180 } else {
3181 cur.stepDetails = null;
3182 }
Adam Lesinski926969b2016-04-28 17:31:12 -07003183
Adam Lesinskia8018ac2016-05-03 10:18:10 -07003184 if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) {
3185 cur.batteryChargeUAh = src.readInt();
Adam Lesinski926969b2016-04-28 17:31:12 -07003186 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003187 }
3188
Dianne Hackbornfc064132014-06-02 12:42:12 -07003189 @Override
3190 public void commitCurrentHistoryBatchLocked() {
3191 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
3192 }
3193
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003194 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003195 if (!mHaveBatteryLevel || !mRecordingHistory) {
3196 return;
3197 }
3198
Dianne Hackborn40c87252014-03-19 16:55:40 -07003199 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003200 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates);
3201 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003202 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003203 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003204 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
3205 + Integer.toHexString(diffStates) + " lastDiff="
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003206 + Integer.toHexString(lastDiffStates) + " diff2="
3207 + Integer.toHexString(diffStates2) + " lastDiff2="
3208 + Integer.toHexString(lastDiffStates2));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003209 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003210 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003211 && (diffStates2&lastDiffStates2) == 0
3212 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
3213 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003214 && mHistoryLastWritten.stepDetails == null
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003215 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003216 || cur.eventCode == HistoryItem.EVENT_NONE)
3217 && mHistoryLastWritten.batteryLevel == cur.batteryLevel
3218 && mHistoryLastWritten.batteryStatus == cur.batteryStatus
3219 && mHistoryLastWritten.batteryHealth == cur.batteryHealth
3220 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
3221 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
3222 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003223 // We can merge this new change in with the last one. Merging is
Dianne Hackborn40c87252014-03-19 16:55:40 -07003224 // allowed as long as only the states have changed, and within those states
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003225 // as long as no bit has changed both between now and the last entry, as
3226 // well as the last entry and the one before it (so we capture any toggles).
3227 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003228 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
3229 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
3230 mHistoryBufferLastPos = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003231 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003232 // If the last written history had a wakelock tag, we need to retain it.
3233 // Note that the condition above made sure that we aren't in a case where
3234 // both it and the current history item have a wakelock tag.
3235 if (mHistoryLastWritten.wakelockTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003236 cur.wakelockTag = cur.localWakelockTag;
3237 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003238 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003239 // If the last written history had a wake reason tag, we need to retain it.
3240 // Note that the condition above made sure that we aren't in a case where
3241 // both it and the current history item have a wakelock tag.
3242 if (mHistoryLastWritten.wakeReasonTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003243 cur.wakeReasonTag = cur.localWakeReasonTag;
3244 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003245 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003246 // If the last written history had an event, we need to retain it.
3247 // Note that the condition above made sure that we aren't in a case where
3248 // both it and the current history item have an event.
3249 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003250 cur.eventCode = mHistoryLastWritten.eventCode;
3251 cur.eventTag = cur.localEventTag;
3252 cur.eventTag.setTo(mHistoryLastWritten.eventTag);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003253 }
Dianne Hackborn1fadab52011-04-14 17:57:33 -07003254 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003255 }
3256
Adam Lesinski45489782016-12-15 23:45:17 -08003257 boolean recordResetDueToOverflow = false;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003258 final int dataSize = mHistoryBuffer.dataSize();
Adam Lesinski45489782016-12-15 23:45:17 -08003259 if (dataSize >= MAX_MAX_HISTORY_BUFFER*3) {
3260 // Clients can't deal with history buffers this large. This only
3261 // really happens when the device is on charger and interacted with
3262 // for long periods of time, like in retail mode. Since the device is
3263 // most likely charged, when unplugged, stats would have reset anyways.
3264 // Reset the stats and mark that we overflowed.
3265 // b/32540341
3266 resetAllStatsLocked();
3267
3268 // Mark that we want to set *OVERFLOW* event and the RESET:START
3269 // events.
3270 recordResetDueToOverflow = true;
3271
3272 } else if (dataSize >= MAX_HISTORY_BUFFER) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003273 if (!mHistoryOverflow) {
3274 mHistoryOverflow = true;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003275 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
3276 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003277 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003278 }
3279
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003280 // After overflow, we allow various bit-wise states to settle to 0.
3281 boolean writeAnyway = false;
3282 final int curStates = cur.states & HistoryItem.SETTLE_TO_ZERO_STATES
3283 & mActiveHistoryStates;
3284 if (mHistoryLastWritten.states != curStates) {
3285 // mActiveHistoryStates keeps track of which bits in .states are now being
3286 // forced to 0.
3287 int old = mActiveHistoryStates;
3288 mActiveHistoryStates &= curStates | ~HistoryItem.SETTLE_TO_ZERO_STATES;
3289 writeAnyway |= old != mActiveHistoryStates;
3290 }
3291 final int curStates2 = cur.states2 & HistoryItem.SETTLE_TO_ZERO_STATES2
3292 & mActiveHistoryStates2;
3293 if (mHistoryLastWritten.states2 != curStates2) {
3294 // mActiveHistoryStates2 keeps track of which bits in .states2 are now being
3295 // forced to 0.
3296 int old = mActiveHistoryStates2;
3297 mActiveHistoryStates2 &= curStates2 | ~HistoryItem.SETTLE_TO_ZERO_STATES2;
3298 writeAnyway |= old != mActiveHistoryStates2;
3299 }
3300
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003301 // Once we've reached the maximum number of items, we only
3302 // record changes to the battery level and the most interesting states.
3303 // Once we've reached the maximum maximum number of items, we only
3304 // record changes to the battery level.
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003305 if (!writeAnyway && mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003306 (dataSize >= MAX_MAX_HISTORY_BUFFER
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003307 || ((mHistoryLastWritten.states^cur.states)
Dianne Hackborn3251b902014-06-20 14:40:53 -07003308 & HistoryItem.MOST_INTERESTING_STATES) == 0
3309 || ((mHistoryLastWritten.states2^cur.states2)
3310 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003311 return;
3312 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003313
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003314 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003315 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003316 }
3317
Adam Lesinski45489782016-12-15 23:45:17 -08003318 if (dataSize == 0 || recordResetDueToOverflow) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003319 // The history is currently empty; we need it to start with a time stamp.
3320 cur.currentTime = System.currentTimeMillis();
Adam Lesinski45489782016-12-15 23:45:17 -08003321 if (recordResetDueToOverflow) {
3322 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
3323 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003324 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur);
3325 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003326 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003327 }
3328
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003329 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
3330 HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003331 if (mIteratingHistory) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003332 throw new IllegalStateException("Can't do this while iterating history!");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003333 }
3334 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
3335 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003336 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003337 mHistoryLastWritten.states &= mActiveHistoryStates;
3338 mHistoryLastWritten.states2 &= mActiveHistoryStates2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003339 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07003340 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003341 cur.wakelockTag = null;
3342 cur.wakeReasonTag = null;
3343 cur.eventCode = HistoryItem.EVENT_NONE;
3344 cur.eventTag = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003345 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
3346 + " now " + mHistoryBuffer.dataPosition()
3347 + " size is now " + mHistoryBuffer.dataSize());
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003348 }
3349
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003350 int mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003351 int mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003352
Dianne Hackborn40c87252014-03-19 16:55:40 -07003353 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003354 if (mTrackRunningHistoryElapsedRealtime != 0) {
3355 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
3356 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
3357 if (diffUptime < (diffElapsed-20)) {
3358 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
3359 mHistoryAddTmp.setTo(mHistoryLastWritten);
3360 mHistoryAddTmp.wakelockTag = null;
3361 mHistoryAddTmp.wakeReasonTag = null;
3362 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
3363 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
3364 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
3365 }
3366 }
3367 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
3368 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
3369 mTrackRunningHistoryUptime = uptimeMs;
3370 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
3371 }
3372
3373 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
3374 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003375
Dianne Hackborne8c88e62011-08-17 19:09:09 -07003376 if (!USE_OLD_HISTORY) {
3377 return;
3378 }
3379
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003380 if (!mHaveBatteryLevel || !mRecordingHistory) {
3381 return;
3382 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003383
3384 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003385 // and no states have since the last recorded entry changed and
3386 // are now resetting back to their original value, then just collapse
3387 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003388 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07003389 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003390 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0
3391 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003392 // If the current is the same as the one before, then we no
3393 // longer need the entry.
3394 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07003395 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003396 && mHistoryLastEnd.sameNonEvent(cur)) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003397 mHistoryLastEnd.next = null;
3398 mHistoryEnd.next = mHistoryCache;
3399 mHistoryCache = mHistoryEnd;
3400 mHistoryEnd = mHistoryLastEnd;
3401 mHistoryLastEnd = null;
3402 } else {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003403 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates);
3404 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003405 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003406 }
3407 return;
3408 }
3409
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003410 mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003411 mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003412
3413 if (mNumHistoryItems == MAX_HISTORY_ITEMS
3414 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07003415 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003416 }
3417
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003418 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
3419 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003420 // record changes to the battery level and the most interesting states.
3421 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003422 // record changes to the battery level.
3423 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003424 == cur.batteryLevel &&
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003425 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003426 || ((mHistoryEnd.states^(cur.states&mActiveHistoryStates))
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003427 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003428 return;
3429 }
3430 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003431
Dianne Hackborn40c87252014-03-19 16:55:40 -07003432 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003433 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003434
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003435 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
Dianne Hackborn40c87252014-03-19 16:55:40 -07003436 String name, int uid) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003437 mHistoryCur.eventCode = code;
3438 mHistoryCur.eventTag = mHistoryCur.localEventTag;
3439 mHistoryCur.eventTag.string = name;
3440 mHistoryCur.eventTag.uid = uid;
Dianne Hackborn4590e522014-03-24 13:36:46 -07003441 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn099bc622014-01-22 13:39:16 -08003442 }
3443
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003444 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003445 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003446 if (rec != null) {
3447 mHistoryCache = rec.next;
3448 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003449 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003450 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003451 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003452
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003453 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003454 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003455
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003456 void addHistoryRecordLocked(HistoryItem rec) {
3457 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003458 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003459 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003460 if (mHistoryEnd != null) {
3461 mHistoryEnd.next = rec;
3462 mHistoryEnd = rec;
3463 } else {
3464 mHistory = mHistoryEnd = rec;
3465 }
3466 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003467
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003468 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003469 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07003470 if (USE_OLD_HISTORY) {
3471 if (mHistory != null) {
3472 mHistoryEnd.next = mHistoryCache;
3473 mHistoryCache = mHistory;
3474 mHistory = mHistoryLastEnd = mHistoryEnd = null;
3475 }
3476 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003477 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07003478
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003479 mHistoryBaseTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003480 mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003481 mTrackRunningHistoryElapsedRealtime = 0;
3482 mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003483
3484 mHistoryBuffer.setDataSize(0);
3485 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003486 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003487 mHistoryLastLastWritten.clear();
3488 mHistoryLastWritten.clear();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003489 mHistoryTagPool.clear();
3490 mNextHistoryTagIdx = 0;
3491 mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003492 mHistoryBufferLastPos = -1;
3493 mHistoryOverflow = false;
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003494 mActiveHistoryStates = 0xffffffff;
3495 mActiveHistoryStates2 = 0xffffffff;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003496 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003497
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003498 public void updateTimeBasesLocked(boolean unplugged, boolean screenOff, long uptime,
3499 long realtime) {
Bookatz867c0d72017-03-07 18:23:42 -08003500 boolean batteryStatusChanged = mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
3501
3502 if (batteryStatusChanged) {
Bookatzc8c44962017-05-11 12:12:54 -07003503 for (int i = 0; i < mUidStats.size(); i++) {
3504 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime);
Bookatz867c0d72017-03-07 18:23:42 -08003505 }
3506 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07003507
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003508 boolean unpluggedScreenOff = unplugged && screenOff;
3509 if (unpluggedScreenOff != mOnBatteryScreenOffTimeBase.isRunning()) {
3510 updateKernelWakelocksLocked();
Adam Lesinskie1f480d2017-02-15 18:51:23 -08003511 updateBatteryPropertiesLocked();
Adam Lesinski72478f02015-06-17 15:39:43 -07003512 if (DEBUG_ENERGY_CPU) {
3513 Slog.d(TAG, "Updating cpu time because screen is now " +
3514 (unpluggedScreenOff ? "off" : "on"));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003515 }
Sudheer Shanka671985f2017-05-19 11:33:42 -07003516 updateCpuTimeLocked(true /* updateCpuFreqData */);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003517 mOnBatteryScreenOffTimeBase.setRunning(unpluggedScreenOff, uptime, realtime);
Bookatzc8c44962017-05-11 12:12:54 -07003518 for (int i = 0; i < mUidStats.size(); i++) {
3519 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime);
3520 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003521 }
3522 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003523
Adam Lesinskie1f480d2017-02-15 18:51:23 -08003524 private void updateBatteryPropertiesLocked() {
3525 try {
3526 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface(
3527 ServiceManager.getService("batteryproperties"));
3528 registrar.scheduleUpdate();
3529 } catch (RemoteException e) {
3530 // Ignore.
3531 }
3532 }
3533
Dianne Hackborn099bc622014-01-22 13:39:16 -08003534 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
3535 mIsolatedUids.put(isolatedUid, appUid);
3536 }
3537
Adam Lesinski61db88f2015-07-01 15:05:07 -07003538 /**
3539 * Schedules a read of the latest cpu times before removing the isolated UID.
3540 * @see #removeIsolatedUidLocked(int)
3541 */
3542 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003543 int curUid = mIsolatedUids.get(isolatedUid, -1);
3544 if (curUid == appUid) {
Adam Lesinski61db88f2015-07-01 15:05:07 -07003545 if (mExternalSync != null) {
3546 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid);
3547 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003548 }
3549 }
3550
Adam Lesinski61db88f2015-07-01 15:05:07 -07003551 /**
3552 * This should only be called after the cpu times have been read.
3553 * @see #scheduleRemoveIsolatedUidLocked(int, int)
3554 */
3555 public void removeIsolatedUidLocked(int isolatedUid) {
3556 mIsolatedUids.delete(isolatedUid);
3557 mKernelUidCpuTimeReader.removeUid(isolatedUid);
Sudheer Shanka6d8dcec2017-06-01 12:09:03 -07003558 mKernelUidCpuFreqTimeReader.removeUid(isolatedUid);
Adam Lesinski61db88f2015-07-01 15:05:07 -07003559 }
3560
Dianne Hackborn099bc622014-01-22 13:39:16 -08003561 public int mapUid(int uid) {
3562 int isolated = mIsolatedUids.get(uid, -1);
3563 return isolated > 0 ? isolated : uid;
3564 }
3565
3566 public void noteEventLocked(int code, String name, int uid) {
3567 uid = mapUid(uid);
Dianne Hackborn37de0982014-05-09 09:32:18 -07003568 if (!mActiveEvents.updateState(code, name, uid, 0)) {
3569 return;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08003570 }
Joe Onoratoabded112016-02-08 16:49:39 -08003571 final long elapsedRealtime = mClocks.elapsedRealtime();
3572 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003573 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08003574 }
3575
Dianne Hackbornd48954f2015-07-22 17:20:33 -07003576 boolean ensureStartClockTime(final long currentTime) {
3577 final long ABOUT_ONE_YEAR = 365*24*60*60*1000L;
3578 if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) {
3579 // If the start clock time has changed by more than a year, then presumably
3580 // the previous time was completely bogus. So we are going to figure out a
3581 // new time based on how much time has elapsed since we started counting.
Joe Onoratoabded112016-02-08 16:49:39 -08003582 mStartClockTime = currentTime - (mClocks.elapsedRealtime()-(mRealtimeStart/1000));
Dianne Hackbornd48954f2015-07-22 17:20:33 -07003583 return true;
3584 }
3585 return false;
3586 }
3587
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07003588 public void noteCurrentTimeChangedLocked() {
3589 final long currentTime = System.currentTimeMillis();
Joe Onoratoabded112016-02-08 16:49:39 -08003590 final long elapsedRealtime = mClocks.elapsedRealtime();
3591 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07003592 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
Dianne Hackbornd48954f2015-07-22 17:20:33 -07003593 ensureStartClockTime(currentTime);
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07003594 }
3595
Dianne Hackborn61659e52014-07-09 16:13:01 -07003596 public void noteProcessStartLocked(String name, int uid) {
3597 uid = mapUid(uid);
3598 if (isOnBattery()) {
3599 Uid u = getUidStatsLocked(uid);
3600 u.getProcessStatsLocked(name).incStartsLocked();
3601 }
3602 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) {
3603 return;
3604 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003605 if (!mRecordAllHistory) {
3606 return;
3607 }
Joe Onoratoabded112016-02-08 16:49:39 -08003608 final long elapsedRealtime = mClocks.elapsedRealtime();
3609 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn61659e52014-07-09 16:13:01 -07003610 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid);
3611 }
3612
Dianne Hackborn1e01d162014-12-04 17:46:42 -08003613 public void noteProcessCrashLocked(String name, int uid) {
3614 uid = mapUid(uid);
3615 if (isOnBattery()) {
3616 Uid u = getUidStatsLocked(uid);
3617 u.getProcessStatsLocked(name).incNumCrashesLocked();
3618 }
3619 }
3620
3621 public void noteProcessAnrLocked(String name, int uid) {
3622 uid = mapUid(uid);
3623 if (isOnBattery()) {
3624 Uid u = getUidStatsLocked(uid);
3625 u.getProcessStatsLocked(name).incNumAnrsLocked();
3626 }
3627 }
3628
Dianne Hackborna8d10942015-11-19 17:55:19 -08003629 public void noteUidProcessStateLocked(int uid, int state) {
Dianne Hackborn61659e52014-07-09 16:13:01 -07003630 uid = mapUid(uid);
Dianne Hackborna8d10942015-11-19 17:55:19 -08003631 getUidStatsLocked(uid).updateUidProcessStateLocked(state);
Dianne Hackborn61659e52014-07-09 16:13:01 -07003632 }
3633
3634 public void noteProcessFinishLocked(String name, int uid) {
3635 uid = mapUid(uid);
3636 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) {
3637 return;
3638 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003639 if (!mRecordAllHistory) {
3640 return;
3641 }
Joe Onoratoabded112016-02-08 16:49:39 -08003642 final long elapsedRealtime = mClocks.elapsedRealtime();
3643 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003644 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid);
Dianne Hackborn61659e52014-07-09 16:13:01 -07003645 }
3646
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003647 public void noteSyncStartLocked(String name, int uid) {
3648 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003649 final long elapsedRealtime = mClocks.elapsedRealtime();
3650 final long uptime = mClocks.uptimeMillis();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003651 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime);
3652 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
3653 return;
3654 }
3655 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid);
3656 }
3657
3658 public void noteSyncFinishLocked(String name, int uid) {
3659 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003660 final long elapsedRealtime = mClocks.elapsedRealtime();
3661 final long uptime = mClocks.uptimeMillis();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003662 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime);
3663 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
3664 return;
3665 }
3666 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid);
3667 }
3668
3669 public void noteJobStartLocked(String name, int uid) {
3670 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003671 final long elapsedRealtime = mClocks.elapsedRealtime();
3672 final long uptime = mClocks.uptimeMillis();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003673 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime);
3674 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
3675 return;
3676 }
3677 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid);
3678 }
3679
Dianne Hackborn94326cb2017-06-28 16:17:20 -07003680 public void noteJobFinishLocked(String name, int uid, int stopReason) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003681 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003682 final long elapsedRealtime = mClocks.elapsedRealtime();
3683 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn94326cb2017-06-28 16:17:20 -07003684 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime, stopReason);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003685 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
3686 return;
3687 }
3688 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid);
3689 }
3690
Dianne Hackborn1e383822015-04-10 14:02:33 -07003691 public void noteAlarmStartLocked(String name, int uid) {
3692 if (!mRecordAllHistory) {
3693 return;
3694 }
3695 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003696 final long elapsedRealtime = mClocks.elapsedRealtime();
3697 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn1e383822015-04-10 14:02:33 -07003698 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_START, name, uid, 0)) {
3699 return;
3700 }
3701 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid);
3702 }
3703
3704 public void noteAlarmFinishLocked(String name, int uid) {
3705 if (!mRecordAllHistory) {
3706 return;
3707 }
3708 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003709 final long elapsedRealtime = mClocks.elapsedRealtime();
3710 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn1e383822015-04-10 14:02:33 -07003711 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) {
3712 return;
3713 }
3714 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid);
3715 }
3716
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003717 private void requestWakelockCpuUpdate() {
3718 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
3719 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
3720 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
3721 }
3722 }
3723
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003724 private void requestImmediateCpuUpdate() {
3725 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
3726 mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS);
3727 }
3728
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003729 public void setRecordAllHistoryLocked(boolean enabled) {
3730 mRecordAllHistory = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003731 if (!enabled) {
3732 // Clear out any existing state.
3733 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK);
Dianne Hackborn1e383822015-04-10 14:02:33 -07003734 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003735 // Record the currently running processes as stopping, now that we are no
3736 // longer tracking them.
3737 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
3738 HistoryItem.EVENT_PROC);
3739 if (active != null) {
Joe Onoratoabded112016-02-08 16:49:39 -08003740 long mSecRealtime = mClocks.elapsedRealtime();
3741 final long mSecUptime = mClocks.uptimeMillis();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003742 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
3743 SparseIntArray uids = ent.getValue();
3744 for (int j=0; j<uids.size(); j++) {
3745 addHistoryEventLocked(mSecRealtime, mSecUptime,
3746 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j));
3747 }
3748 }
3749 }
3750 } else {
3751 // Record the currently running processes as starting, now that we are tracking them.
3752 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
3753 HistoryItem.EVENT_PROC);
3754 if (active != null) {
Joe Onoratoabded112016-02-08 16:49:39 -08003755 long mSecRealtime = mClocks.elapsedRealtime();
3756 final long mSecUptime = mClocks.uptimeMillis();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003757 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
3758 SparseIntArray uids = ent.getValue();
3759 for (int j=0; j<uids.size(); j++) {
3760 addHistoryEventLocked(mSecRealtime, mSecUptime,
3761 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j));
3762 }
3763 }
3764 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003765 }
3766 }
3767
Dianne Hackborn9a755432014-05-15 17:05:22 -07003768 public void setNoAutoReset(boolean enabled) {
3769 mNoAutoReset = enabled;
3770 }
3771
Amith Yamasani674c9bb2017-02-01 09:45:17 -08003772 public void setPretendScreenOff(boolean pretendScreenOff) {
3773 mPretendScreenOff = pretendScreenOff;
3774 noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON);
3775 }
3776
Dianne Hackborn9a755432014-05-15 17:05:22 -07003777 private String mInitialAcquireWakeName;
3778 private int mInitialAcquireWakeUid = -1;
3779
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08003780 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn40c87252014-03-19 16:55:40 -07003781 boolean unimportantForLogging, long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003782 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003783 if (type == WAKE_TYPE_PARTIAL) {
3784 // Only care about partial wake locks, since full wake locks
3785 // will be canceled when the user puts the screen to sleep.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003786 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07003787 if (historyName == null) {
3788 historyName = name;
3789 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003790 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07003791 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
3792 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07003793 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07003794 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07003795 }
3796 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003797 if (mWakeLockNesting == 0) {
3798 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
3799 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
3800 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003801 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003802 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07003803 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003804 mWakeLockImportant = !unimportantForLogging;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003805 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07003806 } else if (!mWakeLockImportant && !unimportantForLogging
3807 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003808 if (mHistoryLastWritten.wakelockTag != null) {
3809 // We'll try to update the last tag.
3810 mHistoryLastWritten.wakelockTag = null;
3811 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003812 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07003813 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003814 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003815 }
3816 mWakeLockImportant = true;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003817 }
3818 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003819 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003820 if (uid >= 0) {
Adam Lesinski72478f02015-06-17 15:39:43 -07003821 if (mOnBatteryScreenOffTimeBase.isRunning()) {
3822 // We only update the cpu time when a wake lock is acquired if the screen is off.
3823 // If the screen is on, we don't distribute the power amongst partial wakelocks.
3824 if (DEBUG_ENERGY_CPU) {
3825 Slog.d(TAG, "Updating cpu time because of +wake_lock");
3826 }
3827 requestWakelockCpuUpdate();
3828 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003829 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003830 }
3831 }
3832
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003833 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type,
3834 long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003835 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003836 if (type == WAKE_TYPE_PARTIAL) {
3837 mWakeLockNesting--;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003838 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07003839 if (historyName == null) {
3840 historyName = name;
3841 }
3842 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
3843 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07003844 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07003845 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07003846 }
3847 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003848 if (mWakeLockNesting == 0) {
3849 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
3850 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
3851 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn37de0982014-05-09 09:32:18 -07003852 mInitialAcquireWakeName = null;
3853 mInitialAcquireWakeUid = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003854 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003855 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003856 }
3857 if (uid >= 0) {
Adam Lesinski72478f02015-06-17 15:39:43 -07003858 if (mOnBatteryScreenOffTimeBase.isRunning()) {
3859 if (DEBUG_ENERGY_CPU) {
3860 Slog.d(TAG, "Updating cpu time because of -wake_lock");
3861 }
3862 requestWakelockCpuUpdate();
3863 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003864 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003865 }
3866 }
3867
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08003868 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
3869 String historyName, int type, boolean unimportantForLogging) {
Joe Onoratoabded112016-02-08 16:49:39 -08003870 final long elapsedRealtime = mClocks.elapsedRealtime();
3871 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003872 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003873 for (int i=0; i<N; i++) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003874 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -07003875 elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003876 }
3877 }
3878
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003879 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
3880 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003881 String newHistoryName, int newType, boolean newUnimportantForLogging) {
Joe Onoratoabded112016-02-08 16:49:39 -08003882 final long elapsedRealtime = mClocks.elapsedRealtime();
3883 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003884 // For correct semantics, we start the need worksources first, so that we won't
3885 // make inappropriate history items as if all wake locks went away and new ones
3886 // appeared. This is okay because tracking of wake locks allows nesting.
Dianne Hackborn40c87252014-03-19 16:55:40 -07003887 final int NN = newWs.size();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003888 for (int i=0; i<NN; i++) {
3889 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
Dianne Hackborn40c87252014-03-19 16:55:40 -07003890 newUnimportantForLogging, elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003891 }
3892 final int NO = ws.size();
3893 for (int i=0; i<NO; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003894 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003895 }
3896 }
3897
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003898 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
3899 String historyName, int type) {
Joe Onoratoabded112016-02-08 16:49:39 -08003900 final long elapsedRealtime = mClocks.elapsedRealtime();
3901 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003902 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003903 for (int i=0; i<N; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003904 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003905 }
3906 }
3907
Dianne Hackbornd0db6f02016-07-18 14:14:20 -07003908 public void noteLongPartialWakelockStart(String name, String historyName, int uid) {
3909 uid = mapUid(uid);
3910 final long elapsedRealtime = mClocks.elapsedRealtime();
3911 final long uptime = mClocks.uptimeMillis();
3912 if (historyName == null) {
3913 historyName = name;
3914 }
3915 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid,
3916 0)) {
3917 return;
3918 }
3919 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
3920 historyName, uid);
3921 }
3922
3923 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) {
3924 uid = mapUid(uid);
3925 final long elapsedRealtime = mClocks.elapsedRealtime();
3926 final long uptime = mClocks.uptimeMillis();
3927 if (historyName == null) {
3928 historyName = name;
3929 }
3930 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid,
3931 0)) {
3932 return;
3933 }
3934 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
3935 historyName, uid);
3936 }
3937
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003938 void aggregateLastWakeupUptimeLocked(long uptimeMs) {
3939 if (mLastWakeupReason != null) {
3940 long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07003941 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
Adam Lesinski757c6ea2016-04-21 09:55:41 -07003942 timer.add(deltaUptime * 1000, 1); // time in in microseconds
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003943 mLastWakeupReason = null;
3944 }
3945 }
3946
3947 public void noteWakeupReasonLocked(String reason) {
Joe Onoratoabded112016-02-08 16:49:39 -08003948 final long elapsedRealtime = mClocks.elapsedRealtime();
3949 final long uptime = mClocks.uptimeMillis();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07003950 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": "
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003951 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003952 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003953 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
3954 mHistoryCur.wakeReasonTag.string = reason;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003955 mHistoryCur.wakeReasonTag.uid = 0;
3956 mLastWakeupReason = reason;
3957 mLastWakeupUptimeMs = uptime;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003958 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003959 }
3960
Adam Lesinski72478f02015-06-17 15:39:43 -07003961 public boolean startAddingCpuLocked() {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003962 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
Adam Lesinski72478f02015-06-17 15:39:43 -07003963 return mOnBatteryInternal;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003964 }
3965
Adam Lesinski72478f02015-06-17 15:39:43 -07003966 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime,
3967 int statSystemTime, int statIOWaitTime, int statIrqTime,
3968 int statSoftIrqTime, int statIdleTime) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003969 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
3970 + " user=" + statUserTime + " sys=" + statSystemTime
3971 + " io=" + statIOWaitTime + " irq=" + statIrqTime
3972 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime);
3973 mCurStepCpuUserTime += totalUTime;
3974 mCurStepCpuSystemTime += totalSTime;
3975 mCurStepStatUserTime += statUserTime;
3976 mCurStepStatSystemTime += statSystemTime;
3977 mCurStepStatIOWaitTime += statIOWaitTime;
3978 mCurStepStatIrqTime += statIrqTime;
3979 mCurStepStatSoftIrqTime += statSoftIrqTime;
3980 mCurStepStatIdleTime += statIdleTime;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07003981 }
3982
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003983 public void noteProcessDiedLocked(int uid, int pid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003984 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003985 Uid u = mUidStats.get(uid);
3986 if (u != null) {
3987 u.mPids.remove(pid);
3988 }
3989 }
3990
3991 public long getProcessWakeTime(int uid, int pid, long realtime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003992 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003993 Uid u = mUidStats.get(uid);
3994 if (u != null) {
3995 Uid.Pid p = u.mPids.get(pid);
3996 if (p != null) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003997 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003998 }
3999 }
4000 return 0;
4001 }
4002
Dianne Hackborn287952c2010-09-22 22:34:31 -07004003 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004004 uid = mapUid(uid);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004005 Uid u = mUidStats.get(uid);
4006 if (u != null) {
4007 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
4008 }
4009 }
4010
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004011 int mSensorNesting;
4012
4013 public void noteStartSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004014 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004015 final long elapsedRealtime = mClocks.elapsedRealtime();
4016 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004017 if (mSensorNesting == 0) {
4018 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
4019 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
4020 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004021 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004022 }
4023 mSensorNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004024 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004025 }
4026
4027 public void noteStopSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004028 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004029 final long elapsedRealtime = mClocks.elapsedRealtime();
4030 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004031 mSensorNesting--;
4032 if (mSensorNesting == 0) {
4033 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
4034 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
4035 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004036 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004037 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004038 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004039 }
4040
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004041 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004042
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004043 public void noteStartGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004044 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004045 final long elapsedRealtime = mClocks.elapsedRealtime();
4046 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004047 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004048 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004049 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
4050 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004051 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004052 }
4053 mGpsNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004054 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004055 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004056
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004057 public void noteStopGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004058 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004059 final long elapsedRealtime = mClocks.elapsedRealtime();
4060 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004061 mGpsNesting--;
4062 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004063 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004064 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
4065 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004066 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004067 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004068 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004069 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004070
Jeff Browne95c3cd2014-05-02 16:59:26 -07004071 public void noteScreenStateLocked(int state) {
Amith Yamasani674c9bb2017-02-01 09:45:17 -08004072 state = mPretendScreenOff ? Display.STATE_OFF : state;
Santos Cordone94f0502017-02-24 12:31:20 -08004073
4074 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the
4075 // original 4 are mapped to one of the originals.
4076 if (state > MAX_TRACKED_SCREEN_STATE) {
4077 switch (state) {
4078 case Display.STATE_VR:
4079 state = Display.STATE_ON;
4080 break;
4081 default:
4082 Slog.wtf(TAG, "Unknown screen state (not mapped): " + state);
4083 break;
4084 }
4085 }
4086
Jeff Browne95c3cd2014-05-02 16:59:26 -07004087 if (mScreenState != state) {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08004088 recordDailyStatsIfNeededLocked(true);
Jeff Browne95c3cd2014-05-02 16:59:26 -07004089 final int oldState = mScreenState;
4090 mScreenState = state;
4091 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
4092 + ", newState=" + Display.stateToString(state));
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004093
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07004094 if (state != Display.STATE_UNKNOWN) {
4095 int stepState = state-1;
Santos Cordone94f0502017-02-24 12:31:20 -08004096 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) {
4097 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState;
4098 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07004099 } else {
4100 Slog.wtf(TAG, "Unexpected screen state: " + state);
4101 }
4102 }
4103
Jeff Browne95c3cd2014-05-02 16:59:26 -07004104 if (state == Display.STATE_ON) {
4105 // Screen turning on.
Joe Onoratoabded112016-02-08 16:49:39 -08004106 final long elapsedRealtime = mClocks.elapsedRealtime();
4107 final long uptime = mClocks.uptimeMillis();
Jeff Browne95c3cd2014-05-02 16:59:26 -07004108 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
4109 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
4110 + Integer.toHexString(mHistoryCur.states));
4111 addHistoryRecordLocked(elapsedRealtime, uptime);
4112 mScreenOnTimer.startRunningLocked(elapsedRealtime);
4113 if (mScreenBrightnessBin >= 0) {
4114 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
4115 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004116
Jeff Browne95c3cd2014-05-02 16:59:26 -07004117 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), false,
Joe Onoratoabded112016-02-08 16:49:39 -08004118 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004119
Jeff Browne95c3cd2014-05-02 16:59:26 -07004120 // Fake a wake lock, so we consider the device waked as long
4121 // as the screen is on.
4122 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
4123 elapsedRealtime, uptime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004124
Jeff Browne95c3cd2014-05-02 16:59:26 -07004125 // Update discharge amounts.
4126 if (mOnBatteryInternal) {
4127 updateDischargeScreenLevelsLocked(false, true);
4128 }
4129 } else if (oldState == Display.STATE_ON) {
4130 // Screen turning off or dozing.
Joe Onoratoabded112016-02-08 16:49:39 -08004131 final long elapsedRealtime = mClocks.elapsedRealtime();
4132 final long uptime = mClocks.uptimeMillis();
Jeff Browne95c3cd2014-05-02 16:59:26 -07004133 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
4134 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
4135 + Integer.toHexString(mHistoryCur.states));
4136 addHistoryRecordLocked(elapsedRealtime, uptime);
4137 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
4138 if (mScreenBrightnessBin >= 0) {
4139 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
4140 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004141
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004142 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL,
Jeff Browne95c3cd2014-05-02 16:59:26 -07004143 elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004144
Jeff Browne95c3cd2014-05-02 16:59:26 -07004145 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), true,
Joe Onoratoabded112016-02-08 16:49:39 -08004146 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004147
Jeff Browne95c3cd2014-05-02 16:59:26 -07004148 // Update discharge amounts.
4149 if (mOnBatteryInternal) {
4150 updateDischargeScreenLevelsLocked(true, false);
4151 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004152 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07004153 }
4154 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004155
Dianne Hackborn617f8772009-03-31 15:04:46 -07004156 public void noteScreenBrightnessLocked(int brightness) {
4157 // Bin the brightness.
4158 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
4159 if (bin < 0) bin = 0;
4160 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
4161 if (mScreenBrightnessBin != bin) {
Joe Onoratoabded112016-02-08 16:49:39 -08004162 final long elapsedRealtime = mClocks.elapsedRealtime();
4163 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004164 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
4165 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004166 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
4167 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004168 addHistoryRecordLocked(elapsedRealtime, uptime);
Jeff Browne95c3cd2014-05-02 16:59:26 -07004169 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07004170 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004171 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004172 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004173 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004174 }
4175 mScreenBrightnessBin = bin;
4176 }
4177 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004178
Dianne Hackborn617f8772009-03-31 15:04:46 -07004179 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004180 if (mOnBatteryInternal) {
4181 uid = mapUid(uid);
4182 getUidStatsLocked(uid).noteUserActivityLocked(event);
4183 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004184 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004185
Dianne Hackborn280a64e2015-07-13 14:48:08 -07004186 public void noteWakeUpLocked(String reason, int reasonUid) {
Joe Onoratoabded112016-02-08 16:49:39 -08004187 final long elapsedRealtime = mClocks.elapsedRealtime();
4188 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn280a64e2015-07-13 14:48:08 -07004189 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP,
4190 reason, reasonUid);
4191 }
4192
Jeff Browne95c3cd2014-05-02 16:59:26 -07004193 public void noteInteractiveLocked(boolean interactive) {
4194 if (mInteractive != interactive) {
Joe Onoratoabded112016-02-08 16:49:39 -08004195 final long elapsedRealtime = mClocks.elapsedRealtime();
Jeff Browne95c3cd2014-05-02 16:59:26 -07004196 mInteractive = interactive;
4197 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
4198 if (interactive) {
4199 mInteractiveTimer.startRunningLocked(elapsedRealtime);
4200 } else {
4201 mInteractiveTimer.stopRunningLocked(elapsedRealtime);
4202 }
4203 }
4204 }
4205
Dianne Hackborn1e01d162014-12-04 17:46:42 -08004206 public void noteConnectivityChangedLocked(int type, String extra) {
Joe Onoratoabded112016-02-08 16:49:39 -08004207 final long elapsedRealtime = mClocks.elapsedRealtime();
4208 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08004209 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
4210 extra, type);
4211 mNumConnectivityChange++;
4212 }
4213
Adam Lesinski5f056f62016-07-14 16:56:08 -07004214 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis,
4215 final long uptimeMillis, int uid) {
4216 uid = mapUid(uid);
4217 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
4218 uid);
4219 getUidStatsLocked(uid).noteMobileRadioApWakeupLocked();
4220 }
4221
Adam Lesinski14ae39a2017-05-26 11:50:40 -07004222 /**
4223 * Updates the radio power state and returns true if an external stats collection should occur.
4224 */
4225 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) {
Joe Onoratoabded112016-02-08 16:49:39 -08004226 final long elapsedRealtime = mClocks.elapsedRealtime();
4227 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004228 if (mMobileRadioPowerState != powerState) {
4229 long realElapsedRealtimeMs;
4230 final boolean active =
4231 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
4232 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
4233 if (active) {
Adam Lesinski5f056f62016-07-14 16:56:08 -07004234 if (uid > 0) {
4235 noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid);
4236 }
4237
Adam Lesinski9acfd812016-04-19 18:29:50 -07004238 mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004239 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
4240 } else {
4241 realElapsedRealtimeMs = timestampNs / (1000*1000);
Dianne Hackbornf7097a52014-05-13 09:56:14 -07004242 long lastUpdateTimeMs = mMobileRadioActiveStartTime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004243 if (realElapsedRealtimeMs < lastUpdateTimeMs) {
4244 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
4245 + " is before start time " + lastUpdateTimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004246 realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004247 } else if (realElapsedRealtimeMs < elapsedRealtime) {
4248 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
4249 - realElapsedRealtimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004250 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004251 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
4252 }
4253 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
4254 + Integer.toHexString(mHistoryCur.states));
4255 addHistoryRecordLocked(elapsedRealtime, uptime);
4256 mMobileRadioPowerState = powerState;
4257 if (active) {
4258 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
4259 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
4260 } else {
4261 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004262 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
Adam Lesinski14ae39a2017-05-26 11:50:40 -07004263 // Tell the caller to collect radio network/power stats.
4264 return true;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004265 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004266 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -07004267 return false;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004268 }
4269
Adam Lesinski14ae39a2017-05-26 11:50:40 -07004270 public void notePowerSaveModeLocked(boolean enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004271 if (mPowerSaveModeEnabled != enabled) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07004272 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0;
4273 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState;
4274 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
Joe Onoratoabded112016-02-08 16:49:39 -08004275 final long elapsedRealtime = mClocks.elapsedRealtime();
4276 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004277 mPowerSaveModeEnabled = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004278 if (enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004279 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
4280 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004281 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004282 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004283 } else {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004284 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
4285 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004286 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004287 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004288 }
4289 addHistoryRecordLocked(elapsedRealtime, uptime);
4290 }
4291 }
4292
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004293 public void noteDeviceIdleModeLocked(int mode, String activeReason, int activeUid) {
Joe Onoratoabded112016-02-08 16:49:39 -08004294 final long elapsedRealtime = mClocks.elapsedRealtime();
4295 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07004296 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004297 if (mDeviceIdling && !nowIdling && activeReason == null) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004298 // We don't go out of general idling mode until explicitly taken out of
4299 // device idle through going active or significant motion.
4300 nowIdling = true;
4301 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004302 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT;
4303 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) {
4304 // We don't go out of general light idling mode until explicitly taken out of
4305 // device idle through going active or significant motion.
4306 nowLightIdling = true;
4307 }
4308 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) {
4309 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
4310 activeReason, activeUid);
4311 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004312 if (mDeviceIdling != nowIdling) {
4313 mDeviceIdling = nowIdling;
4314 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0;
4315 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState;
4316 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004317 if (nowIdling) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004318 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime);
4319 } else {
4320 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime);
4321 }
4322 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004323 if (mDeviceLightIdling != nowLightIdling) {
4324 mDeviceLightIdling = nowLightIdling;
4325 if (nowLightIdling) {
4326 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004327 } else {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004328 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004329 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004330 }
4331 if (mDeviceIdleMode != mode) {
4332 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK)
4333 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT);
4334 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: "
4335 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004336 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004337 long lastDuration = elapsedRealtime - mLastIdleTimeStart;
4338 mLastIdleTimeStart = elapsedRealtime;
4339 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) {
4340 if (lastDuration > mLongestLightIdleTime) {
4341 mLongestLightIdleTime = lastDuration;
4342 }
4343 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07004344 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004345 if (lastDuration > mLongestFullIdleTime) {
4346 mLongestFullIdleTime = lastDuration;
4347 }
4348 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime);
4349 }
4350 if (mode == DEVICE_IDLE_MODE_LIGHT) {
4351 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07004352 } else if (mode == DEVICE_IDLE_MODE_DEEP) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004353 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime);
4354 }
4355 mDeviceIdleMode = mode;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004356 }
4357 }
4358
4359 public void notePackageInstalledLocked(String pkgName, int versionCode) {
Joe Onoratoabded112016-02-08 16:49:39 -08004360 final long elapsedRealtime = mClocks.elapsedRealtime();
4361 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004362 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED,
4363 pkgName, versionCode);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004364 PackageChange pc = new PackageChange();
4365 pc.mPackageName = pkgName;
4366 pc.mUpdate = true;
4367 pc.mVersionCode = versionCode;
4368 addPackageChange(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004369 }
4370
4371 public void notePackageUninstalledLocked(String pkgName) {
Joe Onoratoabded112016-02-08 16:49:39 -08004372 final long elapsedRealtime = mClocks.elapsedRealtime();
4373 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004374 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
4375 pkgName, 0);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004376 PackageChange pc = new PackageChange();
4377 pc.mPackageName = pkgName;
4378 pc.mUpdate = true;
4379 addPackageChange(pc);
4380 }
4381
4382 private void addPackageChange(PackageChange pc) {
4383 if (mDailyPackageChanges == null) {
4384 mDailyPackageChanges = new ArrayList<>();
4385 }
4386 mDailyPackageChanges.add(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004387 }
4388
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004389 public void notePhoneOnLocked() {
4390 if (!mPhoneOn) {
Joe Onoratoabded112016-02-08 16:49:39 -08004391 final long elapsedRealtime = mClocks.elapsedRealtime();
4392 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07004393 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004394 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
4395 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004396 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004397 mPhoneOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004398 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004399 }
4400 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004401
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004402 public void notePhoneOffLocked() {
4403 if (mPhoneOn) {
Joe Onoratoabded112016-02-08 16:49:39 -08004404 final long elapsedRealtime = mClocks.elapsedRealtime();
4405 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07004406 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004407 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
4408 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004409 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004410 mPhoneOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004411 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004412 }
4413 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004414
Dianne Hackborn3251b902014-06-20 14:40:53 -07004415 void stopAllPhoneSignalStrengthTimersLocked(int except) {
Joe Onoratoabded112016-02-08 16:49:39 -08004416 final long elapsedRealtime = mClocks.elapsedRealtime();
Wink Saville52840902011-02-18 12:40:47 -08004417 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004418 if (i == except) {
4419 continue;
4420 }
4421 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004422 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004423 }
4424 }
4425 }
4426
Dianne Hackborne4a59512010-12-07 11:08:07 -08004427 private int fixPhoneServiceState(int state, int signalBin) {
4428 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
4429 // In this case we will always be STATE_OUT_OF_SERVICE, so need
4430 // to infer that we are scanning from other data.
4431 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08004432 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004433 state = ServiceState.STATE_IN_SERVICE;
4434 }
4435 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004436
Dianne Hackborne4a59512010-12-07 11:08:07 -08004437 return state;
4438 }
4439
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004440 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004441 boolean scanning = false;
4442 boolean newHistory = false;
4443
4444 mPhoneServiceStateRaw = state;
4445 mPhoneSimStateRaw = simState;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004446 mPhoneSignalStrengthBinRaw = strengthBin;
4447
Joe Onoratoabded112016-02-08 16:49:39 -08004448 final long elapsedRealtime = mClocks.elapsedRealtime();
4449 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne4a59512010-12-07 11:08:07 -08004450
4451 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
4452 // In this case we will always be STATE_OUT_OF_SERVICE, so need
4453 // to infer that we are scanning from other data.
4454 if (state == ServiceState.STATE_OUT_OF_SERVICE
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004455 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004456 state = ServiceState.STATE_IN_SERVICE;
4457 }
4458 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004459
4460 // If the phone is powered off, stop all timers.
4461 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004462 strengthBin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07004463
Dianne Hackborne4a59512010-12-07 11:08:07 -08004464 // If we are in service, make sure the correct signal string timer is running.
4465 } else if (state == ServiceState.STATE_IN_SERVICE) {
4466 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004467
4468 // If we're out of service, we are in the lowest signal strength
4469 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07004470 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004471 scanning = true;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004472 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07004473 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004474 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08004475 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004476 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
4477 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004478 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
Amith Yamasanif37447b2009-10-08 18:28:01 -07004479 }
4480 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004481
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004482 if (!scanning) {
4483 // If we are no longer scanning, then stop the scanning timer.
4484 if (mPhoneSignalScanningTimer.isRunningLocked()) {
4485 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
4486 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
4487 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08004488 newHistory = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004489 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004490 }
4491 }
4492
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004493 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004494 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
4495 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004496 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004497 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08004498 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004499 mPhoneServiceState = state;
4500 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08004501
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004502 if (mPhoneSignalStrengthBin != strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004503 if (mPhoneSignalStrengthBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004504 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004505 elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004506 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004507 if (strengthBin >= 0) {
4508 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004509 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004510 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07004511 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
4512 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004513 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
Dianne Hackborne4a59512010-12-07 11:08:07 -08004514 + Integer.toHexString(mHistoryCur.states));
4515 newHistory = true;
4516 } else {
Dianne Hackborn3251b902014-06-20 14:40:53 -07004517 stopAllPhoneSignalStrengthTimersLocked(-1);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004518 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004519 mPhoneSignalStrengthBin = strengthBin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08004520 }
4521
4522 if (newHistory) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07004523 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004524 }
4525 }
4526
4527 /**
4528 * Telephony stack updates the phone state.
4529 * @param state phone state from ServiceState.getState()
4530 */
4531 public void notePhoneStateLocked(int state, int simState) {
4532 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004533 }
4534
Wink Savillee9b06d72009-05-18 21:47:50 -07004535 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07004536 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08004537 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08004538 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004539 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004540
Dianne Hackborn627bba72009-03-24 22:32:56 -07004541 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
4542 int bin = DATA_CONNECTION_NONE;
4543 if (hasData) {
4544 switch (dataType) {
4545 case TelephonyManager.NETWORK_TYPE_EDGE:
4546 bin = DATA_CONNECTION_EDGE;
4547 break;
4548 case TelephonyManager.NETWORK_TYPE_GPRS:
4549 bin = DATA_CONNECTION_GPRS;
4550 break;
4551 case TelephonyManager.NETWORK_TYPE_UMTS:
4552 bin = DATA_CONNECTION_UMTS;
4553 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004554 case TelephonyManager.NETWORK_TYPE_CDMA:
4555 bin = DATA_CONNECTION_CDMA;
4556 break;
4557 case TelephonyManager.NETWORK_TYPE_EVDO_0:
4558 bin = DATA_CONNECTION_EVDO_0;
4559 break;
4560 case TelephonyManager.NETWORK_TYPE_EVDO_A:
4561 bin = DATA_CONNECTION_EVDO_A;
4562 break;
4563 case TelephonyManager.NETWORK_TYPE_1xRTT:
4564 bin = DATA_CONNECTION_1xRTT;
4565 break;
4566 case TelephonyManager.NETWORK_TYPE_HSDPA:
4567 bin = DATA_CONNECTION_HSDPA;
4568 break;
4569 case TelephonyManager.NETWORK_TYPE_HSUPA:
4570 bin = DATA_CONNECTION_HSUPA;
4571 break;
4572 case TelephonyManager.NETWORK_TYPE_HSPA:
4573 bin = DATA_CONNECTION_HSPA;
4574 break;
4575 case TelephonyManager.NETWORK_TYPE_IDEN:
4576 bin = DATA_CONNECTION_IDEN;
4577 break;
4578 case TelephonyManager.NETWORK_TYPE_EVDO_B:
4579 bin = DATA_CONNECTION_EVDO_B;
4580 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07004581 case TelephonyManager.NETWORK_TYPE_LTE:
4582 bin = DATA_CONNECTION_LTE;
4583 break;
4584 case TelephonyManager.NETWORK_TYPE_EHRPD:
4585 bin = DATA_CONNECTION_EHRPD;
4586 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08004587 case TelephonyManager.NETWORK_TYPE_HSPAP:
4588 bin = DATA_CONNECTION_HSPAP;
4589 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07004590 default:
4591 bin = DATA_CONNECTION_OTHER;
4592 break;
4593 }
4594 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004595 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004596 if (mPhoneDataConnectionType != bin) {
Joe Onoratoabded112016-02-08 16:49:39 -08004597 final long elapsedRealtime = mClocks.elapsedRealtime();
4598 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004599 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
4600 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004601 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
4602 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004603 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004604 if (mPhoneDataConnectionType >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004605 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004606 elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004607 }
4608 mPhoneDataConnectionType = bin;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004609 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004610 }
4611 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004612
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004613 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004614 if (!mWifiOn) {
Joe Onoratoabded112016-02-08 16:49:39 -08004615 final long elapsedRealtime = mClocks.elapsedRealtime();
4616 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07004617 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004618 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
4619 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004620 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07004621 mWifiOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004622 mWifiOnTimer.startRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004623 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI);
The Android Open Source Project10592532009-03-18 17:39:46 -07004624 }
4625 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004626
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004627 public void noteWifiOffLocked() {
Joe Onoratoabded112016-02-08 16:49:39 -08004628 final long elapsedRealtime = mClocks.elapsedRealtime();
4629 final long uptime = mClocks.uptimeMillis();
The Android Open Source Project10592532009-03-18 17:39:46 -07004630 if (mWifiOn) {
Dianne Hackborn3251b902014-06-20 14:40:53 -07004631 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004632 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
4633 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004634 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07004635 mWifiOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004636 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004637 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI);
The Android Open Source Project10592532009-03-18 17:39:46 -07004638 }
4639 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004640
4641 public void noteAudioOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004642 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004643 final long elapsedRealtime = mClocks.elapsedRealtime();
4644 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004645 if (mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004646 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004647 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
4648 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004649 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004650 mAudioOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004651 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004652 mAudioOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004653 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004654 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004655
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004656 public void noteAudioOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004657 if (mAudioOnNesting == 0) {
4658 return;
4659 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08004660 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004661 final long elapsedRealtime = mClocks.elapsedRealtime();
4662 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004663 if (--mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004664 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004665 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
4666 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004667 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004668 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004669 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004670 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004671 }
4672
4673 public void noteVideoOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004674 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004675 final long elapsedRealtime = mClocks.elapsedRealtime();
4676 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004677 if (mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004678 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004679 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
4680 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004681 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004682 mVideoOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004683 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004684 mVideoOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004685 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004686 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004687
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004688 public void noteVideoOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004689 if (mVideoOnNesting == 0) {
4690 return;
4691 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08004692 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004693 final long elapsedRealtime = mClocks.elapsedRealtime();
4694 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004695 if (--mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004696 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004697 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
4698 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004699 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004700 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004701 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004702 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004703 }
4704
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004705 public void noteResetAudioLocked() {
4706 if (mAudioOnNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08004707 final long elapsedRealtime = mClocks.elapsedRealtime();
4708 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004709 mAudioOnNesting = 0;
4710 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
4711 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
4712 + Integer.toHexString(mHistoryCur.states));
4713 addHistoryRecordLocked(elapsedRealtime, uptime);
4714 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime);
4715 for (int i=0; i<mUidStats.size(); i++) {
4716 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
4717 uid.noteResetAudioLocked(elapsedRealtime);
4718 }
4719 }
4720 }
4721
4722 public void noteResetVideoLocked() {
4723 if (mVideoOnNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08004724 final long elapsedRealtime = mClocks.elapsedRealtime();
4725 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004726 mAudioOnNesting = 0;
4727 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
4728 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
4729 + Integer.toHexString(mHistoryCur.states));
4730 addHistoryRecordLocked(elapsedRealtime, uptime);
4731 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime);
4732 for (int i=0; i<mUidStats.size(); i++) {
4733 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
4734 uid.noteResetVideoLocked(elapsedRealtime);
4735 }
4736 }
4737 }
4738
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004739 public void noteActivityResumedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004740 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004741 getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004742 }
4743
4744 public void noteActivityPausedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004745 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004746 getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004747 }
4748
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004749 public void noteVibratorOnLocked(int uid, long durationMillis) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004750 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004751 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
4752 }
4753
4754 public void noteVibratorOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004755 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004756 getUidStatsLocked(uid).noteVibratorOffLocked();
4757 }
4758
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004759 public void noteFlashlightOnLocked(int uid) {
4760 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004761 final long elapsedRealtime = mClocks.elapsedRealtime();
4762 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004763 if (mFlashlightOnNesting++ == 0) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004764 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
4765 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004766 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004767 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004768 mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
4769 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004770 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime);
4771 }
4772
4773 public void noteFlashlightOffLocked(int uid) {
4774 if (mFlashlightOnNesting == 0) {
4775 return;
4776 }
4777 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004778 final long elapsedRealtime = mClocks.elapsedRealtime();
4779 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004780 if (--mFlashlightOnNesting == 0) {
4781 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
4782 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
4783 + Integer.toHexString(mHistoryCur.states2));
4784 addHistoryRecordLocked(elapsedRealtime, uptime);
4785 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
4786 }
4787 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime);
4788 }
4789
4790 public void noteCameraOnLocked(int uid) {
4791 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004792 final long elapsedRealtime = mClocks.elapsedRealtime();
4793 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004794 if (mCameraOnNesting++ == 0) {
4795 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG;
4796 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: "
4797 + Integer.toHexString(mHistoryCur.states2));
4798 addHistoryRecordLocked(elapsedRealtime, uptime);
4799 mCameraOnTimer.startRunningLocked(elapsedRealtime);
4800 }
4801 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime);
4802 }
4803
4804 public void noteCameraOffLocked(int uid) {
4805 if (mCameraOnNesting == 0) {
4806 return;
4807 }
4808 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004809 final long elapsedRealtime = mClocks.elapsedRealtime();
4810 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004811 if (--mCameraOnNesting == 0) {
4812 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
4813 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
4814 + Integer.toHexString(mHistoryCur.states2));
4815 addHistoryRecordLocked(elapsedRealtime, uptime);
4816 mCameraOnTimer.stopRunningLocked(elapsedRealtime);
4817 }
4818 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime);
4819 }
4820
4821 public void noteResetCameraLocked() {
4822 if (mCameraOnNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08004823 final long elapsedRealtime = mClocks.elapsedRealtime();
4824 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004825 mCameraOnNesting = 0;
4826 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
4827 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
4828 + Integer.toHexString(mHistoryCur.states2));
4829 addHistoryRecordLocked(elapsedRealtime, uptime);
4830 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime);
4831 for (int i=0; i<mUidStats.size(); i++) {
4832 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
4833 uid.noteResetCameraLocked(elapsedRealtime);
4834 }
4835 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004836 }
4837
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004838 public void noteResetFlashlightLocked() {
4839 if (mFlashlightOnNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08004840 final long elapsedRealtime = mClocks.elapsedRealtime();
4841 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004842 mFlashlightOnNesting = 0;
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004843 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
4844 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004845 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004846 addHistoryRecordLocked(elapsedRealtime, uptime);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004847 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime);
4848 for (int i=0; i<mUidStats.size(); i++) {
4849 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
4850 uid.noteResetFlashlightLocked(elapsedRealtime);
4851 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004852 }
4853 }
4854
Bookatzb1f04f32017-05-19 13:57:32 -07004855 private void noteBluetoothScanStartedLocked(int uid, boolean isUnoptimized) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004856 uid = mapUid(uid);
Bookatz867c0d72017-03-07 18:23:42 -08004857 final long elapsedRealtime = mClocks.elapsedRealtime();
4858 final long uptime = mClocks.uptimeMillis();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004859 if (mBluetoothScanNesting == 0) {
4860 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
4861 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: "
4862 + Integer.toHexString(mHistoryCur.states2));
4863 addHistoryRecordLocked(elapsedRealtime, uptime);
Adam Lesinskid9b99be2016-03-30 16:58:51 -07004864 mBluetoothScanTimer.startRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004865 }
4866 mBluetoothScanNesting++;
Bookatzb1f04f32017-05-19 13:57:32 -07004867 getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004868 }
4869
Bookatzb1f04f32017-05-19 13:57:32 -07004870 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004871 final int N = ws.size();
4872 for (int i = 0; i < N; i++) {
Bookatzb1f04f32017-05-19 13:57:32 -07004873 noteBluetoothScanStartedLocked(ws.get(i), isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004874 }
4875 }
4876
4877 private void noteBluetoothScanStoppedLocked(int uid) {
4878 uid = mapUid(uid);
Bookatz867c0d72017-03-07 18:23:42 -08004879 final long elapsedRealtime = mClocks.elapsedRealtime();
4880 final long uptime = mClocks.uptimeMillis();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004881 mBluetoothScanNesting--;
4882 if (mBluetoothScanNesting == 0) {
4883 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
4884 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: "
4885 + Integer.toHexString(mHistoryCur.states2));
4886 addHistoryRecordLocked(elapsedRealtime, uptime);
Adam Lesinskid9b99be2016-03-30 16:58:51 -07004887 mBluetoothScanTimer.stopRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004888 }
4889 getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime);
4890 }
4891
4892 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws) {
4893 final int N = ws.size();
4894 for (int i = 0; i < N; i++) {
4895 noteBluetoothScanStoppedLocked(ws.get(i));
4896 }
4897 }
4898
4899 public void noteResetBluetoothScanLocked() {
4900 if (mBluetoothScanNesting > 0) {
Bookatz867c0d72017-03-07 18:23:42 -08004901 final long elapsedRealtime = mClocks.elapsedRealtime();
4902 final long uptime = mClocks.uptimeMillis();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004903 mBluetoothScanNesting = 0;
4904 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
4905 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: "
4906 + Integer.toHexString(mHistoryCur.states2));
4907 addHistoryRecordLocked(elapsedRealtime, uptime);
4908 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime);
4909 for (int i=0; i<mUidStats.size(); i++) {
4910 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
4911 uid.noteResetBluetoothScanLocked(elapsedRealtime);
4912 }
4913 }
4914 }
4915
Bookatz4ebc0642017-05-11 12:21:19 -07004916 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) {
Bookatz956f36bf2017-04-28 09:48:17 -07004917 final int N = ws.size();
4918 for (int i = 0; i < N; i++) {
4919 int uid = mapUid(ws.get(i));
Bookatz4ebc0642017-05-11 12:21:19 -07004920 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults);
Bookatz956f36bf2017-04-28 09:48:17 -07004921 }
4922 }
4923
Adam Lesinski5f056f62016-07-14 16:56:08 -07004924 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis,
4925 final long uptimeMillis, int uid) {
4926 uid = mapUid(uid);
4927 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
4928 uid);
4929 getUidStatsLocked(uid).noteWifiRadioApWakeupLocked();
4930 }
4931
4932 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) {
Joe Onoratoabded112016-02-08 16:49:39 -08004933 final long elapsedRealtime = mClocks.elapsedRealtime();
4934 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07004935 if (mWifiRadioPowerState != powerState) {
4936 final boolean active =
4937 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
4938 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
4939 if (active) {
Adam Lesinski5f056f62016-07-14 16:56:08 -07004940 if (uid > 0) {
4941 noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid);
4942 }
Dianne Hackborn0c820db2015-04-14 17:47:34 -07004943 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
4944 } else {
4945 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
4946 }
4947 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: "
4948 + Integer.toHexString(mHistoryCur.states));
4949 addHistoryRecordLocked(elapsedRealtime, uptime);
4950 mWifiRadioPowerState = powerState;
4951 }
4952 }
4953
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004954 public void noteWifiRunningLocked(WorkSource ws) {
4955 if (!mGlobalWifiRunning) {
Joe Onoratoabded112016-02-08 16:49:39 -08004956 final long elapsedRealtime = mClocks.elapsedRealtime();
4957 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07004958 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004959 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
4960 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004961 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004962 mGlobalWifiRunning = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004963 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004964 int N = ws.size();
4965 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004966 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004967 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004968 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004969 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004970 } else {
4971 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07004972 }
4973 }
4974
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004975 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
4976 if (mGlobalWifiRunning) {
Joe Onoratoabded112016-02-08 16:49:39 -08004977 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004978 int N = oldWs.size();
4979 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004980 int uid = mapUid(oldWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004981 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004982 }
4983 N = newWs.size();
4984 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004985 int uid = mapUid(newWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004986 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004987 }
4988 } else {
4989 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
4990 }
4991 }
4992
4993 public void noteWifiStoppedLocked(WorkSource ws) {
4994 if (mGlobalWifiRunning) {
Joe Onoratoabded112016-02-08 16:49:39 -08004995 final long elapsedRealtime = mClocks.elapsedRealtime();
4996 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07004997 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004998 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
4999 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005000 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005001 mGlobalWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005002 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005003 int N = ws.size();
5004 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005005 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005006 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005007 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005008 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005009 } else {
5010 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07005011 }
5012 }
5013
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005014 public void noteWifiStateLocked(int wifiState, String accessPoint) {
5015 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
5016 if (mWifiState != wifiState) {
Joe Onoratoabded112016-02-08 16:49:39 -08005017 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005018 if (mWifiState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005019 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005020 }
5021 mWifiState = wifiState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005022 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005023 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005024 }
5025 }
5026
Dianne Hackborn3251b902014-06-20 14:40:53 -07005027 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
5028 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
5029 if (mWifiSupplState != supplState) {
Joe Onoratoabded112016-02-08 16:49:39 -08005030 final long elapsedRealtime = mClocks.elapsedRealtime();
5031 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07005032 if (mWifiSupplState >= 0) {
5033 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime);
5034 }
5035 mWifiSupplState = supplState;
5036 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime);
5037 mHistoryCur.states2 =
5038 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
5039 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
5040 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
5041 + Integer.toHexString(mHistoryCur.states2));
5042 addHistoryRecordLocked(elapsedRealtime, uptime);
5043 }
5044 }
5045
5046 void stopAllWifiSignalStrengthTimersLocked(int except) {
Joe Onoratoabded112016-02-08 16:49:39 -08005047 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackborn3251b902014-06-20 14:40:53 -07005048 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
5049 if (i == except) {
5050 continue;
5051 }
5052 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) {
5053 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
5054 }
5055 }
5056 }
5057
5058 public void noteWifiRssiChangedLocked(int newRssi) {
5059 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
5060 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
5061 if (mWifiSignalStrengthBin != strengthBin) {
Joe Onoratoabded112016-02-08 16:49:39 -08005062 final long elapsedRealtime = mClocks.elapsedRealtime();
5063 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07005064 if (mWifiSignalStrengthBin >= 0) {
5065 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked(
5066 elapsedRealtime);
5067 }
5068 if (strengthBin >= 0) {
5069 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
5070 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
5071 }
5072 mHistoryCur.states2 =
5073 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
5074 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
5075 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
5076 + Integer.toHexString(mHistoryCur.states2));
5077 addHistoryRecordLocked(elapsedRealtime, uptime);
5078 } else {
5079 stopAllWifiSignalStrengthTimersLocked(-1);
5080 }
5081 mWifiSignalStrengthBin = strengthBin;
5082 }
5083 }
5084
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005085 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005086
The Android Open Source Project10592532009-03-18 17:39:46 -07005087 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005088 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005089 final long elapsedRealtime = mClocks.elapsedRealtime();
5090 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005091 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005092 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005093 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
5094 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005095 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005096 }
5097 mWifiFullLockNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005098 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005099 }
5100
5101 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005102 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005103 final long elapsedRealtime = mClocks.elapsedRealtime();
5104 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005105 mWifiFullLockNesting--;
5106 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005107 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005108 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
5109 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005110 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005111 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005112 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005113 }
5114
Nick Pelly6ccaa542012-06-15 15:22:47 -07005115 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005116
Nick Pelly6ccaa542012-06-15 15:22:47 -07005117 public void noteWifiScanStartedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005118 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005119 final long elapsedRealtime = mClocks.elapsedRealtime();
5120 final long uptime = mClocks.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07005121 if (mWifiScanNesting == 0) {
5122 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
5123 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005124 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005125 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005126 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005127 mWifiScanNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005128 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005129 }
5130
Nick Pelly6ccaa542012-06-15 15:22:47 -07005131 public void noteWifiScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005132 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005133 final long elapsedRealtime = mClocks.elapsedRealtime();
5134 final long uptime = mClocks.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07005135 mWifiScanNesting--;
5136 if (mWifiScanNesting == 0) {
5137 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
5138 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005139 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005140 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005141 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005142 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005143 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005144
Robert Greenwalta029ea12013-09-25 16:38:12 -07005145 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005146 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005147 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005148 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005149 }
5150
5151 public void noteWifiBatchedScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005152 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005153 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005154 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005155 }
5156
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005157 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005158
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005159 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005160 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005161 final long elapsedRealtime = mClocks.elapsedRealtime();
5162 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005163 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005164 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005165 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
5166 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005167 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005168 }
5169 mWifiMulticastNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005170 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005171 }
5172
5173 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005174 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005175 final long elapsedRealtime = mClocks.elapsedRealtime();
5176 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005177 mWifiMulticastNesting--;
5178 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005179 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005180 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
5181 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005182 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005183 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005184 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005185 }
5186
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005187 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
5188 int N = ws.size();
5189 for (int i=0; i<N; i++) {
5190 noteFullWifiLockAcquiredLocked(ws.get(i));
5191 }
5192 }
5193
5194 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
5195 int N = ws.size();
5196 for (int i=0; i<N; i++) {
5197 noteFullWifiLockReleasedLocked(ws.get(i));
5198 }
5199 }
5200
Nick Pelly6ccaa542012-06-15 15:22:47 -07005201 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005202 int N = ws.size();
5203 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005204 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005205 }
5206 }
5207
Nick Pelly6ccaa542012-06-15 15:22:47 -07005208 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005209 int N = ws.size();
5210 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005211 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005212 }
5213 }
5214
Robert Greenwalta029ea12013-09-25 16:38:12 -07005215 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
5216 int N = ws.size();
5217 for (int i=0; i<N; i++) {
5218 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
5219 }
5220 }
5221
5222 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
5223 int N = ws.size();
5224 for (int i=0; i<N; i++) {
5225 noteWifiBatchedScanStoppedLocked(ws.get(i));
5226 }
5227 }
5228
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005229 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
5230 int N = ws.size();
5231 for (int i=0; i<N; i++) {
5232 noteWifiMulticastEnabledLocked(ws.get(i));
5233 }
5234 }
5235
5236 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
5237 int N = ws.size();
5238 for (int i=0; i<N; i++) {
5239 noteWifiMulticastDisabledLocked(ws.get(i));
5240 }
5241 }
5242
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08005243 private static String[] includeInStringArray(String[] array, String str) {
5244 if (ArrayUtils.indexOf(array, str) >= 0) {
5245 return array;
5246 }
5247 String[] newArray = new String[array.length+1];
5248 System.arraycopy(array, 0, newArray, 0, array.length);
5249 newArray[array.length] = str;
5250 return newArray;
5251 }
5252
5253 private static String[] excludeFromStringArray(String[] array, String str) {
5254 int index = ArrayUtils.indexOf(array, str);
5255 if (index >= 0) {
5256 String[] newArray = new String[array.length-1];
5257 if (index > 0) {
5258 System.arraycopy(array, 0, newArray, 0, index);
5259 }
5260 if (index < array.length-1) {
5261 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
5262 }
5263 return newArray;
5264 }
5265 return array;
5266 }
5267
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005268 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07005269 if (TextUtils.isEmpty(iface)) return;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005270
Adam Lesinski14ae39a2017-05-26 11:50:40 -07005271 synchronized (mModemNetworkLock) {
5272 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
5273 mModemIfaces = includeInStringArray(mModemIfaces, iface);
5274 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces);
5275 } else {
5276 mModemIfaces = excludeFromStringArray(mModemIfaces, iface);
5277 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces);
5278 }
5279 }
5280
5281 synchronized (mWifiNetworkLock) {
5282 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
5283 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
5284 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
5285 } else {
5286 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
5287 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
5288 }
5289 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005290 }
5291
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005292 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
5293 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005294 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005295
Dianne Hackborn77b987f2014-02-26 16:20:52 -08005296 @Override public int getScreenOnCount(int which) {
5297 return mScreenOnTimer.getCountLocked(which);
5298 }
5299
Dianne Hackborn617f8772009-03-31 15:04:46 -07005300 @Override public long getScreenBrightnessTime(int brightnessBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005301 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07005302 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005303 elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005304 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005305
Jeff Browne95c3cd2014-05-02 16:59:26 -07005306 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
5307 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005308 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005309
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07005310 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) {
5311 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005312 }
5313
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07005314 @Override public int getPowerSaveModeEnabledCount(int which) {
5315 return mPowerSaveModeEnabledTimer.getCountLocked(which);
5316 }
5317
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005318 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs,
5319 int which) {
5320 switch (mode) {
5321 case DEVICE_IDLE_MODE_LIGHT:
5322 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005323 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005324 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5325 }
5326 return 0;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07005327 }
5328
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005329 @Override public int getDeviceIdleModeCount(int mode, int which) {
5330 switch (mode) {
5331 case DEVICE_IDLE_MODE_LIGHT:
5332 return mDeviceIdleModeLightTimer.getCountLocked(which);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005333 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005334 return mDeviceIdleModeFullTimer.getCountLocked(which);
5335 }
5336 return 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005337 }
5338
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005339 @Override public long getLongestDeviceIdleModeTime(int mode) {
5340 switch (mode) {
5341 case DEVICE_IDLE_MODE_LIGHT:
5342 return mLongestLightIdleTime;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005343 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005344 return mLongestFullIdleTime;
5345 }
5346 return 0;
Dianne Hackborn88e98df2015-03-23 13:29:14 -07005347 }
5348
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005349 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) {
5350 switch (mode) {
5351 case DEVICE_IDLE_MODE_LIGHT:
5352 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005353 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005354 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5355 }
5356 return 0;
5357 }
5358
5359 @Override public int getDeviceIdlingCount(int mode, int which) {
5360 switch (mode) {
5361 case DEVICE_IDLE_MODE_LIGHT:
5362 return mDeviceLightIdlingTimer.getCountLocked(which);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005363 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005364 return mDeviceIdlingTimer.getCountLocked(which);
5365 }
5366 return 0;
Dianne Hackborn88e98df2015-03-23 13:29:14 -07005367 }
5368
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005369 @Override public int getNumConnectivityChange(int which) {
5370 int val = mNumConnectivityChange;
5371 if (which == STATS_CURRENT) {
5372 val -= mLoadedNumConnectivityChange;
5373 } else if (which == STATS_SINCE_UNPLUGGED) {
5374 val -= mUnpluggedNumConnectivityChange;
5375 }
5376 return val;
5377 }
5378
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005379 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
5380 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005381 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005382
Dianne Hackborn77b987f2014-02-26 16:20:52 -08005383 @Override public int getPhoneOnCount(int which) {
5384 return mPhoneOnTimer.getCountLocked(which);
5385 }
5386
Dianne Hackborn627bba72009-03-24 22:32:56 -07005387 @Override public long getPhoneSignalStrengthTime(int strengthBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005388 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07005389 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005390 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005391 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005392
5393 @Override public long getPhoneSignalScanningTime(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005394 long elapsedRealtimeUs, int which) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07005395 return mPhoneSignalScanningTimer.getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005396 elapsedRealtimeUs, which);
Amith Yamasanif37447b2009-10-08 18:28:01 -07005397 }
5398
Catherine Liufb900812012-07-17 14:12:56 -05005399 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
5400 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005401 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005402
Dianne Hackborn627bba72009-03-24 22:32:56 -07005403 @Override public long getPhoneDataConnectionTime(int dataType,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005404 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07005405 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005406 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005407 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005408
Dianne Hackborn617f8772009-03-31 15:04:46 -07005409 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07005410 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005411 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005412
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005413 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
5414 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08005415 }
5416
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005417 @Override public int getMobileRadioActiveCount(int which) {
5418 return mMobileRadioActiveTimer.getCountLocked(which);
5419 }
5420
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005421 @Override public long getMobileRadioActiveAdjustedTime(int which) {
5422 return mMobileRadioActiveAdjustedTime.getCountLocked(which);
5423 }
5424
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005425 @Override public long getMobileRadioActiveUnknownTime(int which) {
5426 return mMobileRadioActiveUnknownTime.getCountLocked(which);
5427 }
5428
5429 @Override public int getMobileRadioActiveUnknownCount(int which) {
5430 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
5431 }
5432
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005433 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
5434 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07005435 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005436
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005437 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
5438 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07005439 }
5440
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005441 @Override public long getWifiStateTime(int wifiState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005442 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005443 return mWifiStateTimer[wifiState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005444 elapsedRealtimeUs, which);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005445 }
5446
5447 @Override public int getWifiStateCount(int wifiState, int which) {
5448 return mWifiStateTimer[wifiState].getCountLocked(which);
5449 }
5450
Dianne Hackborn3251b902014-06-20 14:40:53 -07005451 @Override public long getWifiSupplStateTime(int state,
5452 long elapsedRealtimeUs, int which) {
5453 return mWifiSupplStateTimer[state].getTotalTimeLocked(
5454 elapsedRealtimeUs, which);
5455 }
5456
5457 @Override public int getWifiSupplStateCount(int state, int which) {
5458 return mWifiSupplStateTimer[state].getCountLocked(which);
5459 }
5460
5461 @Override public long getWifiSignalStrengthTime(int strengthBin,
5462 long elapsedRealtimeUs, int which) {
5463 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
5464 elapsedRealtimeUs, which);
5465 }
5466
5467 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) {
5468 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which);
5469 }
5470
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005471 @Override
5472 public ControllerActivityCounter getBluetoothControllerActivity() {
5473 return mBluetoothActivity;
Adam Lesinski17390762015-04-10 13:17:47 -07005474 }
5475
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005476 @Override
5477 public ControllerActivityCounter getWifiControllerActivity() {
5478 return mWifiActivity;
Adam Lesinski33dac552015-03-09 15:24:48 -07005479 }
5480
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005481 @Override
5482 public ControllerActivityCounter getModemControllerActivity() {
5483 return mModemActivity;
Adam Lesinski17390762015-04-10 13:17:47 -07005484 }
5485
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005486 @Override
5487 public boolean hasBluetoothActivityReporting() {
5488 return mHasBluetoothReporting;
5489 }
5490
5491 @Override
5492 public boolean hasWifiActivityReporting() {
5493 return mHasWifiReporting;
5494 }
5495
5496 @Override
5497 public boolean hasModemActivityReporting() {
5498 return mHasModemReporting;
Adam Lesinski33dac552015-03-09 15:24:48 -07005499 }
5500
Ruben Brunk5b1308f2015-06-03 18:49:27 -07005501 @Override
5502 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -07005503 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5504 }
5505
Ruben Brunk5b1308f2015-06-03 18:49:27 -07005506 @Override
5507 public long getFlashlightOnCount(int which) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -07005508 return mFlashlightOnTimer.getCountLocked(which);
5509 }
5510
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005511 @Override
Ruben Brunk5b1308f2015-06-03 18:49:27 -07005512 public long getCameraOnTime(long elapsedRealtimeUs, int which) {
5513 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5514 }
5515
5516 @Override
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005517 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) {
5518 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5519 }
5520
5521 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005522 public long getNetworkActivityBytes(int type, int which) {
5523 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
5524 return mNetworkByteActivityCounters[type].getCountLocked(which);
5525 } else {
5526 return 0;
5527 }
5528 }
5529
5530 @Override
5531 public long getNetworkActivityPackets(int type, int which) {
5532 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
5533 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005534 } else {
5535 return 0;
5536 }
5537 }
5538
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08005539 @Override public long getStartClockTime() {
Dianne Hackbornd48954f2015-07-22 17:20:33 -07005540 final long currentTime = System.currentTimeMillis();
5541 if (ensureStartClockTime(currentTime)) {
Joe Onoratoabded112016-02-08 16:49:39 -08005542 recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(),
5543 mClocks.uptimeMillis());
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07005544 }
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08005545 return mStartClockTime;
5546 }
5547
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005548 @Override public String getStartPlatformVersion() {
5549 return mStartPlatformVersion;
5550 }
5551
5552 @Override public String getEndPlatformVersion() {
5553 return mEndPlatformVersion;
5554 }
5555
5556 @Override public int getParcelVersion() {
5557 return VERSION;
5558 }
5559
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005560 @Override public boolean getIsOnBattery() {
5561 return mOnBattery;
5562 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005564 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
5565 return mUidStats;
5566 }
5567
Adam Lesinski5f056f62016-07-14 16:56:08 -07005568 private static void detachTimerIfNotNull(BatteryStatsImpl.Timer timer) {
5569 if (timer != null) {
5570 timer.detach();
5571 }
5572 }
5573
5574 private static boolean resetTimerIfNotNull(BatteryStatsImpl.Timer timer,
5575 boolean detachIfReset) {
5576 if (timer != null) {
5577 return timer.reset(detachIfReset);
5578 }
5579 return true;
5580 }
5581
Bookatz867c0d72017-03-07 18:23:42 -08005582 private static boolean resetTimerIfNotNull(DualTimer timer, boolean detachIfReset) {
5583 if (timer != null) {
5584 return timer.reset(detachIfReset);
5585 }
5586 return true;
5587 }
5588
Adam Lesinski5f056f62016-07-14 16:56:08 -07005589 private static void detachLongCounterIfNotNull(LongSamplingCounter counter) {
5590 if (counter != null) {
5591 counter.detach();
5592 }
5593 }
5594
5595 private static void resetLongCounterIfNotNull(LongSamplingCounter counter,
5596 boolean detachIfReset) {
5597 if (counter != null) {
5598 counter.reset(detachIfReset);
5599 }
5600 }
5601
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005602 /**
5603 * The statistics associated with a particular uid.
5604 */
Joe Onoratoabded112016-02-08 16:49:39 -08005605 public static class Uid extends BatteryStats.Uid {
5606 /**
5607 * BatteryStatsImpl that we are associated with.
5608 */
5609 protected BatteryStatsImpl mBsi;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005610
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005611 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005612
Bookatz867c0d72017-03-07 18:23:42 -08005613 /** TimeBase for when uid is in background and device is on battery. */
5614 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
5615 public final TimeBase mOnBatteryBackgroundTimeBase;
Bookatzc8c44962017-05-11 12:12:54 -07005616 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
5617 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase;
Bookatz867c0d72017-03-07 18:23:42 -08005618
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005619 boolean mWifiRunning;
5620 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005621
The Android Open Source Project10592532009-03-18 17:39:46 -07005622 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07005623 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005624
Nick Pelly6ccaa542012-06-15 15:22:47 -07005625 boolean mWifiScanStarted;
Bookatz867c0d72017-03-07 18:23:42 -08005626 DualTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005627
Dianne Hackborn61659e52014-07-09 16:13:01 -07005628 static final int NO_BATCHED_SCAN_STARTED = -1;
Robert Greenwalta029ea12013-09-25 16:38:12 -07005629 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
5630 StopwatchTimer[] mWifiBatchedScanTimer;
5631
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005632 boolean mWifiMulticastEnabled;
5633 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005634
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005635 StopwatchTimer mAudioTurnedOnTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005636 StopwatchTimer mVideoTurnedOnTimer;
Ruben Brunk6d2c3632015-05-26 17:32:16 -07005637 StopwatchTimer mFlashlightTurnedOnTimer;
5638 StopwatchTimer mCameraTurnedOnTimer;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005639 StopwatchTimer mForegroundActivityTimer;
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07005640 StopwatchTimer mForegroundServiceTimer;
Bookatzc8c44962017-05-11 12:12:54 -07005641 /** Total time spent by the uid holding any partial wakelocks. */
5642 DualTimer mAggregatedPartialWakelockTimer;
Bookatz867c0d72017-03-07 18:23:42 -08005643 DualTimer mBluetoothScanTimer;
Bookatzb1f04f32017-05-19 13:57:32 -07005644 DualTimer mBluetoothUnoptimizedScanTimer;
Bookatz956f36bf2017-04-28 09:48:17 -07005645 Counter mBluetoothScanResultCounter;
Bookatzb1f04f32017-05-19 13:57:32 -07005646 Counter mBluetoothScanResultBgCounter;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005647
Dianne Hackborna8d10942015-11-19 17:55:19 -08005648 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
Dianne Hackborn61659e52014-07-09 16:13:01 -07005649 StopwatchTimer[] mProcessStateTimer;
5650
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07005651 boolean mInForegroundService = false;
5652
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005653 BatchTimer mVibratorOnTimer;
5654
Dianne Hackborn617f8772009-03-31 15:04:46 -07005655 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005656
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005657 LongSamplingCounter[] mNetworkByteActivityCounters;
5658 LongSamplingCounter[] mNetworkPacketActivityCounters;
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005659 LongSamplingCounter mMobileRadioActiveTime;
5660 LongSamplingCounter mMobileRadioActiveCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005661
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005662 /**
Adam Lesinski5f056f62016-07-14 16:56:08 -07005663 * How many times this UID woke up the Application Processor due to a Mobile radio packet.
5664 */
5665 private LongSamplingCounter mMobileRadioApWakeupCount;
5666
5667 /**
5668 * How many times this UID woke up the Application Processor due to a Wifi packet.
5669 */
5670 private LongSamplingCounter mWifiRadioApWakeupCount;
5671
5672 /**
Adam Lesinskie08af192015-03-25 16:42:59 -07005673 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode.
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005674 * Can be null if the UID has had no such activity.
Adam Lesinskie08af192015-03-25 16:42:59 -07005675 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005676 private ControllerActivityCounterImpl mWifiControllerActivity;
Adam Lesinskie08af192015-03-25 16:42:59 -07005677
5678 /**
5679 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode.
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005680 * Can be null if the UID has had no such activity.
Adam Lesinskie08af192015-03-25 16:42:59 -07005681 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005682 private ControllerActivityCounterImpl mBluetoothControllerActivity;
5683
5684 /**
5685 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode.
5686 * Can be null if the UID has had no such activity.
5687 */
5688 private ControllerActivityCounterImpl mModemControllerActivity;
Adam Lesinskie08af192015-03-25 16:42:59 -07005689
5690 /**
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005691 * The CPU times we had at the last history details update.
5692 */
5693 long mLastStepUserTime;
5694 long mLastStepSystemTime;
5695 long mCurStepUserTime;
5696 long mCurStepSystemTime;
5697
Joe Onoratoabded112016-02-08 16:49:39 -08005698 LongSamplingCounter mUserCpuTime;
5699 LongSamplingCounter mSystemCpuTime;
Adam Lesinski6832f392015-09-05 18:05:40 -07005700 LongSamplingCounter[][] mCpuClusterSpeed;
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005701
Sudheer Shanka9b735c52017-05-09 18:26:18 -07005702 LongSamplingCounterArray mCpuFreqTimeMs;
5703 LongSamplingCounterArray mScreenOffCpuFreqTimeMs;
5704
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005705 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005706 * The statistics we have collected for this uid's wake locks.
5707 */
Joe Onoratoabded112016-02-08 16:49:39 -08005708 final OverflowArrayMap<Wakelock> mWakelockStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005709
5710 /**
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005711 * The statistics we have collected for this uid's syncs.
5712 */
Bookatz2bffb5b2017-04-13 11:59:33 -07005713 final OverflowArrayMap<DualTimer> mSyncStats;
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005714
5715 /**
5716 * The statistics we have collected for this uid's jobs.
5717 */
Bookatzaa4594a2017-03-24 12:39:56 -07005718 final OverflowArrayMap<DualTimer> mJobStats;
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005719
5720 /**
Dianne Hackborn94326cb2017-06-28 16:17:20 -07005721 * Count of the jobs that have completed and the reasons why they completed.
5722 */
5723 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>();
5724
5725 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005726 * The statistics we have collected for this uid's sensor activations.
5727 */
Adam Lesinskie08af192015-03-25 16:42:59 -07005728 final SparseArray<Sensor> mSensorStats = new SparseArray<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005729
5730 /**
5731 * The statistics we have collected for this uid's processes.
5732 */
Adam Lesinskie08af192015-03-25 16:42:59 -07005733 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005734
5735 /**
5736 * The statistics we have collected for this uid's processes.
5737 */
Adam Lesinskie08af192015-03-25 16:42:59 -07005738 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005739
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005740 /**
5741 * The transient wake stats we have collected for this uid's pids.
5742 */
Adam Lesinskie08af192015-03-25 16:42:59 -07005743 final SparseArray<Pid> mPids = new SparseArray<>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005744
Joe Onoratoabded112016-02-08 16:49:39 -08005745 public Uid(BatteryStatsImpl bsi, int uid) {
5746 mBsi = bsi;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005747 mUid = uid;
Joe Onoratoabded112016-02-08 16:49:39 -08005748
Bookatz867c0d72017-03-07 18:23:42 -08005749 mOnBatteryBackgroundTimeBase = new TimeBase();
5750 mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
5751 mBsi.mClocks.elapsedRealtime() * 1000);
5752
Bookatzc8c44962017-05-11 12:12:54 -07005753 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase();
5754 mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
5755 mBsi.mClocks.elapsedRealtime() * 1000);
5756
Joe Onoratoabded112016-02-08 16:49:39 -08005757 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
5758 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
Joe Onoratoabded112016-02-08 16:49:39 -08005759
Dianne Hackborn657153b2016-07-29 14:54:14 -07005760 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) {
Joe Onoratoabded112016-02-08 16:49:39 -08005761 @Override public Wakelock instantiateObject() {
5762 return new Wakelock(mBsi, Uid.this);
5763 }
5764 };
Bookatz2bffb5b2017-04-13 11:59:33 -07005765 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) {
5766 @Override public DualTimer instantiateObject() {
5767 return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null,
5768 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
Joe Onoratoabded112016-02-08 16:49:39 -08005769 }
5770 };
Bookatzaa4594a2017-03-24 12:39:56 -07005771 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) {
5772 @Override public DualTimer instantiateObject() {
5773 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null,
5774 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
Joe Onoratoabded112016-02-08 16:49:39 -08005775 }
5776 };
5777
5778 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING,
5779 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase);
5780 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK,
5781 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase);
Bookatz867c0d72017-03-07 18:23:42 -08005782 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN,
5783 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005784 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Joe Onoratoabded112016-02-08 16:49:39 -08005785 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED,
5786 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005787 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005788 }
5789
5790 @Override
Sudheer Shanka9b735c52017-05-09 18:26:18 -07005791 public long[] getCpuFreqTimes(int which) {
5792 if (mCpuFreqTimeMs == null) {
5793 return null;
5794 }
5795 final long[] cpuFreqTimes = mCpuFreqTimeMs.getCountsLocked(which);
5796 if (cpuFreqTimes == null) {
5797 return null;
5798 }
5799 // Return cpuFreqTimes only if atleast one of the elements in non-zero.
5800 for (int i = 0; i < cpuFreqTimes.length; ++i) {
5801 if (cpuFreqTimes[i] != 0) {
5802 return cpuFreqTimes;
5803 }
5804 }
5805 return null;
5806 }
5807
5808 @Override
5809 public long[] getScreenOffCpuFreqTimes(int which) {
5810 if (mScreenOffCpuFreqTimeMs == null) {
5811 return null;
5812 }
5813 final long[] cpuFreqTimes = mScreenOffCpuFreqTimeMs.getCountsLocked(which);
5814 if (cpuFreqTimes == null) {
5815 return null;
5816 }
5817 // Return cpuFreqTimes only if atleast one of the elements in non-zero.
5818 for (int i = 0; i < cpuFreqTimes.length; ++i) {
5819 if (cpuFreqTimes[i] != 0) {
5820 return cpuFreqTimes;
5821 }
5822 }
5823 return null;
5824 }
5825
5826 @Override
Bookatzc8c44962017-05-11 12:12:54 -07005827 public Timer getAggregatedPartialWakelockTimer() {
5828 return mAggregatedPartialWakelockTimer;
5829 }
5830
5831 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07005832 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005833 return mWakelockStats.getMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005834 }
5835
5836 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07005837 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005838 return mSyncStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005839 }
5840
5841 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07005842 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005843 return mJobStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005844 }
5845
5846 @Override
Dianne Hackborn94326cb2017-06-28 16:17:20 -07005847 public ArrayMap<String, SparseIntArray> getJobCompletionStats() {
5848 return mJobCompletions;
5849 }
5850
5851 @Override
Dianne Hackborn61659e52014-07-09 16:13:01 -07005852 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005853 return mSensorStats;
5854 }
5855
5856 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07005857 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005858 return mProcessStats;
5859 }
5860
5861 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07005862 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005863 return mPackageStats;
5864 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005865
5866 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005867 public int getUid() {
5868 return mUid;
5869 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07005870
5871 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005872 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005873 if (!mWifiRunning) {
5874 mWifiRunning = true;
5875 if (mWifiRunningTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08005876 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING,
5877 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005878 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005879 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005880 }
5881 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005882
Dianne Hackborn617f8772009-03-31 15:04:46 -07005883 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005884 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005885 if (mWifiRunning) {
5886 mWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005887 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005888 }
5889 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005890
Dianne Hackborn617f8772009-03-31 15:04:46 -07005891 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005892 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07005893 if (!mFullWifiLockOut) {
5894 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005895 if (mFullWifiLockTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08005896 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK,
5897 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005898 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005899 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07005900 }
5901 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005902
The Android Open Source Project10592532009-03-18 17:39:46 -07005903 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005904 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07005905 if (mFullWifiLockOut) {
5906 mFullWifiLockOut = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005907 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07005908 }
5909 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005910
The Android Open Source Project10592532009-03-18 17:39:46 -07005911 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005912 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005913 if (!mWifiScanStarted) {
5914 mWifiScanStarted = true;
5915 if (mWifiScanTimer == null) {
Bookatz867c0d72017-03-07 18:23:42 -08005916 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN,
5917 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase,
5918 mOnBatteryBackgroundTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005919 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005920 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07005921 }
5922 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005923
The Android Open Source Project10592532009-03-18 17:39:46 -07005924 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005925 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005926 if (mWifiScanStarted) {
5927 mWifiScanStarted = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005928 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project10592532009-03-18 17:39:46 -07005929 }
5930 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005931
5932 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005933 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07005934 int bin = 0;
Navtej Singh Mann3c0ce5c2015-06-11 16:53:11 -07005935 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07005936 csph = csph >> 3;
5937 bin++;
5938 }
5939
5940 if (mWifiBatchedScanBinStarted == bin) return;
5941
5942 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
5943 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005944 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005945 }
5946 mWifiBatchedScanBinStarted = bin;
5947 if (mWifiBatchedScanTimer[bin] == null) {
5948 makeWifiBatchedScanBin(bin, null);
5949 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005950 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005951 }
5952
5953 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005954 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07005955 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
5956 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005957 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005958 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
5959 }
5960 }
5961
5962 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005963 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005964 if (!mWifiMulticastEnabled) {
5965 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005966 if (mWifiMulticastTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08005967 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
5968 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005969 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005970 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005971 }
5972 }
5973
5974 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005975 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005976 if (mWifiMulticastEnabled) {
5977 mWifiMulticastEnabled = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005978 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005979 }
5980 }
5981
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005982 @Override
5983 public ControllerActivityCounter getWifiControllerActivity() {
5984 return mWifiControllerActivity;
Adam Lesinskie08af192015-03-25 16:42:59 -07005985 }
5986
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005987 @Override
5988 public ControllerActivityCounter getBluetoothControllerActivity() {
5989 return mBluetoothControllerActivity;
5990 }
5991
5992 @Override
5993 public ControllerActivityCounter getModemControllerActivity() {
5994 return mModemControllerActivity;
5995 }
5996
5997 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() {
5998 if (mWifiControllerActivity == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08005999 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006000 NUM_BT_TX_LEVELS);
Adam Lesinski50e47602015-12-04 17:04:54 -08006001 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006002 return mWifiControllerActivity;
6003 }
6004
6005 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() {
6006 if (mBluetoothControllerActivity == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006007 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006008 NUM_BT_TX_LEVELS);
6009 }
6010 return mBluetoothControllerActivity;
6011 }
6012
6013 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() {
6014 if (mModemControllerActivity == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006015 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006016 ModemActivityInfo.TX_POWER_LEVELS);
6017 }
6018 return mModemControllerActivity;
Adam Lesinski50e47602015-12-04 17:04:54 -08006019 }
6020
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006021 public StopwatchTimer createAudioTurnedOnTimerLocked() {
6022 if (mAudioTurnedOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006023 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON,
6024 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006025 }
6026 return mAudioTurnedOnTimer;
6027 }
6028
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006029 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006030 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
6031 }
6032
6033 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
6034 if (mAudioTurnedOnTimer != null) {
6035 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006036 }
6037 }
6038
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006039 public void noteResetAudioLocked(long elapsedRealtimeMs) {
6040 if (mAudioTurnedOnTimer != null) {
6041 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006042 }
6043 }
6044
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006045 public StopwatchTimer createVideoTurnedOnTimerLocked() {
6046 if (mVideoTurnedOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006047 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON,
6048 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006049 }
6050 return mVideoTurnedOnTimer;
6051 }
6052
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006053 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006054 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
6055 }
6056
6057 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
6058 if (mVideoTurnedOnTimer != null) {
6059 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006060 }
6061 }
6062
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006063 public void noteResetVideoLocked(long elapsedRealtimeMs) {
6064 if (mVideoTurnedOnTimer != null) {
6065 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006066 }
6067 }
6068
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006069 public StopwatchTimer createFlashlightTurnedOnTimerLocked() {
6070 if (mFlashlightTurnedOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006071 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
6072 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006073 }
6074 return mFlashlightTurnedOnTimer;
6075 }
6076
6077 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) {
6078 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
6079 }
6080
6081 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) {
6082 if (mFlashlightTurnedOnTimer != null) {
6083 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
6084 }
6085 }
6086
6087 public void noteResetFlashlightLocked(long elapsedRealtimeMs) {
6088 if (mFlashlightTurnedOnTimer != null) {
6089 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
6090 }
6091 }
6092
6093 public StopwatchTimer createCameraTurnedOnTimerLocked() {
6094 if (mCameraTurnedOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006095 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON,
6096 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006097 }
6098 return mCameraTurnedOnTimer;
6099 }
6100
6101 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) {
6102 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
6103 }
6104
6105 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) {
6106 if (mCameraTurnedOnTimer != null) {
6107 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
6108 }
6109 }
6110
6111 public void noteResetCameraLocked(long elapsedRealtimeMs) {
6112 if (mCameraTurnedOnTimer != null) {
6113 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
6114 }
6115 }
6116
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006117 public StopwatchTimer createForegroundActivityTimerLocked() {
6118 if (mForegroundActivityTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006119 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
6120 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006121 }
6122 return mForegroundActivityTimer;
6123 }
6124
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07006125 public StopwatchTimer createForegroundServiceTimerLocked() {
6126 if (mForegroundServiceTimer == null) {
6127 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
6128 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase);
6129 }
6130 return mForegroundServiceTimer;
6131 }
6132
Bookatzc8c44962017-05-11 12:12:54 -07006133 public DualTimer createAggregatedPartialWakelockTimerLocked() {
6134 if (mAggregatedPartialWakelockTimer == null) {
6135 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
6136 AGGREGATED_WAKE_TYPE_PARTIAL, null,
6137 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase);
6138 }
6139 return mAggregatedPartialWakelockTimer;
6140 }
6141
Bookatz867c0d72017-03-07 18:23:42 -08006142 public DualTimer createBluetoothScanTimerLocked() {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006143 if (mBluetoothScanTimer == null) {
Bookatz867c0d72017-03-07 18:23:42 -08006144 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
6145 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
6146 mOnBatteryBackgroundTimeBase);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006147 }
6148 return mBluetoothScanTimer;
6149 }
6150
Bookatzb1f04f32017-05-19 13:57:32 -07006151 public DualTimer createBluetoothUnoptimizedScanTimerLocked() {
6152 if (mBluetoothUnoptimizedScanTimer == null) {
6153 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
6154 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
6155 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
6156 }
6157 return mBluetoothUnoptimizedScanTimer;
6158 }
6159
6160 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006161 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
Bookatzb1f04f32017-05-19 13:57:32 -07006162 if (isUnoptimized) {
6163 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
6164 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006165 }
6166
6167 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs) {
6168 if (mBluetoothScanTimer != null) {
6169 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
6170 }
Bookatzb1f04f32017-05-19 13:57:32 -07006171 // In the ble code, a scan cannot change types and nested starts are not possible.
6172 // So if an unoptimizedScan is running, it is now being stopped.
6173 if (mBluetoothUnoptimizedScanTimer != null
6174 && mBluetoothUnoptimizedScanTimer.isRunningLocked()) {
6175 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs);
6176 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006177 }
6178
6179 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) {
6180 if (mBluetoothScanTimer != null) {
6181 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
6182 }
Bookatzb1f04f32017-05-19 13:57:32 -07006183 if (mBluetoothUnoptimizedScanTimer != null) {
6184 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
6185 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006186 }
6187
Bookatz956f36bf2017-04-28 09:48:17 -07006188 public Counter createBluetoothScanResultCounterLocked() {
6189 if (mBluetoothScanResultCounter == null) {
6190 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase);
6191 }
6192 return mBluetoothScanResultCounter;
6193 }
6194
Bookatzb1f04f32017-05-19 13:57:32 -07006195 public Counter createBluetoothScanResultBgCounterLocked() {
6196 if (mBluetoothScanResultBgCounter == null) {
6197 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase);
6198 }
6199 return mBluetoothScanResultBgCounter;
6200 }
6201
Bookatz4ebc0642017-05-11 12:21:19 -07006202 public void noteBluetoothScanResultsLocked(int numNewResults) {
6203 createBluetoothScanResultCounterLocked().addAtomic(numNewResults);
Bookatzb1f04f32017-05-19 13:57:32 -07006204 // Uses background timebase, so the count will only be incremented if uid in background.
6205 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults);
Bookatz956f36bf2017-04-28 09:48:17 -07006206 }
6207
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006208 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006209 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006210 // We always start, since we want multiple foreground PIDs to nest
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006211 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006212 }
6213
6214 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006215 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006216 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006217 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006218 }
6219 }
6220
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07006221 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) {
6222 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs);
6223 }
6224
6225 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) {
6226 if (mForegroundServiceTimer != null) {
6227 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs);
6228 }
6229 }
6230
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006231 public BatchTimer createVibratorOnTimerLocked() {
6232 if (mVibratorOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006233 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON,
6234 mBsi.mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006235 }
6236 return mVibratorOnTimer;
6237 }
6238
6239 public void noteVibratorOnLocked(long durationMillis) {
Joe Onoratoabded112016-02-08 16:49:39 -08006240 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006241 }
6242
6243 public void noteVibratorOffLocked() {
6244 if (mVibratorOnTimer != null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006245 mVibratorOnTimer.abortLastDuration(mBsi);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006246 }
6247 }
6248
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006249 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006250 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006251 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006252 return 0;
6253 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006254 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006255 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07006256
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006257 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006258 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006259 if (mFullWifiLockTimer == null) {
6260 return 0;
6261 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006262 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07006263 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006264
6265 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006266 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07006267 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006268 return 0;
6269 }
Bookatzaa4594a2017-03-24 12:39:56 -07006270 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07006271 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006272
6273 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07006274 public int getWifiScanCount(int which) {
6275 if (mWifiScanTimer == null) {
6276 return 0;
6277 }
Bookatzaa4594a2017-03-24 12:39:56 -07006278 return mWifiScanTimer.getCountLocked(which);
Bookatz867c0d72017-03-07 18:23:42 -08006279 }
6280
6281 @Override
6282 public int getWifiScanBackgroundCount(int which) {
Bookatzaa4594a2017-03-24 12:39:56 -07006283 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) {
Bookatz867c0d72017-03-07 18:23:42 -08006284 return 0;
6285 }
6286 return mWifiScanTimer.getSubTimer().getCountLocked(which);
6287 }
6288
6289 @Override
6290 public long getWifiScanActualTime(final long elapsedRealtimeUs) {
6291 if (mWifiScanTimer == null) {
6292 return 0;
6293 }
6294 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000;
Bookatzaa4594a2017-03-24 12:39:56 -07006295 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000;
Bookatz867c0d72017-03-07 18:23:42 -08006296 }
6297
6298 @Override
6299 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) {
Bookatzaa4594a2017-03-24 12:39:56 -07006300 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) {
Bookatz867c0d72017-03-07 18:23:42 -08006301 return 0;
6302 }
6303 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000;
6304 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000;
Dianne Hackborn62793e42015-03-09 11:15:41 -07006305 }
6306
6307 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006308 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07006309 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
6310 if (mWifiBatchedScanTimer[csphBin] == null) {
6311 return 0;
6312 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006313 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006314 }
6315
6316 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07006317 public int getWifiBatchedScanCount(int csphBin, int which) {
6318 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
6319 if (mWifiBatchedScanTimer[csphBin] == null) {
6320 return 0;
6321 }
6322 return mWifiBatchedScanTimer[csphBin].getCountLocked(which);
6323 }
6324
6325 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006326 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006327 if (mWifiMulticastTimer == null) {
6328 return 0;
6329 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006330 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006331 }
6332
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006333 @Override
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006334 public Timer getAudioTurnedOnTimer() {
6335 return mAudioTurnedOnTimer;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006336 }
6337
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006338 @Override
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006339 public Timer getVideoTurnedOnTimer() {
6340 return mVideoTurnedOnTimer;
6341 }
6342
6343 @Override
6344 public Timer getFlashlightTurnedOnTimer() {
6345 return mFlashlightTurnedOnTimer;
6346 }
6347
6348 @Override
6349 public Timer getCameraTurnedOnTimer() {
6350 return mCameraTurnedOnTimer;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006351 }
6352
Dianne Hackborn617f8772009-03-31 15:04:46 -07006353 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006354 public Timer getForegroundActivityTimer() {
6355 return mForegroundActivityTimer;
6356 }
6357
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006358 @Override
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07006359 public Timer getForegroundServiceTimer() {
6360 return mForegroundServiceTimer;
6361 }
6362
6363 @Override
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006364 public Timer getBluetoothScanTimer() {
Bookatzaa4594a2017-03-24 12:39:56 -07006365 return mBluetoothScanTimer;
Bookatz867c0d72017-03-07 18:23:42 -08006366 }
6367
6368 @Override
6369 public Timer getBluetoothScanBackgroundTimer() {
6370 if (mBluetoothScanTimer == null) {
6371 return null;
6372 }
6373 return mBluetoothScanTimer.getSubTimer();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006374 }
6375
Bookatz956f36bf2017-04-28 09:48:17 -07006376 @Override
Bookatzb1f04f32017-05-19 13:57:32 -07006377 public Timer getBluetoothUnoptimizedScanTimer() {
6378 return mBluetoothUnoptimizedScanTimer;
6379 }
6380
6381 @Override
6382 public Timer getBluetoothUnoptimizedScanBackgroundTimer() {
6383 if (mBluetoothUnoptimizedScanTimer == null) {
6384 return null;
6385 }
6386 return mBluetoothUnoptimizedScanTimer.getSubTimer();
6387 }
6388
6389 @Override
Bookatz956f36bf2017-04-28 09:48:17 -07006390 public Counter getBluetoothScanResultCounter() {
6391 return mBluetoothScanResultCounter;
6392 }
6393
Bookatzb1f04f32017-05-19 13:57:32 -07006394 @Override
6395 public Counter getBluetoothScanResultBgCounter() {
6396 return mBluetoothScanResultBgCounter;
6397 }
6398
Dianne Hackborn61659e52014-07-09 16:13:01 -07006399 void makeProcessState(int i, Parcel in) {
6400 if (i < 0 || i >= NUM_PROCESS_STATE) return;
6401
6402 if (in == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006403 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null,
6404 mBsi.mOnBatteryTimeBase);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006405 } else {
Joe Onoratoabded112016-02-08 16:49:39 -08006406 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null,
6407 mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006408 }
6409 }
6410
6411 @Override
6412 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) {
6413 if (state < 0 || state >= NUM_PROCESS_STATE) return 0;
6414 if (mProcessStateTimer[state] == null) {
6415 return 0;
6416 }
6417 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which);
6418 }
6419
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006420 @Override
Joe Onorato713fec82016-03-04 10:34:02 -08006421 public Timer getProcessStateTimer(int state) {
6422 if (state < 0 || state >= NUM_PROCESS_STATE) return null;
6423 return mProcessStateTimer[state];
6424 }
6425
6426 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006427 public Timer getVibratorOnTimer() {
6428 return mVibratorOnTimer;
6429 }
6430
6431 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07006432 public void noteUserActivityLocked(int type) {
6433 if (mUserActivityCounters == null) {
6434 initUserActivityLocked();
6435 }
Jeff Browndf693de2012-07-27 12:03:38 -07006436 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
6437 mUserActivityCounters[type].stepAtomic();
6438 } else {
6439 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
6440 new Throwable());
6441 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07006442 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006443
Dianne Hackborn617f8772009-03-31 15:04:46 -07006444 @Override
6445 public boolean hasUserActivity() {
6446 return mUserActivityCounters != null;
6447 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006448
Dianne Hackborn617f8772009-03-31 15:04:46 -07006449 @Override
6450 public int getUserActivityCount(int type, int which) {
6451 if (mUserActivityCounters == null) {
6452 return 0;
6453 }
Evan Millarc64edde2009-04-18 12:26:32 -07006454 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006455 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006456
Robert Greenwalta029ea12013-09-25 16:38:12 -07006457 void makeWifiBatchedScanBin(int i, Parcel in) {
6458 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
6459
Joe Onoratoabded112016-02-08 16:49:39 -08006460 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006461 if (collected == null) {
6462 collected = new ArrayList<StopwatchTimer>();
Joe Onoratoabded112016-02-08 16:49:39 -08006463 mBsi.mWifiBatchedScanTimers.put(i, collected);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006464 }
6465 if (in == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006466 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN,
6467 collected, mBsi.mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006468 } else {
Joe Onoratoabded112016-02-08 16:49:39 -08006469 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN,
6470 collected, mBsi.mOnBatteryTimeBase, in);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006471 }
6472 }
6473
6474
Dianne Hackborn617f8772009-03-31 15:04:46 -07006475 void initUserActivityLocked() {
6476 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
6477 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08006478 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006479 }
6480 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006481
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006482 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
6483 if (mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006484 initNetworkActivityLocked();
6485 }
6486 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006487 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
6488 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006489 } else {
6490 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
6491 new Throwable());
6492 }
6493 }
6494
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006495 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
6496 if (mNetworkByteActivityCounters == null) {
6497 initNetworkActivityLocked();
6498 }
6499 mMobileRadioActiveTime.addCountLocked(batteryUptime);
6500 mMobileRadioActiveCount.addCountLocked(1);
6501 }
6502
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006503 @Override
6504 public boolean hasNetworkActivity() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006505 return mNetworkByteActivityCounters != null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006506 }
6507
6508 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006509 public long getNetworkActivityBytes(int type, int which) {
6510 if (mNetworkByteActivityCounters != null && type >= 0
6511 && type < mNetworkByteActivityCounters.length) {
6512 return mNetworkByteActivityCounters[type].getCountLocked(which);
6513 } else {
6514 return 0;
6515 }
6516 }
6517
6518 @Override
6519 public long getNetworkActivityPackets(int type, int which) {
6520 if (mNetworkPacketActivityCounters != null && type >= 0
6521 && type < mNetworkPacketActivityCounters.length) {
6522 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006523 } else {
6524 return 0;
6525 }
6526 }
6527
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006528 @Override
6529 public long getMobileRadioActiveTime(int which) {
6530 return mMobileRadioActiveTime != null
6531 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
6532 }
6533
6534 @Override
6535 public int getMobileRadioActiveCount(int which) {
6536 return mMobileRadioActiveCount != null
6537 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
6538 }
6539
Adam Lesinskie08af192015-03-25 16:42:59 -07006540 @Override
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006541 public long getUserCpuTimeUs(int which) {
6542 return mUserCpuTime.getCountLocked(which);
6543 }
6544
6545 @Override
6546 public long getSystemCpuTimeUs(int which) {
6547 return mSystemCpuTime.getCountLocked(which);
6548 }
6549
6550 @Override
Adam Lesinski6832f392015-09-05 18:05:40 -07006551 public long getTimeAtCpuSpeed(int cluster, int step, int which) {
6552 if (mCpuClusterSpeed != null) {
6553 if (cluster >= 0 && cluster < mCpuClusterSpeed.length) {
6554 final LongSamplingCounter[] cpuSpeeds = mCpuClusterSpeed[cluster];
6555 if (cpuSpeeds != null) {
6556 if (step >= 0 && step < cpuSpeeds.length) {
6557 final LongSamplingCounter c = cpuSpeeds[step];
6558 if (c != null) {
6559 return c.getCountLocked(which);
6560 }
6561 }
6562 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006563 }
6564 }
6565 return 0;
6566 }
6567
Adam Lesinski5f056f62016-07-14 16:56:08 -07006568 public void noteMobileRadioApWakeupLocked() {
6569 if (mMobileRadioApWakeupCount == null) {
6570 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6571 }
6572 mMobileRadioApWakeupCount.addCountLocked(1);
6573 }
6574
6575 @Override
6576 public long getMobileRadioApWakeupCount(int which) {
6577 if (mMobileRadioApWakeupCount != null) {
6578 return mMobileRadioApWakeupCount.getCountLocked(which);
6579 }
6580 return 0;
6581 }
6582
6583 public void noteWifiRadioApWakeupLocked() {
6584 if (mWifiRadioApWakeupCount == null) {
6585 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6586 }
6587 mWifiRadioApWakeupCount.addCountLocked(1);
6588 }
6589
6590 @Override
6591 public long getWifiRadioApWakeupCount(int which) {
6592 if (mWifiRadioApWakeupCount != null) {
6593 return mWifiRadioApWakeupCount.getCountLocked(which);
6594 }
6595 return 0;
6596 }
6597
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006598 void initNetworkActivityLocked() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006599 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
6600 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006601 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08006602 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6603 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006604 }
Joe Onoratoabded112016-02-08 16:49:39 -08006605 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6606 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006607 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07006608
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006609 /**
6610 * Clear all stats for this uid. Returns true if the uid is completely
6611 * inactive so can be dropped.
6612 */
Adam Lesinski5f212c82017-03-13 12:25:13 -07006613 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
6614 public boolean reset() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006615 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006616
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006617 if (mWifiRunningTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006618 active |= !mWifiRunningTimer.reset(false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006619 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006620 }
6621 if (mFullWifiLockTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006622 active |= !mFullWifiLockTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006623 active |= mFullWifiLockOut;
6624 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07006625 if (mWifiScanTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006626 active |= !mWifiScanTimer.reset(false);
Nick Pelly6ccaa542012-06-15 15:22:47 -07006627 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006628 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07006629 if (mWifiBatchedScanTimer != null) {
6630 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
6631 if (mWifiBatchedScanTimer[i] != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006632 active |= !mWifiBatchedScanTimer[i].reset(false);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006633 }
6634 }
6635 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
6636 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006637 if (mWifiMulticastTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006638 active |= !mWifiMulticastTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006639 active |= mWifiMulticastEnabled;
6640 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07006641
6642 active |= !resetTimerIfNotNull(mAudioTurnedOnTimer, false);
6643 active |= !resetTimerIfNotNull(mVideoTurnedOnTimer, false);
6644 active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false);
6645 active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false);
6646 active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07006647 active |= !resetTimerIfNotNull(mForegroundServiceTimer, false);
Bookatzc8c44962017-05-11 12:12:54 -07006648 active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false);
Adam Lesinski5f056f62016-07-14 16:56:08 -07006649 active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
Bookatzb1f04f32017-05-19 13:57:32 -07006650 active |= !resetTimerIfNotNull(mBluetoothUnoptimizedScanTimer, false);
Bookatz956f36bf2017-04-28 09:48:17 -07006651 if (mBluetoothScanResultCounter != null) {
6652 mBluetoothScanResultCounter.reset(false);
6653 }
Bookatzb1f04f32017-05-19 13:57:32 -07006654 if (mBluetoothScanResultBgCounter != null) {
6655 mBluetoothScanResultBgCounter.reset(false);
6656 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07006657
Dianne Hackborn61659e52014-07-09 16:13:01 -07006658 if (mProcessStateTimer != null) {
6659 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
6660 if (mProcessStateTimer[i] != null) {
6661 active |= !mProcessStateTimer[i].reset(false);
6662 }
6663 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08006664 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006665 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006666 if (mVibratorOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006667 if (mVibratorOnTimer.reset(false)) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006668 mVibratorOnTimer.detach();
6669 mVibratorOnTimer = null;
6670 } else {
6671 active = true;
6672 }
6673 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006674
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006675 if (mUserActivityCounters != null) {
6676 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
6677 mUserActivityCounters[i].reset(false);
6678 }
6679 }
6680
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006681 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006682 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006683 mNetworkByteActivityCounters[i].reset(false);
6684 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006685 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006686 mMobileRadioActiveTime.reset(false);
6687 mMobileRadioActiveCount.reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006688 }
6689
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006690 if (mWifiControllerActivity != null) {
6691 mWifiControllerActivity.reset(false);
6692 }
Adam Lesinskie08af192015-03-25 16:42:59 -07006693
Adam Lesinski1a2b39e2016-04-29 17:56:58 -07006694 if (mBluetoothControllerActivity != null) {
6695 mBluetoothControllerActivity.reset(false);
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006696 }
6697
Adam Lesinski1a2b39e2016-04-29 17:56:58 -07006698 if (mModemControllerActivity != null) {
6699 mModemControllerActivity.reset(false);
Adam Lesinskie08af192015-03-25 16:42:59 -07006700 }
6701
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006702 mUserCpuTime.reset(false);
6703 mSystemCpuTime.reset(false);
Adam Lesinski6832f392015-09-05 18:05:40 -07006704
6705 if (mCpuClusterSpeed != null) {
6706 for (LongSamplingCounter[] speeds : mCpuClusterSpeed) {
6707 if (speeds != null) {
6708 for (LongSamplingCounter speed : speeds) {
6709 if (speed != null) {
6710 speed.reset(false);
6711 }
6712 }
6713 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006714 }
6715 }
6716
Sudheer Shanka9b735c52017-05-09 18:26:18 -07006717 if (mCpuFreqTimeMs != null) {
6718 mCpuFreqTimeMs.reset(false);
6719 }
6720 if (mScreenOffCpuFreqTimeMs != null) {
6721 mScreenOffCpuFreqTimeMs.reset(false);
6722 }
6723
Adam Lesinski5f056f62016-07-14 16:56:08 -07006724 resetLongCounterIfNotNull(mMobileRadioApWakeupCount, false);
6725 resetLongCounterIfNotNull(mWifiRadioApWakeupCount, false);
6726
Dianne Hackbornd953c532014-08-16 18:17:38 -07006727 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
6728 for (int iw=wakeStats.size()-1; iw>=0; iw--) {
6729 Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006730 if (wl.reset()) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006731 wakeStats.removeAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006732 } else {
6733 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006734 }
6735 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006736 mWakelockStats.cleanup();
Bookatz2bffb5b2017-04-13 11:59:33 -07006737 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -07006738 for (int is=syncStats.size()-1; is>=0; is--) {
Bookatz2bffb5b2017-04-13 11:59:33 -07006739 DualTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006740 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006741 syncStats.removeAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006742 timer.detach();
6743 } else {
6744 active = true;
6745 }
6746 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006747 mSyncStats.cleanup();
Bookatzaa4594a2017-03-24 12:39:56 -07006748 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -07006749 for (int ij=jobStats.size()-1; ij>=0; ij--) {
Bookatzaa4594a2017-03-24 12:39:56 -07006750 DualTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006751 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006752 jobStats.removeAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006753 timer.detach();
6754 } else {
6755 active = true;
6756 }
6757 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006758 mJobStats.cleanup();
Dianne Hackborn94326cb2017-06-28 16:17:20 -07006759 mJobCompletions.clear();
Dianne Hackborn61659e52014-07-09 16:13:01 -07006760 for (int ise=mSensorStats.size()-1; ise>=0; ise--) {
6761 Sensor s = mSensorStats.valueAt(ise);
6762 if (s.reset()) {
6763 mSensorStats.removeAt(ise);
6764 } else {
6765 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006766 }
6767 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07006768 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
6769 Proc proc = mProcessStats.valueAt(ip);
Dianne Hackborna8d10942015-11-19 17:55:19 -08006770 proc.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006771 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08006772 mProcessStats.clear();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006773 if (mPids.size() > 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006774 for (int i=mPids.size()-1; i>=0; i--) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006775 Pid pid = mPids.valueAt(i);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006776 if (pid.mWakeNesting > 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006777 active = true;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006778 } else {
6779 mPids.removeAt(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07006780 }
6781 }
6782 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006783 if (mPackageStats.size() > 0) {
6784 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
6785 while (it.hasNext()) {
6786 Map.Entry<String, Pkg> pkgEntry = it.next();
6787 Pkg p = pkgEntry.getValue();
6788 p.detach();
6789 if (p.mServiceStats.size() > 0) {
6790 Iterator<Map.Entry<String, Pkg.Serv>> it2
6791 = p.mServiceStats.entrySet().iterator();
6792 while (it2.hasNext()) {
6793 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
6794 servEntry.getValue().detach();
6795 }
6796 }
6797 }
6798 mPackageStats.clear();
6799 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006800
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08006801 mLastStepUserTime = mLastStepSystemTime = 0;
6802 mCurStepUserTime = mCurStepSystemTime = 0;
6803
Bookatz867c0d72017-03-07 18:23:42 -08006804 mOnBatteryBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
6805 mBsi.mClocks.uptimeMillis() * 1000);
Bookatzc8c44962017-05-11 12:12:54 -07006806 mOnBatteryScreenOffBackgroundTimeBase.reset(mBsi.mClocks.elapsedRealtime() * 1000,
6807 mBsi.mClocks.uptimeMillis() * 1000);
Bookatz867c0d72017-03-07 18:23:42 -08006808
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006809 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006810 if (mWifiRunningTimer != null) {
6811 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006812 }
6813 if (mFullWifiLockTimer != null) {
6814 mFullWifiLockTimer.detach();
6815 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07006816 if (mWifiScanTimer != null) {
6817 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006818 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07006819 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
6820 if (mWifiBatchedScanTimer[i] != null) {
6821 mWifiBatchedScanTimer[i].detach();
6822 }
6823 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006824 if (mWifiMulticastTimer != null) {
6825 mWifiMulticastTimer.detach();
6826 }
6827 if (mAudioTurnedOnTimer != null) {
6828 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006829 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006830 }
6831 if (mVideoTurnedOnTimer != null) {
6832 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006833 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006834 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006835 if (mFlashlightTurnedOnTimer != null) {
6836 mFlashlightTurnedOnTimer.detach();
6837 mFlashlightTurnedOnTimer = null;
6838 }
6839 if (mCameraTurnedOnTimer != null) {
6840 mCameraTurnedOnTimer.detach();
6841 mCameraTurnedOnTimer = null;
6842 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006843 if (mForegroundActivityTimer != null) {
6844 mForegroundActivityTimer.detach();
6845 mForegroundActivityTimer = null;
6846 }
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07006847 if (mForegroundServiceTimer != null) {
6848 mForegroundServiceTimer.detach();
6849 mForegroundServiceTimer = null;
6850 }
Bookatzc8c44962017-05-11 12:12:54 -07006851 if (mAggregatedPartialWakelockTimer != null) {
6852 mAggregatedPartialWakelockTimer.detach();
6853 mAggregatedPartialWakelockTimer = null;
6854 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006855 if (mBluetoothScanTimer != null) {
6856 mBluetoothScanTimer.detach();
6857 mBluetoothScanTimer = null;
6858 }
Bookatzb1f04f32017-05-19 13:57:32 -07006859 if (mBluetoothUnoptimizedScanTimer != null) {
6860 mBluetoothUnoptimizedScanTimer.detach();
6861 mBluetoothUnoptimizedScanTimer = null;
6862 }
Bookatz956f36bf2017-04-28 09:48:17 -07006863 if (mBluetoothScanResultCounter != null) {
6864 mBluetoothScanResultCounter.detach();
6865 mBluetoothScanResultCounter = null;
6866 }
Bookatzb1f04f32017-05-19 13:57:32 -07006867 if (mBluetoothScanResultBgCounter != null) {
6868 mBluetoothScanResultBgCounter.detach();
6869 mBluetoothScanResultBgCounter = null;
6870 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006871 if (mUserActivityCounters != null) {
6872 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
6873 mUserActivityCounters[i].detach();
6874 }
6875 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006876 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006877 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006878 mNetworkByteActivityCounters[i].detach();
6879 mNetworkPacketActivityCounters[i].detach();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006880 }
6881 }
Adam Lesinskie08af192015-03-25 16:42:59 -07006882
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006883 if (mWifiControllerActivity != null) {
6884 mWifiControllerActivity.detach();
Adam Lesinskie08af192015-03-25 16:42:59 -07006885 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006886
6887 if (mBluetoothControllerActivity != null) {
6888 mBluetoothControllerActivity.detach();
6889 }
6890
6891 if (mModemControllerActivity != null) {
6892 mModemControllerActivity.detach();
6893 }
6894
Dianne Hackborne5167ca2014-03-08 14:39:10 -08006895 mPids.clear();
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006896
6897 mUserCpuTime.detach();
6898 mSystemCpuTime.detach();
Adam Lesinski6832f392015-09-05 18:05:40 -07006899
6900 if (mCpuClusterSpeed != null) {
6901 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) {
6902 if (cpuSpeeds != null) {
6903 for (LongSamplingCounter c : cpuSpeeds) {
6904 if (c != null) {
6905 c.detach();
6906 }
6907 }
6908 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006909 }
6910 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07006911
Sudheer Shanka9b735c52017-05-09 18:26:18 -07006912 if (mCpuFreqTimeMs != null) {
6913 mCpuFreqTimeMs.detach();
6914 }
6915 if (mScreenOffCpuFreqTimeMs != null) {
6916 mScreenOffCpuFreqTimeMs.detach();
6917 }
6918
Adam Lesinski5f056f62016-07-14 16:56:08 -07006919 detachLongCounterIfNotNull(mMobileRadioApWakeupCount);
6920 detachLongCounterIfNotNull(mWifiRadioApWakeupCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006921 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006922
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006923 return !active;
6924 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006925
Dianne Hackborn94326cb2017-06-28 16:17:20 -07006926 void writeJobCompletionsToParcelLocked(Parcel out) {
6927 int NJC = mJobCompletions.size();
6928 out.writeInt(NJC);
6929 for (int ijc=0; ijc<NJC; ijc++) {
6930 out.writeString(mJobCompletions.keyAt(ijc));
6931 SparseIntArray types = mJobCompletions.valueAt(ijc);
6932 int NT = types.size();
6933 out.writeInt(NT);
6934 for (int it=0; it<NT; it++) {
6935 out.writeInt(types.keyAt(it));
6936 out.writeInt(types.valueAt(it));
6937 }
6938 }
6939 }
6940
Bookatz867c0d72017-03-07 18:23:42 -08006941 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) {
6942 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
Bookatzc8c44962017-05-11 12:12:54 -07006943 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
Bookatz867c0d72017-03-07 18:23:42 -08006944
Dianne Hackbornd953c532014-08-16 18:17:38 -07006945 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
6946 int NW = wakeStats.size();
Dianne Hackborn61659e52014-07-09 16:13:01 -07006947 out.writeInt(NW);
6948 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006949 out.writeString(wakeStats.keyAt(iw));
6950 Uid.Wakelock wakelock = wakeStats.valueAt(iw);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006951 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006952 }
6953
Bookatz2bffb5b2017-04-13 11:59:33 -07006954 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -07006955 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006956 out.writeInt(NS);
6957 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006958 out.writeString(syncStats.keyAt(is));
Bookatz2bffb5b2017-04-13 11:59:33 -07006959 DualTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006960 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
6961 }
6962
Bookatzaa4594a2017-03-24 12:39:56 -07006963 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -07006964 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006965 out.writeInt(NJ);
6966 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006967 out.writeString(jobStats.keyAt(ij));
Bookatzaa4594a2017-03-24 12:39:56 -07006968 DualTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006969 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
6970 }
6971
Dianne Hackborn94326cb2017-06-28 16:17:20 -07006972 writeJobCompletionsToParcelLocked(out);
6973
Dianne Hackborn61659e52014-07-09 16:13:01 -07006974 int NSE = mSensorStats.size();
6975 out.writeInt(NSE);
6976 for (int ise=0; ise<NSE; ise++) {
6977 out.writeInt(mSensorStats.keyAt(ise));
6978 Uid.Sensor sensor = mSensorStats.valueAt(ise);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006979 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006980 }
6981
Dianne Hackborn61659e52014-07-09 16:13:01 -07006982 int NP = mProcessStats.size();
6983 out.writeInt(NP);
6984 for (int ip=0; ip<NP; ip++) {
6985 out.writeString(mProcessStats.keyAt(ip));
6986 Uid.Proc proc = mProcessStats.valueAt(ip);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006987 proc.writeToParcelLocked(out);
6988 }
6989
6990 out.writeInt(mPackageStats.size());
6991 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
6992 out.writeString(pkgEntry.getKey());
6993 Uid.Pkg pkg = pkgEntry.getValue();
6994 pkg.writeToParcelLocked(out);
6995 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006996
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006997 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006998 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006999 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007000 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007001 out.writeInt(0);
7002 }
7003 if (mFullWifiLockTimer != null) {
7004 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007005 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007006 } else {
7007 out.writeInt(0);
7008 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07007009 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007010 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007011 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007012 } else {
7013 out.writeInt(0);
7014 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07007015 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7016 if (mWifiBatchedScanTimer[i] != null) {
7017 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007018 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07007019 } else {
7020 out.writeInt(0);
7021 }
7022 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007023 if (mWifiMulticastTimer != null) {
7024 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007025 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007026 } else {
7027 out.writeInt(0);
7028 }
Adam Lesinskie08af192015-03-25 16:42:59 -07007029
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007030 if (mAudioTurnedOnTimer != null) {
7031 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007032 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007033 } else {
7034 out.writeInt(0);
7035 }
7036 if (mVideoTurnedOnTimer != null) {
7037 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007038 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007039 } else {
7040 out.writeInt(0);
7041 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07007042 if (mFlashlightTurnedOnTimer != null) {
7043 out.writeInt(1);
7044 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
7045 } else {
7046 out.writeInt(0);
7047 }
7048 if (mCameraTurnedOnTimer != null) {
7049 out.writeInt(1);
7050 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
7051 } else {
7052 out.writeInt(0);
7053 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007054 if (mForegroundActivityTimer != null) {
7055 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007056 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007057 } else {
7058 out.writeInt(0);
7059 }
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07007060 if (mForegroundServiceTimer != null) {
7061 out.writeInt(1);
7062 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs);
7063 } else {
7064 out.writeInt(0);
7065 }
Bookatzc8c44962017-05-11 12:12:54 -07007066 if (mAggregatedPartialWakelockTimer != null) {
7067 out.writeInt(1);
7068 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs);
7069 } else {
7070 out.writeInt(0);
7071 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08007072 if (mBluetoothScanTimer != null) {
7073 out.writeInt(1);
7074 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs);
7075 } else {
7076 out.writeInt(0);
7077 }
Bookatzb1f04f32017-05-19 13:57:32 -07007078 if (mBluetoothUnoptimizedScanTimer != null) {
7079 out.writeInt(1);
7080 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs);
7081 } else {
7082 out.writeInt(0);
7083 }
Bookatz956f36bf2017-04-28 09:48:17 -07007084 if (mBluetoothScanResultCounter != null) {
7085 out.writeInt(1);
7086 mBluetoothScanResultCounter.writeToParcel(out);
7087 } else {
7088 out.writeInt(0);
7089 }
Bookatzb1f04f32017-05-19 13:57:32 -07007090 if (mBluetoothScanResultBgCounter != null) {
7091 out.writeInt(1);
7092 mBluetoothScanResultBgCounter.writeToParcel(out);
7093 } else {
7094 out.writeInt(0);
7095 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07007096 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
7097 if (mProcessStateTimer[i] != null) {
7098 out.writeInt(1);
7099 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs);
7100 } else {
7101 out.writeInt(0);
7102 }
7103 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007104 if (mVibratorOnTimer != null) {
7105 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007106 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007107 } else {
7108 out.writeInt(0);
7109 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007110 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07007111 out.writeInt(1);
7112 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
7113 mUserActivityCounters[i].writeToParcel(out);
7114 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007115 } else {
7116 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007117 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007118 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007119 out.writeInt(1);
7120 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007121 mNetworkByteActivityCounters[i].writeToParcel(out);
7122 mNetworkPacketActivityCounters[i].writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007123 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007124 mMobileRadioActiveTime.writeToParcel(out);
7125 mMobileRadioActiveCount.writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007126 } else {
7127 out.writeInt(0);
7128 }
Adam Lesinskie08af192015-03-25 16:42:59 -07007129
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007130 if (mWifiControllerActivity != null) {
7131 out.writeInt(1);
7132 mWifiControllerActivity.writeToParcel(out, 0);
7133 } else {
7134 out.writeInt(0);
Adam Lesinskie08af192015-03-25 16:42:59 -07007135 }
7136
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007137 if (mBluetoothControllerActivity != null) {
7138 out.writeInt(1);
7139 mBluetoothControllerActivity.writeToParcel(out, 0);
7140 } else {
7141 out.writeInt(0);
7142 }
7143
7144 if (mModemControllerActivity != null) {
7145 out.writeInt(1);
7146 mModemControllerActivity.writeToParcel(out, 0);
7147 } else {
7148 out.writeInt(0);
Adam Lesinskie08af192015-03-25 16:42:59 -07007149 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007150
7151 mUserCpuTime.writeToParcel(out);
7152 mSystemCpuTime.writeToParcel(out);
7153
Adam Lesinski6832f392015-09-05 18:05:40 -07007154 if (mCpuClusterSpeed != null) {
7155 out.writeInt(1);
7156 out.writeInt(mCpuClusterSpeed.length);
7157 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeed) {
7158 if (cpuSpeeds != null) {
7159 out.writeInt(1);
7160 out.writeInt(cpuSpeeds.length);
7161 for (LongSamplingCounter c : cpuSpeeds) {
7162 if (c != null) {
7163 out.writeInt(1);
7164 c.writeToParcel(out);
7165 } else {
7166 out.writeInt(0);
7167 }
7168 }
7169 } else {
7170 out.writeInt(0);
7171 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007172 }
Adam Lesinski6832f392015-09-05 18:05:40 -07007173 } else {
7174 out.writeInt(0);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007175 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07007176
Sudheer Shanka59f5c002017-05-15 10:57:15 -07007177 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs);
7178 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs);
Sudheer Shanka9b735c52017-05-09 18:26:18 -07007179
Adam Lesinski5f056f62016-07-14 16:56:08 -07007180 if (mMobileRadioApWakeupCount != null) {
7181 out.writeInt(1);
7182 mMobileRadioApWakeupCount.writeToParcel(out);
7183 } else {
7184 out.writeInt(0);
7185 }
7186
7187 if (mWifiRadioApWakeupCount != null) {
7188 out.writeInt(1);
7189 mWifiRadioApWakeupCount.writeToParcel(out);
7190 } else {
7191 out.writeInt(0);
7192 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007193 }
7194
Dianne Hackborn94326cb2017-06-28 16:17:20 -07007195 void readJobCompletionsFromParcelLocked(Parcel in) {
7196 int numJobCompletions = in.readInt();
7197 mJobCompletions.clear();
7198 for (int j = 0; j < numJobCompletions; j++) {
7199 String jobName = in.readString();
7200 int numTypes = in.readInt();
7201 if (numTypes > 0) {
7202 SparseIntArray types = new SparseIntArray();
7203 for (int k = 0; k < numTypes; k++) {
7204 int type = in.readInt();
7205 int count = in.readInt();
7206 types.put(type, count);
7207 }
7208 mJobCompletions.put(jobName, types);
7209 }
7210 }
7211 }
7212
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007213 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
Bookatz867c0d72017-03-07 18:23:42 -08007214 mOnBatteryBackgroundTimeBase.readFromParcel(in);
Bookatzc8c44962017-05-11 12:12:54 -07007215 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in);
Bookatz867c0d72017-03-07 18:23:42 -08007216
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007217 int numWakelocks = in.readInt();
7218 mWakelockStats.clear();
7219 for (int j = 0; j < numWakelocks; j++) {
7220 String wakelockName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -08007221 Uid.Wakelock wakelock = new Wakelock(mBsi, this);
Bookatz5b5ec322017-05-26 09:40:38 -07007222 wakelock.readFromParcelLocked(
7223 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in);
Dianne Hackbornd953c532014-08-16 18:17:38 -07007224 mWakelockStats.add(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007225 }
7226
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007227 int numSyncs = in.readInt();
7228 mSyncStats.clear();
7229 for (int j = 0; j < numSyncs; j++) {
7230 String syncName = in.readString();
7231 if (in.readInt() != 0) {
Bookatz2bffb5b2017-04-13 11:59:33 -07007232 mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null,
7233 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in));
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007234 }
7235 }
7236
7237 int numJobs = in.readInt();
7238 mJobStats.clear();
7239 for (int j = 0; j < numJobs; j++) {
7240 String jobName = in.readString();
7241 if (in.readInt() != 0) {
Bookatzaa4594a2017-03-24 12:39:56 -07007242 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null,
7243 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in));
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007244 }
7245 }
7246
Dianne Hackborn94326cb2017-06-28 16:17:20 -07007247 readJobCompletionsFromParcelLocked(in);
7248
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007249 int numSensors = in.readInt();
7250 mSensorStats.clear();
7251 for (int k = 0; k < numSensors; k++) {
7252 int sensorNumber = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -08007253 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber);
Bookatz867c0d72017-03-07 18:23:42 -08007254 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase,
7255 in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007256 mSensorStats.put(sensorNumber, sensor);
7257 }
7258
7259 int numProcs = in.readInt();
7260 mProcessStats.clear();
7261 for (int k = 0; k < numProcs; k++) {
7262 String processName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -08007263 Uid.Proc proc = new Proc(mBsi, processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007264 proc.readFromParcelLocked(in);
7265 mProcessStats.put(processName, proc);
7266 }
7267
7268 int numPkgs = in.readInt();
7269 mPackageStats.clear();
7270 for (int l = 0; l < numPkgs; l++) {
7271 String packageName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -08007272 Uid.Pkg pkg = new Pkg(mBsi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007273 pkg.readFromParcelLocked(in);
7274 mPackageStats.put(packageName, pkg);
7275 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007276
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007277 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007278 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007279 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING,
7280 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007281 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007282 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007283 }
7284 mFullWifiLockOut = false;
7285 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007286 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK,
7287 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007288 } else {
7289 mFullWifiLockTimer = null;
7290 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07007291 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007292 if (in.readInt() != 0) {
Bookatz867c0d72017-03-07 18:23:42 -08007293 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN,
7294 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase,
7295 in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007296 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07007297 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007298 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07007299 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
7300 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7301 if (in.readInt() != 0) {
7302 makeWifiBatchedScanBin(i, in);
7303 } else {
7304 mWifiBatchedScanTimer[i] = null;
7305 }
7306 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007307 mWifiMulticastEnabled = false;
7308 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007309 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED,
7310 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007311 } else {
7312 mWifiMulticastTimer = null;
7313 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007314 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007315 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON,
7316 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007317 } else {
7318 mAudioTurnedOnTimer = null;
7319 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007320 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007321 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON,
7322 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007323 } else {
7324 mVideoTurnedOnTimer = null;
7325 }
7326 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007327 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7328 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07007329 } else {
7330 mFlashlightTurnedOnTimer = null;
7331 }
7332 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007333 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON,
7334 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07007335 } else {
7336 mCameraTurnedOnTimer = null;
7337 }
7338 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007339 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7340 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007341 } else {
7342 mForegroundActivityTimer = null;
7343 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08007344 if (in.readInt() != 0) {
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07007345 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7346 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in);
7347 } else {
7348 mForegroundServiceTimer = null;
7349 }
7350 if (in.readInt() != 0) {
Bookatzc8c44962017-05-11 12:12:54 -07007351 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
7352 AGGREGATED_WAKE_TYPE_PARTIAL, null,
7353 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase,
7354 in);
7355 } else {
7356 mAggregatedPartialWakelockTimer = null;
7357 }
7358 if (in.readInt() != 0) {
Bookatz867c0d72017-03-07 18:23:42 -08007359 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
7360 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
7361 mOnBatteryBackgroundTimeBase, in);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08007362 } else {
7363 mBluetoothScanTimer = null;
7364 }
Bookatz956f36bf2017-04-28 09:48:17 -07007365 if (in.readInt() != 0) {
Bookatzb1f04f32017-05-19 13:57:32 -07007366 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
7367 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
7368 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in);
7369 } else {
7370 mBluetoothUnoptimizedScanTimer = null;
7371 }
7372 if (in.readInt() != 0) {
Bookatz956f36bf2017-04-28 09:48:17 -07007373 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in);
7374 } else {
7375 mBluetoothScanResultCounter = null;
7376 }
Bookatzb1f04f32017-05-19 13:57:32 -07007377 if (in.readInt() != 0) {
7378 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in);
7379 } else {
7380 mBluetoothScanResultBgCounter = null;
7381 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08007382 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
Dianne Hackborn61659e52014-07-09 16:13:01 -07007383 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
7384 if (in.readInt() != 0) {
7385 makeProcessState(i, in);
7386 } else {
7387 mProcessStateTimer[i] = null;
7388 }
7389 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007390 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007391 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON,
7392 mBsi.mOnBatteryTimeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007393 } else {
7394 mVibratorOnTimer = null;
7395 }
7396 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07007397 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
7398 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08007399 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007400 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007401 } else {
7402 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07007403 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007404 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007405 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
7406 mNetworkPacketActivityCounters
7407 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007408 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007409 mNetworkByteActivityCounters[i]
Joe Onoratoabded112016-02-08 16:49:39 -08007410 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007411 mNetworkPacketActivityCounters[i]
Joe Onoratoabded112016-02-08 16:49:39 -08007412 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007413 }
Joe Onoratoabded112016-02-08 16:49:39 -08007414 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
7415 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007416 } else {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007417 mNetworkByteActivityCounters = null;
7418 mNetworkPacketActivityCounters = null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007419 }
Adam Lesinskie08af192015-03-25 16:42:59 -07007420
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007421 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007422 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007423 NUM_WIFI_TX_LEVELS, in);
7424 } else {
7425 mWifiControllerActivity = null;
Adam Lesinskie08af192015-03-25 16:42:59 -07007426 }
7427
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007428 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007429 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007430 NUM_BT_TX_LEVELS, in);
7431 } else {
7432 mBluetoothControllerActivity = null;
7433 }
7434
7435 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007436 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007437 ModemActivityInfo.TX_POWER_LEVELS, in);
7438 } else {
7439 mModemControllerActivity = null;
Adam Lesinskie08af192015-03-25 16:42:59 -07007440 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007441
Joe Onoratoabded112016-02-08 16:49:39 -08007442 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
7443 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007444
Adam Lesinski6832f392015-09-05 18:05:40 -07007445 if (in.readInt() != 0) {
7446 int numCpuClusters = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -08007447 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) {
Adam Lesinski6832f392015-09-05 18:05:40 -07007448 throw new ParcelFormatException("Incompatible number of cpu clusters");
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007449 }
Adam Lesinski6832f392015-09-05 18:05:40 -07007450
7451 mCpuClusterSpeed = new LongSamplingCounter[numCpuClusters][];
7452 for (int cluster = 0; cluster < numCpuClusters; cluster++) {
7453 if (in.readInt() != 0) {
7454 int numSpeeds = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -08007455 if (mBsi.mPowerProfile != null &&
7456 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) {
Adam Lesinski6832f392015-09-05 18:05:40 -07007457 throw new ParcelFormatException("Incompatible number of cpu speeds");
7458 }
7459
7460 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds];
7461 mCpuClusterSpeed[cluster] = cpuSpeeds;
7462 for (int speed = 0; speed < numSpeeds; speed++) {
7463 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007464 cpuSpeeds[speed] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
Adam Lesinski6832f392015-09-05 18:05:40 -07007465 }
7466 }
Adam Lesinskia57a5402015-09-28 10:21:33 -07007467 } else {
7468 mCpuClusterSpeed[cluster] = null;
Adam Lesinski6832f392015-09-05 18:05:40 -07007469 }
7470 }
7471 } else {
7472 mCpuClusterSpeed = null;
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007473 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07007474
Sudheer Shanka59f5c002017-05-15 10:57:15 -07007475 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase);
7476 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(
7477 in, mBsi.mOnBatteryScreenOffTimeBase);
Sudheer Shanka9b735c52017-05-09 18:26:18 -07007478
7479 if (in.readInt() != 0) {
Adam Lesinski5f056f62016-07-14 16:56:08 -07007480 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
7481 } else {
7482 mMobileRadioApWakeupCount = null;
7483 }
7484
7485 if (in.readInt() != 0) {
7486 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
7487 } else {
7488 mWifiRadioApWakeupCount = null;
7489 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007490 }
7491
7492 /**
7493 * The statistics associated with a particular wake lock.
7494 */
Joe Onoratoabded112016-02-08 16:49:39 -08007495 public static class Wakelock extends BatteryStats.Uid.Wakelock {
7496 /**
7497 * BatteryStatsImpl that we are associated with.
7498 */
7499 protected BatteryStatsImpl mBsi;
7500
7501 /**
7502 * BatteryStatsImpl that we are associated with.
7503 */
7504 protected Uid mUid;
7505
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007506 /**
7507 * How long (in ms) this uid has been keeping the device partially awake.
Bookatz5b5ec322017-05-26 09:40:38 -07007508 * Tracks both the total time and the time while the app was in the background.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007509 */
Bookatz5b5ec322017-05-26 09:40:38 -07007510 DualTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007511
7512 /**
7513 * How long (in ms) this uid has been keeping the device fully awake.
7514 */
Evan Millarc64edde2009-04-18 12:26:32 -07007515 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007516
7517 /**
7518 * How long (in ms) this uid has had a window keeping the device awake.
7519 */
Evan Millarc64edde2009-04-18 12:26:32 -07007520 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007521
7522 /**
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007523 * How long (in ms) this uid has had a draw wake lock.
Adam Lesinski9425fe22015-06-19 12:02:13 -07007524 */
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007525 StopwatchTimer mTimerDraw;
Adam Lesinski9425fe22015-06-19 12:02:13 -07007526
Joe Onoratoabded112016-02-08 16:49:39 -08007527 public Wakelock(BatteryStatsImpl bsi, Uid uid) {
7528 mBsi = bsi;
7529 mUid = uid;
7530 }
7531
Adam Lesinski9425fe22015-06-19 12:02:13 -07007532 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007533 * Reads a possibly null Timer from a Parcel. The timer is associated with the
7534 * proper timer pool from the given BatteryStatsImpl object.
7535 *
7536 * @param in the Parcel to be read from.
7537 * return a new Timer, or null.
7538 */
Joe Onorato92fd23f2016-07-25 11:18:42 -07007539 private StopwatchTimer readStopwatchTimerFromParcel(int type,
7540 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007541 if (in.readInt() == 0) {
7542 return null;
7543 }
7544
Joe Onoratoabded112016-02-08 16:49:39 -08007545 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007546 }
7547
Joe Onorato92fd23f2016-07-25 11:18:42 -07007548 /**
7549 * Reads a possibly null Timer from a Parcel. The timer is associated with the
7550 * proper timer pool from the given BatteryStatsImpl object.
7551 *
7552 * @param in the Parcel to be read from.
7553 * return a new Timer, or null.
7554 */
Bookatz5b5ec322017-05-26 09:40:38 -07007555 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
7556 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
Joe Onorato92fd23f2016-07-25 11:18:42 -07007557 if (in.readInt() == 0) {
7558 return null;
7559 }
7560
Bookatz5b5ec322017-05-26 09:40:38 -07007561 return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in);
Joe Onorato92fd23f2016-07-25 11:18:42 -07007562 }
7563
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007564 boolean reset() {
7565 boolean wlactive = false;
7566 if (mTimerFull != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007567 wlactive |= !mTimerFull.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007568 }
7569 if (mTimerPartial != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007570 wlactive |= !mTimerPartial.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007571 }
7572 if (mTimerWindow != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007573 wlactive |= !mTimerWindow.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007574 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007575 if (mTimerDraw != null) {
7576 wlactive |= !mTimerDraw.reset(false);
Adam Lesinski9425fe22015-06-19 12:02:13 -07007577 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007578 if (!wlactive) {
7579 if (mTimerFull != null) {
7580 mTimerFull.detach();
7581 mTimerFull = null;
7582 }
7583 if (mTimerPartial != null) {
7584 mTimerPartial.detach();
7585 mTimerPartial = null;
7586 }
7587 if (mTimerWindow != null) {
7588 mTimerWindow.detach();
7589 mTimerWindow = null;
7590 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007591 if (mTimerDraw != null) {
7592 mTimerDraw.detach();
7593 mTimerDraw = null;
Adam Lesinski9425fe22015-06-19 12:02:13 -07007594 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007595 }
7596 return !wlactive;
7597 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007598
Bookatz5b5ec322017-05-26 09:40:38 -07007599 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase,
7600 TimeBase screenOffBgTimeBase, Parcel in) {
7601 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL,
7602 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in);
Joe Onorato92fd23f2016-07-25 11:18:42 -07007603 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL,
7604 mBsi.mFullTimers, timeBase, in);
7605 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW,
7606 mBsi.mWindowTimers, timeBase, in);
7607 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW,
7608 mBsi.mDrawTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007609 }
7610
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007611 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
7612 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
7613 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
7614 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007615 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007616 }
7617
7618 @Override
7619 public Timer getWakeTime(int type) {
7620 switch (type) {
7621 case WAKE_TYPE_FULL: return mTimerFull;
7622 case WAKE_TYPE_PARTIAL: return mTimerPartial;
7623 case WAKE_TYPE_WINDOW: return mTimerWindow;
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007624 case WAKE_TYPE_DRAW: return mTimerDraw;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007625 default: throw new IllegalArgumentException("type = " + type);
7626 }
7627 }
7628 }
7629
Joe Onoratoabded112016-02-08 16:49:39 -08007630 public static class Sensor extends BatteryStats.Uid.Sensor {
7631 /**
7632 * BatteryStatsImpl that we are associated with.
7633 */
7634 protected BatteryStatsImpl mBsi;
7635
7636 /**
Bookatz867c0d72017-03-07 18:23:42 -08007637 * Uid that we are associated with.
Joe Onoratoabded112016-02-08 16:49:39 -08007638 */
7639 protected Uid mUid;
7640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007641 final int mHandle;
Bookatz867c0d72017-03-07 18:23:42 -08007642 DualTimer mTimer;
Amith Yamasaniab9ad192016-12-06 12:46:59 -08007643
Joe Onoratoabded112016-02-08 16:49:39 -08007644 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) {
7645 mBsi = bsi;
7646 mUid = uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007647 mHandle = handle;
7648 }
7649
Bookatz867c0d72017-03-07 18:23:42 -08007650 private DualTimer readTimersFromParcel(
7651 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007652 if (in.readInt() == 0) {
7653 return null;
7654 }
7655
Joe Onoratoabded112016-02-08 16:49:39 -08007656 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007657 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07007658 pool = new ArrayList<StopwatchTimer>();
Joe Onoratoabded112016-02-08 16:49:39 -08007659 mBsi.mSensorTimers.put(mHandle, pool);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007660 }
Bookatz867c0d72017-03-07 18:23:42 -08007661 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in);
Amith Yamasaniab9ad192016-12-06 12:46:59 -08007662 }
7663
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007664 boolean reset() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007665 if (mTimer.reset(true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007666 mTimer = null;
7667 return true;
7668 }
7669 return false;
7670 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007671
Bookatz867c0d72017-03-07 18:23:42 -08007672 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
7673 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007674 }
7675
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007676 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
Bookatzaa4594a2017-03-24 12:39:56 -07007677 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007678 }
7679
7680 @Override
7681 public Timer getSensorTime() {
Bookatzaa4594a2017-03-24 12:39:56 -07007682 return mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007683 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007684
7685 @Override
Bookatz867c0d72017-03-07 18:23:42 -08007686 public Timer getSensorBackgroundTime() {
7687 if (mTimer == null) {
7688 return null;
7689 }
7690 return mTimer.getSubTimer();
Amith Yamasaniab9ad192016-12-06 12:46:59 -08007691 }
7692
7693 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007694 public int getHandle() {
7695 return mHandle;
7696 }
7697 }
7698
7699 /**
7700 * The statistics associated with a particular process.
7701 */
Joe Onoratoabded112016-02-08 16:49:39 -08007702 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
7703 /**
7704 * BatteryStatsImpl that we are associated with.
7705 */
7706 protected BatteryStatsImpl mBsi;
7707
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007708 /**
Dianne Hackborncd0e3352014-08-07 17:08:09 -07007709 * The name of this process.
7710 */
7711 final String mName;
7712
7713 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -08007714 * Remains true until removed from the stats.
7715 */
7716 boolean mActive = true;
7717
7718 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07007719 * Total time (in ms) spent executing in user code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007720 */
7721 long mUserTime;
7722
7723 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07007724 * Total time (in ms) spent executing in kernel code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007725 */
7726 long mSystemTime;
7727
7728 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07007729 * Amount of time (in ms) the process was running in the foreground.
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007730 */
7731 long mForegroundTime;
7732
7733 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007734 * Number of times the process has been started.
7735 */
7736 int mStarts;
7737
7738 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007739 * Number of times the process has crashed.
7740 */
7741 int mNumCrashes;
7742
7743 /**
7744 * Number of times the process has had an ANR.
7745 */
7746 int mNumAnrs;
7747
7748 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007749 * The amount of user time loaded from a previous save.
7750 */
7751 long mLoadedUserTime;
7752
7753 /**
7754 * The amount of system time loaded from a previous save.
7755 */
7756 long mLoadedSystemTime;
7757
7758 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007759 * The amount of foreground time loaded from a previous save.
7760 */
7761 long mLoadedForegroundTime;
7762
7763 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007764 * The number of times the process has started from a previous save.
7765 */
7766 int mLoadedStarts;
7767
7768 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007769 * Number of times the process has crashed from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007770 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007771 int mLoadedNumCrashes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007772
7773 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007774 * Number of times the process has had an ANR from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007775 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007776 int mLoadedNumAnrs;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007777
7778 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007779 * The amount of user time when last unplugged.
7780 */
7781 long mUnpluggedUserTime;
7782
7783 /**
7784 * The amount of system time when last unplugged.
7785 */
7786 long mUnpluggedSystemTime;
7787
7788 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007789 * The amount of foreground time since unplugged.
7790 */
7791 long mUnpluggedForegroundTime;
7792
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007793 /**
7794 * The number of times the process has started before unplugged.
7795 */
7796 int mUnpluggedStarts;
7797
Dianne Hackborn61659e52014-07-09 16:13:01 -07007798 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007799 * Number of times the process has crashed before unplugged.
7800 */
7801 int mUnpluggedNumCrashes;
7802
7803 /**
7804 * Number of times the process has had an ANR before unplugged.
7805 */
7806 int mUnpluggedNumAnrs;
7807
Dianne Hackborn287952c2010-09-22 22:34:31 -07007808 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007809
Joe Onoratoabded112016-02-08 16:49:39 -08007810 public Proc(BatteryStatsImpl bsi, String name) {
7811 mBsi = bsi;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07007812 mName = name;
Joe Onoratoabded112016-02-08 16:49:39 -08007813 mBsi.mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007814 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07007815
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007816 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007817 mUnpluggedUserTime = mUserTime;
7818 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007819 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007820 mUnpluggedStarts = mStarts;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007821 mUnpluggedNumCrashes = mNumCrashes;
7822 mUnpluggedNumAnrs = mNumAnrs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007823 }
7824
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007825 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007826 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007827
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007828 void detach() {
Dianne Hackborn099bc622014-01-22 13:39:16 -08007829 mActive = false;
Joe Onoratoabded112016-02-08 16:49:39 -08007830 mBsi.mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007831 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007832
Dianne Hackborn287952c2010-09-22 22:34:31 -07007833 public int countExcessivePowers() {
7834 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007835 }
7836
Dianne Hackborn287952c2010-09-22 22:34:31 -07007837 public ExcessivePower getExcessivePower(int i) {
7838 if (mExcessivePower != null) {
7839 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007840 }
7841 return null;
7842 }
7843
Dianne Hackborn287952c2010-09-22 22:34:31 -07007844 public void addExcessiveCpu(long overTime, long usedTime) {
7845 if (mExcessivePower == null) {
7846 mExcessivePower = new ArrayList<ExcessivePower>();
7847 }
7848 ExcessivePower ew = new ExcessivePower();
7849 ew.type = ExcessivePower.TYPE_CPU;
7850 ew.overTime = overTime;
7851 ew.usedTime = usedTime;
7852 mExcessivePower.add(ew);
7853 }
7854
7855 void writeExcessivePowerToParcelLocked(Parcel out) {
7856 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007857 out.writeInt(0);
7858 return;
7859 }
7860
Dianne Hackborn287952c2010-09-22 22:34:31 -07007861 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007862 out.writeInt(N);
7863 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07007864 ExcessivePower ew = mExcessivePower.get(i);
7865 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007866 out.writeLong(ew.overTime);
7867 out.writeLong(ew.usedTime);
7868 }
7869 }
7870
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07007871 void readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007872 final int N = in.readInt();
7873 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07007874 mExcessivePower = null;
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07007875 return;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007876 }
7877
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007878 if (N > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07007879 throw new ParcelFormatException(
7880 "File corrupt: too many excessive power entries " + N);
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08007881 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07007882
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07007883 mExcessivePower = new ArrayList<>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007884 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07007885 ExcessivePower ew = new ExcessivePower();
7886 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007887 ew.overTime = in.readLong();
7888 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07007889 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007890 }
7891 }
7892
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007893 void writeToParcelLocked(Parcel out) {
7894 out.writeLong(mUserTime);
7895 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007896 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007897 out.writeInt(mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007898 out.writeInt(mNumCrashes);
7899 out.writeInt(mNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007900 out.writeLong(mLoadedUserTime);
7901 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007902 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007903 out.writeInt(mLoadedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007904 out.writeInt(mLoadedNumCrashes);
7905 out.writeInt(mLoadedNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007906 out.writeLong(mUnpluggedUserTime);
7907 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007908 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007909 out.writeInt(mUnpluggedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007910 out.writeInt(mUnpluggedNumCrashes);
7911 out.writeInt(mUnpluggedNumAnrs);
Dianne Hackborn287952c2010-09-22 22:34:31 -07007912 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007913 }
7914
7915 void readFromParcelLocked(Parcel in) {
7916 mUserTime = in.readLong();
7917 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007918 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007919 mStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007920 mNumCrashes = in.readInt();
7921 mNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007922 mLoadedUserTime = in.readLong();
7923 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007924 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007925 mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007926 mLoadedNumCrashes = in.readInt();
7927 mLoadedNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007928 mUnpluggedUserTime = in.readLong();
7929 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007930 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007931 mUnpluggedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007932 mUnpluggedNumCrashes = in.readInt();
7933 mUnpluggedNumAnrs = in.readInt();
Dianne Hackborn287952c2010-09-22 22:34:31 -07007934 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007935 }
7936
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007937 public void addCpuTimeLocked(int utime, int stime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007938 mUserTime += utime;
7939 mSystemTime += stime;
7940 }
7941
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007942 public void addForegroundTimeLocked(long ttime) {
7943 mForegroundTime += ttime;
7944 }
7945
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007946 public void incStartsLocked() {
7947 mStarts++;
7948 }
7949
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007950 public void incNumCrashesLocked() {
7951 mNumCrashes++;
7952 }
7953
7954 public void incNumAnrsLocked() {
7955 mNumAnrs++;
7956 }
7957
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007958 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08007959 public boolean isActive() {
7960 return mActive;
7961 }
7962
7963 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007964 public long getUserTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07007965 long val = mUserTime;
7966 if (which == STATS_CURRENT) {
7967 val -= mLoadedUserTime;
7968 } else if (which == STATS_SINCE_UNPLUGGED) {
7969 val -= mUnpluggedUserTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007970 }
7971 return val;
7972 }
7973
7974 @Override
7975 public long getSystemTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07007976 long val = mSystemTime;
7977 if (which == STATS_CURRENT) {
7978 val -= mLoadedSystemTime;
7979 } else if (which == STATS_SINCE_UNPLUGGED) {
7980 val -= mUnpluggedSystemTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007981 }
7982 return val;
7983 }
7984
7985 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007986 public long getForegroundTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07007987 long val = mForegroundTime;
7988 if (which == STATS_CURRENT) {
7989 val -= mLoadedForegroundTime;
7990 } else if (which == STATS_SINCE_UNPLUGGED) {
7991 val -= mUnpluggedForegroundTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007992 }
7993 return val;
7994 }
7995
7996 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007997 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07007998 int val = mStarts;
7999 if (which == STATS_CURRENT) {
8000 val -= mLoadedStarts;
8001 } else if (which == STATS_SINCE_UNPLUGGED) {
8002 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008003 }
8004 return val;
8005 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07008006
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008007 @Override
8008 public int getNumCrashes(int which) {
8009 int val = mNumCrashes;
8010 if (which == STATS_CURRENT) {
8011 val -= mLoadedNumCrashes;
8012 } else if (which == STATS_SINCE_UNPLUGGED) {
8013 val -= mUnpluggedNumCrashes;
8014 }
8015 return val;
8016 }
8017
8018 @Override
8019 public int getNumAnrs(int which) {
8020 int val = mNumAnrs;
8021 if (which == STATS_CURRENT) {
8022 val -= mLoadedNumAnrs;
8023 } else if (which == STATS_SINCE_UNPLUGGED) {
8024 val -= mUnpluggedNumAnrs;
8025 }
8026 return val;
8027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008028 }
8029
8030 /**
8031 * The statistics associated with a particular package.
8032 */
Joe Onoratoabded112016-02-08 16:49:39 -08008033 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
8034 /**
8035 * BatteryStatsImpl that we are associated with.
8036 */
8037 protected BatteryStatsImpl mBsi;
8038
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008039 /**
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008040 * Number of times wakeup alarms have occurred for this app.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008041 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008042 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008043
8044 /**
8045 * The statics we have collected for this package's services.
8046 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008047 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008048
Joe Onoratoabded112016-02-08 16:49:39 -08008049 public Pkg(BatteryStatsImpl bsi) {
8050 mBsi = bsi;
8051 mBsi.mOnBatteryScreenOffTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008052 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008053
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008054 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008055 }
8056
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008057 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008058 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008059
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008060 void detach() {
Joe Onoratoabded112016-02-08 16:49:39 -08008061 mBsi.mOnBatteryScreenOffTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008062 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008063
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008064 void readFromParcelLocked(Parcel in) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008065 int numWA = in.readInt();
8066 mWakeupAlarms.clear();
8067 for (int i=0; i<numWA; i++) {
8068 String tag = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -08008069 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryTimeBase, in));
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008070 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008071
8072 int numServs = in.readInt();
8073 mServiceStats.clear();
8074 for (int m = 0; m < numServs; m++) {
8075 String serviceName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -08008076 Uid.Pkg.Serv serv = new Serv(mBsi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008077 mServiceStats.put(serviceName, serv);
8078
8079 serv.readFromParcelLocked(in);
8080 }
8081 }
8082
8083 void writeToParcelLocked(Parcel out) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008084 int numWA = mWakeupAlarms.size();
8085 out.writeInt(numWA);
8086 for (int i=0; i<numWA; i++) {
8087 out.writeString(mWakeupAlarms.keyAt(i));
8088 mWakeupAlarms.valueAt(i).writeToParcel(out);
8089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008090
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008091 final int NS = mServiceStats.size();
8092 out.writeInt(NS);
8093 for (int i=0; i<NS; i++) {
8094 out.writeString(mServiceStats.keyAt(i));
8095 Uid.Pkg.Serv serv = mServiceStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008096 serv.writeToParcelLocked(out);
8097 }
8098 }
8099
8100 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008101 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() {
8102 return mWakeupAlarms;
8103 }
8104
8105 public void noteWakeupAlarmLocked(String tag) {
8106 Counter c = mWakeupAlarms.get(tag);
8107 if (c == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08008108 c = new Counter(mBsi.mOnBatteryTimeBase);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008109 mWakeupAlarms.put(tag, c);
8110 }
8111 c.stepAtomic();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008112 }
8113
8114 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008115 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
8116 return mServiceStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008117 }
8118
8119 /**
8120 * The statistics associated with a particular service.
8121 */
Joe Onoratoabded112016-02-08 16:49:39 -08008122 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
8123 /**
8124 * BatteryStatsImpl that we are associated with.
8125 */
8126 protected BatteryStatsImpl mBsi;
8127
8128 /**
8129 * The android package in which this service resides.
8130 */
8131 protected Pkg mPkg;
8132
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008133 /**
8134 * Total time (ms in battery uptime) the service has been left started.
8135 */
Joe Onoratoabded112016-02-08 16:49:39 -08008136 protected long mStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137
8138 /**
8139 * If service has been started and not yet stopped, this is
8140 * when it was started.
8141 */
Joe Onoratoabded112016-02-08 16:49:39 -08008142 protected long mRunningSince;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008143
8144 /**
8145 * True if we are currently running.
8146 */
Joe Onoratoabded112016-02-08 16:49:39 -08008147 protected boolean mRunning;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008148
8149 /**
8150 * Total number of times startService() has been called.
8151 */
Joe Onoratoabded112016-02-08 16:49:39 -08008152 protected int mStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153
8154 /**
8155 * Total time (ms in battery uptime) the service has been left launched.
8156 */
Joe Onoratoabded112016-02-08 16:49:39 -08008157 protected long mLaunchedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008158
8159 /**
8160 * If service has been launched and not yet exited, this is
8161 * when it was launched (ms in battery uptime).
8162 */
Joe Onoratoabded112016-02-08 16:49:39 -08008163 protected long mLaunchedSince;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008164
8165 /**
8166 * True if we are currently launched.
8167 */
Joe Onoratoabded112016-02-08 16:49:39 -08008168 protected boolean mLaunched;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008169
8170 /**
8171 * Total number times the service has been launched.
8172 */
Joe Onoratoabded112016-02-08 16:49:39 -08008173 protected int mLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008174
8175 /**
8176 * The amount of time spent started loaded from a previous save
8177 * (ms in battery uptime).
8178 */
Joe Onoratoabded112016-02-08 16:49:39 -08008179 protected long mLoadedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008180
8181 /**
8182 * The number of starts loaded from a previous save.
8183 */
Joe Onoratoabded112016-02-08 16:49:39 -08008184 protected int mLoadedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008185
8186 /**
8187 * The number of launches loaded from a previous save.
8188 */
Joe Onoratoabded112016-02-08 16:49:39 -08008189 protected int mLoadedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008190
8191 /**
8192 * The amount of time spent started as of the last run (ms
8193 * in battery uptime).
8194 */
Joe Onoratoabded112016-02-08 16:49:39 -08008195 protected long mLastStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008196
8197 /**
8198 * The number of starts as of the last run.
8199 */
Joe Onoratoabded112016-02-08 16:49:39 -08008200 protected int mLastStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008201
8202 /**
8203 * The number of launches as of the last run.
8204 */
Joe Onoratoabded112016-02-08 16:49:39 -08008205 protected int mLastLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008206
8207 /**
8208 * The amount of time spent started when last unplugged (ms
8209 * in battery uptime).
8210 */
Joe Onoratoabded112016-02-08 16:49:39 -08008211 protected long mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008212
8213 /**
8214 * The number of starts when last unplugged.
8215 */
Joe Onoratoabded112016-02-08 16:49:39 -08008216 protected int mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008217
8218 /**
8219 * The number of launches when last unplugged.
8220 */
Joe Onoratoabded112016-02-08 16:49:39 -08008221 protected int mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008222
Joe Onoratoabded112016-02-08 16:49:39 -08008223 /**
8224 * Construct a Serv. Also adds it to the on-battery time base as a listener.
8225 */
8226 public Serv(BatteryStatsImpl bsi) {
8227 mBsi = bsi;
8228 mBsi.mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008229 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008230
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008231 public void onTimeStarted(long elapsedRealtime, long baseUptime,
8232 long baseRealtime) {
8233 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008234 mUnpluggedStarts = mStarts;
8235 mUnpluggedLaunches = mLaunches;
8236 }
8237
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008238 public void onTimeStopped(long elapsedRealtime, long baseUptime,
8239 long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008240 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008241
Joe Onoratoabded112016-02-08 16:49:39 -08008242 /**
8243 * Remove this Serv as a listener from the time base.
8244 */
8245 public void detach() {
8246 mBsi.mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008247 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008248
Joe Onoratoabded112016-02-08 16:49:39 -08008249 public void readFromParcelLocked(Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008250 mStartTime = in.readLong();
8251 mRunningSince = in.readLong();
8252 mRunning = in.readInt() != 0;
8253 mStarts = in.readInt();
8254 mLaunchedTime = in.readLong();
8255 mLaunchedSince = in.readLong();
8256 mLaunched = in.readInt() != 0;
8257 mLaunches = in.readInt();
8258 mLoadedStartTime = in.readLong();
8259 mLoadedStarts = in.readInt();
8260 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008261 mLastStartTime = 0;
8262 mLastStarts = 0;
8263 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008264 mUnpluggedStartTime = in.readLong();
8265 mUnpluggedStarts = in.readInt();
8266 mUnpluggedLaunches = in.readInt();
8267 }
8268
Joe Onoratoabded112016-02-08 16:49:39 -08008269 public void writeToParcelLocked(Parcel out) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008270 out.writeLong(mStartTime);
8271 out.writeLong(mRunningSince);
8272 out.writeInt(mRunning ? 1 : 0);
8273 out.writeInt(mStarts);
8274 out.writeLong(mLaunchedTime);
8275 out.writeLong(mLaunchedSince);
8276 out.writeInt(mLaunched ? 1 : 0);
8277 out.writeInt(mLaunches);
8278 out.writeLong(mLoadedStartTime);
8279 out.writeInt(mLoadedStarts);
8280 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008281 out.writeLong(mUnpluggedStartTime);
8282 out.writeInt(mUnpluggedStarts);
8283 out.writeInt(mUnpluggedLaunches);
8284 }
8285
Joe Onoratoabded112016-02-08 16:49:39 -08008286 public long getLaunchTimeToNowLocked(long batteryUptime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008287 if (!mLaunched) return mLaunchedTime;
8288 return mLaunchedTime + batteryUptime - mLaunchedSince;
8289 }
8290
Joe Onoratoabded112016-02-08 16:49:39 -08008291 public long getStartTimeToNowLocked(long batteryUptime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008292 if (!mRunning) return mStartTime;
8293 return mStartTime + batteryUptime - mRunningSince;
8294 }
8295
8296 public void startLaunchedLocked() {
8297 if (!mLaunched) {
8298 mLaunches++;
Joe Onoratoabded112016-02-08 16:49:39 -08008299 mLaunchedSince = mBsi.getBatteryUptimeLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008300 mLaunched = true;
8301 }
8302 }
8303
8304 public void stopLaunchedLocked() {
8305 if (mLaunched) {
Joe Onoratoabded112016-02-08 16:49:39 -08008306 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008307 if (time > 0) {
8308 mLaunchedTime += time;
8309 } else {
8310 mLaunches--;
8311 }
8312 mLaunched = false;
8313 }
8314 }
8315
8316 public void startRunningLocked() {
8317 if (!mRunning) {
8318 mStarts++;
Joe Onoratoabded112016-02-08 16:49:39 -08008319 mRunningSince = mBsi.getBatteryUptimeLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008320 mRunning = true;
8321 }
8322 }
8323
8324 public void stopRunningLocked() {
8325 if (mRunning) {
Joe Onoratoabded112016-02-08 16:49:39 -08008326 long time = mBsi.getBatteryUptimeLocked() - mRunningSince;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008327 if (time > 0) {
8328 mStartTime += time;
8329 } else {
8330 mStarts--;
8331 }
8332 mRunning = false;
8333 }
8334 }
8335
8336 public BatteryStatsImpl getBatteryStats() {
Joe Onoratoabded112016-02-08 16:49:39 -08008337 return mBsi;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008338 }
8339
8340 @Override
8341 public int getLaunches(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008342 int val = mLaunches;
8343 if (which == STATS_CURRENT) {
8344 val -= mLoadedLaunches;
8345 } else if (which == STATS_SINCE_UNPLUGGED) {
8346 val -= mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008347 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008348 return val;
8349 }
8350
8351 @Override
8352 public long getStartTime(long now, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008353 long val = getStartTimeToNowLocked(now);
8354 if (which == STATS_CURRENT) {
8355 val -= mLoadedStartTime;
8356 } else if (which == STATS_SINCE_UNPLUGGED) {
8357 val -= mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008358 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008359 return val;
8360 }
8361
8362 @Override
8363 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008364 int val = mStarts;
8365 if (which == STATS_CURRENT) {
8366 val -= mLoadedStarts;
8367 } else if (which == STATS_SINCE_UNPLUGGED) {
8368 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008369 }
8370
8371 return val;
8372 }
8373 }
8374
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008375 final Serv newServiceStatsLocked() {
Joe Onoratoabded112016-02-08 16:49:39 -08008376 return new Serv(mBsi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008377 }
8378 }
8379
8380 /**
8381 * Retrieve the statistics object for a particular process, creating
8382 * if needed.
8383 */
8384 public Proc getProcessStatsLocked(String name) {
8385 Proc ps = mProcessStats.get(name);
8386 if (ps == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08008387 ps = new Proc(mBsi, name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008388 mProcessStats.put(name, ps);
8389 }
8390
8391 return ps;
8392 }
8393
Dianne Hackborna8d10942015-11-19 17:55:19 -08008394 public void updateUidProcessStateLocked(int procState) {
8395 int uidRunningState;
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008396 // Make special note of Foreground Services
8397 final boolean userAwareService =
8398 (procState == ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
Dianne Hackborna8d10942015-11-19 17:55:19 -08008399 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
8400 uidRunningState = ActivityManager.PROCESS_STATE_NONEXISTENT;
8401 } else if (procState == ActivityManager.PROCESS_STATE_TOP) {
8402 uidRunningState = PROCESS_STATE_TOP;
8403 } else if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
8404 // Persistent and other foreground states go here.
8405 uidRunningState = PROCESS_STATE_FOREGROUND_SERVICE;
8406 } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
8407 uidRunningState = PROCESS_STATE_TOP_SLEEPING;
8408 } else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
8409 // Persistent and other foreground states go here.
8410 uidRunningState = PROCESS_STATE_FOREGROUND;
8411 } else if (procState <= ActivityManager.PROCESS_STATE_RECEIVER) {
8412 uidRunningState = PROCESS_STATE_BACKGROUND;
Dianne Hackborn61659e52014-07-09 16:13:01 -07008413 } else {
Dianne Hackborna8d10942015-11-19 17:55:19 -08008414 uidRunningState = PROCESS_STATE_CACHED;
Dianne Hackborn61659e52014-07-09 16:13:01 -07008415 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07008416
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008417 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) {
8418 return;
8419 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08008420
Bookatz867c0d72017-03-07 18:23:42 -08008421 final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime();
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008422 if (mProcessState != uidRunningState) {
8423 final long uptimeMs = mBsi.mClocks.uptimeMillis();
Dianne Hackborna8d10942015-11-19 17:55:19 -08008424
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008425 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
8426 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn61659e52014-07-09 16:13:01 -07008427 }
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008428 mProcessState = uidRunningState;
8429 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
8430 if (mProcessStateTimer[uidRunningState] == null) {
8431 makeProcessState(uidRunningState, null);
8432 }
8433 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs);
8434 }
8435
8436 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
8437 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
Dianne Hackborn61659e52014-07-09 16:13:01 -07008438 }
Bookatz867c0d72017-03-07 18:23:42 -08008439
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008440 if (userAwareService != mInForegroundService) {
8441 if (userAwareService) {
8442 noteForegroundServiceResumedLocked(elapsedRealtimeMs);
8443 } else {
8444 noteForegroundServicePausedLocked(elapsedRealtimeMs);
8445 }
8446 mInForegroundService = userAwareService;
8447 }
Bookatz867c0d72017-03-07 18:23:42 -08008448 }
8449
Bookatzc8c44962017-05-11 12:12:54 -07008450 /** Whether to consider Uid to be in the background for background timebase purposes. */
8451 public boolean isInBackground() {
Bookatz867c0d72017-03-07 18:23:42 -08008452 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is
8453 // also considered to be 'background' for our purposes, because it's not foreground.
Bookatzc8c44962017-05-11 12:12:54 -07008454 return mProcessState >= PROCESS_STATE_BACKGROUND;
8455 }
8456
8457 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) {
8458 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground();
8459 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
8460 }
8461
8462 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) {
8463 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground();
8464 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
Dianne Hackborn61659e52014-07-09 16:13:01 -07008465 }
8466
Dianne Hackbornb5e31652010-09-07 12:13:55 -07008467 public SparseArray<? extends Pid> getPidStats() {
8468 return mPids;
8469 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008470
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008471 public Pid getPidStatsLocked(int pid) {
8472 Pid p = mPids.get(pid);
8473 if (p == null) {
8474 p = new Pid();
8475 mPids.put(pid, p);
8476 }
8477 return p;
8478 }
8479
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008480 /**
8481 * Retrieve the statistics object for a particular service, creating
8482 * if needed.
8483 */
8484 public Pkg getPackageStatsLocked(String name) {
8485 Pkg ps = mPackageStats.get(name);
8486 if (ps == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08008487 ps = new Pkg(mBsi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008488 mPackageStats.put(name, ps);
8489 }
8490
8491 return ps;
8492 }
8493
8494 /**
8495 * Retrieve the statistics object for a particular service, creating
8496 * if needed.
8497 */
8498 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
8499 Pkg ps = getPackageStatsLocked(pkg);
8500 Pkg.Serv ss = ps.mServiceStats.get(serv);
8501 if (ss == null) {
8502 ss = ps.newServiceStatsLocked();
8503 ps.mServiceStats.put(serv, ss);
8504 }
8505
8506 return ss;
8507 }
8508
Dianne Hackbornd953c532014-08-16 18:17:38 -07008509 public void readSyncSummaryFromParcelLocked(String name, Parcel in) {
Bookatz2bffb5b2017-04-13 11:59:33 -07008510 DualTimer timer = mSyncStats.instantiateObject();
Dianne Hackbornd953c532014-08-16 18:17:38 -07008511 timer.readSummaryFromParcelLocked(in);
8512 mSyncStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008513 }
8514
Dianne Hackbornd953c532014-08-16 18:17:38 -07008515 public void readJobSummaryFromParcelLocked(String name, Parcel in) {
Bookatzaa4594a2017-03-24 12:39:56 -07008516 DualTimer timer = mJobStats.instantiateObject();
Dianne Hackbornd953c532014-08-16 18:17:38 -07008517 timer.readSummaryFromParcelLocked(in);
8518 mJobStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008519 }
8520
Dianne Hackbornd953c532014-08-16 18:17:38 -07008521 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) {
Joe Onoratoabded112016-02-08 16:49:39 -08008522 Wakelock wl = new Wakelock(mBsi, this);
Dianne Hackbornd953c532014-08-16 18:17:38 -07008523 mWakelockStats.add(wlName, wl);
8524 if (in.readInt() != 0) {
Bookatz5b5ec322017-05-26 09:40:38 -07008525 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008526 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07008527 if (in.readInt() != 0) {
Bookatz5b5ec322017-05-26 09:40:38 -07008528 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
Dianne Hackbornd953c532014-08-16 18:17:38 -07008529 }
8530 if (in.readInt() != 0) {
Bookatz5b5ec322017-05-26 09:40:38 -07008531 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008532 }
Adam Lesinski9425fe22015-06-19 12:02:13 -07008533 if (in.readInt() != 0) {
Bookatz5b5ec322017-05-26 09:40:38 -07008534 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
Adam Lesinski9425fe22015-06-19 12:02:13 -07008535 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008536 }
8537
Bookatz867c0d72017-03-07 18:23:42 -08008538 public DualTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008539 Sensor se = mSensorStats.get(sensor);
8540 if (se == null) {
8541 if (!create) {
8542 return null;
8543 }
Joe Onoratoabded112016-02-08 16:49:39 -08008544 se = new Sensor(mBsi, this, sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008545 mSensorStats.put(sensor, se);
8546 }
Bookatz867c0d72017-03-07 18:23:42 -08008547 DualTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008548 if (t != null) {
8549 return t;
8550 }
Joe Onoratoabded112016-02-08 16:49:39 -08008551 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008552 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07008553 timers = new ArrayList<StopwatchTimer>();
Joe Onoratoabded112016-02-08 16:49:39 -08008554 mBsi.mSensorTimers.put(sensor, timers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008555 }
Bookatz867c0d72017-03-07 18:23:42 -08008556 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers,
8557 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008558 se.mTimer = t;
8559 return t;
8560 }
8561
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008562 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) {
Bookatz2bffb5b2017-04-13 11:59:33 -07008563 DualTimer t = mSyncStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008564 if (t != null) {
8565 t.startRunningLocked(elapsedRealtimeMs);
8566 }
8567 }
8568
8569 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) {
Bookatz2bffb5b2017-04-13 11:59:33 -07008570 DualTimer t = mSyncStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008571 if (t != null) {
8572 t.stopRunningLocked(elapsedRealtimeMs);
8573 }
8574 }
8575
8576 public void noteStartJobLocked(String name, long elapsedRealtimeMs) {
Bookatzaa4594a2017-03-24 12:39:56 -07008577 DualTimer t = mJobStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008578 if (t != null) {
8579 t.startRunningLocked(elapsedRealtimeMs);
8580 }
8581 }
8582
Dianne Hackborn94326cb2017-06-28 16:17:20 -07008583 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) {
Bookatzaa4594a2017-03-24 12:39:56 -07008584 DualTimer t = mJobStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008585 if (t != null) {
8586 t.stopRunningLocked(elapsedRealtimeMs);
8587 }
Dianne Hackborn94326cb2017-06-28 16:17:20 -07008588 if (mBsi.mOnBatteryTimeBase.isRunning()) {
8589 SparseIntArray types = mJobCompletions.get(name);
8590 if (types == null) {
8591 types = new SparseIntArray();
8592 mJobCompletions.put(name, types);
8593 }
8594 int last = types.get(stopReason, 0);
8595 types.put(stopReason, last + 1);
8596 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008597 }
8598
Bookatz5b5ec322017-05-26 09:40:38 -07008599 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) {
8600 if (wl == null) {
8601 return null;
8602 }
8603 switch (type) {
8604 case WAKE_TYPE_PARTIAL: {
8605 DualTimer t = wl.mTimerPartial;
8606 if (t == null) {
8607 t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL,
8608 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase,
8609 mOnBatteryScreenOffBackgroundTimeBase);
8610 wl.mTimerPartial = t;
8611 }
8612 return t;
8613 }
8614 case WAKE_TYPE_FULL: {
8615 StopwatchTimer t = wl.mTimerFull;
8616 if (t == null) {
8617 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL,
8618 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase);
8619 wl.mTimerFull = t;
8620 }
8621 return t;
8622 }
8623 case WAKE_TYPE_WINDOW: {
8624 StopwatchTimer t = wl.mTimerWindow;
8625 if (t == null) {
8626 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW,
8627 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase);
8628 wl.mTimerWindow = t;
8629 }
8630 return t;
8631 }
8632 case WAKE_TYPE_DRAW: {
8633 StopwatchTimer t = wl.mTimerDraw;
8634 if (t == null) {
8635 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW,
8636 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase);
8637 wl.mTimerDraw = t;
8638 }
8639 return t;
8640 }
8641 default:
8642 throw new IllegalArgumentException("type=" + type);
8643 }
8644 }
8645
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008646 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07008647 Wakelock wl = mWakelockStats.startObject(name);
8648 if (wl != null) {
Bookatz5b5ec322017-05-26 09:40:38 -07008649 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008650 }
Bookatzc8c44962017-05-11 12:12:54 -07008651 if (type == WAKE_TYPE_PARTIAL) {
8652 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs);
8653 if (pid >= 0) {
8654 Pid p = getPidStatsLocked(pid);
8655 if (p.mWakeNesting++ == 0) {
8656 p.mWakeStartMs = elapsedRealtimeMs;
8657 }
Dianne Hackbornb8071d792010-09-09 16:45:15 -07008658 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008659 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008660 }
8661
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008662 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07008663 Wakelock wl = mWakelockStats.stopObject(name);
8664 if (wl != null) {
Bookatz5b5ec322017-05-26 09:40:38 -07008665 getWakelockTimerLocked(wl, type).stopRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008666 }
Bookatzc8c44962017-05-11 12:12:54 -07008667 if (type == WAKE_TYPE_PARTIAL) {
8668 if (mAggregatedPartialWakelockTimer != null) {
8669 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs);
8670 }
8671 if (pid >= 0) {
8672 Pid p = mPids.get(pid);
8673 if (p != null && p.mWakeNesting > 0) {
8674 if (p.mWakeNesting-- == 1) {
8675 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
8676 p.mWakeStartMs = 0;
8677 }
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008678 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008679 }
8680 }
8681 }
8682
Dianne Hackborn287952c2010-09-22 22:34:31 -07008683 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
8684 Proc p = getProcessStatsLocked(proc);
8685 if (p != null) {
8686 p.addExcessiveCpu(overTime, usedTime);
8687 }
8688 }
8689
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008690 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
Bookatz867c0d72017-03-07 18:23:42 -08008691 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true);
Amith Yamasani154d1242017-02-16 10:01:48 -08008692 t.startRunningLocked(elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008693 }
8694
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008695 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008696 // Don't create a timer if one doesn't already exist
Bookatz867c0d72017-03-07 18:23:42 -08008697 DualTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008698 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008699 t.stopRunningLocked(elapsedRealtimeMs);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008700 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008701 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008702
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008703 public void noteStartGps(long elapsedRealtimeMs) {
Bookatz867c0d72017-03-07 18:23:42 -08008704 noteStartSensor(Sensor.GPS, elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008705 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008706
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008707 public void noteStopGps(long elapsedRealtimeMs) {
Bookatz867c0d72017-03-07 18:23:42 -08008708 noteStopSensor(Sensor.GPS, elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008709 }
8710
8711 public BatteryStatsImpl getBatteryStats() {
Joe Onoratoabded112016-02-08 16:49:39 -08008712 return mBsi;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008713 }
8714 }
8715
Sudheer Shanka9b735c52017-05-09 18:26:18 -07008716 public long[] getCpuFreqs() {
8717 return mCpuFreqs;
8718 }
8719
Suprabh Shuklae6e723d2017-06-14 16:14:43 -07008720 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb,
8721 UserInfoProvider userInfoProvider) {
8722 this(new SystemClocks(), systemDir, handler, cb, userInfoProvider);
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07008723 }
8724
Suprabh Shuklae6e723d2017-06-14 16:14:43 -07008725 private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler,
8726 PlatformIdleStateCallback cb,
8727 UserInfoProvider userInfoProvider) {
Joe Onoratoabded112016-02-08 16:49:39 -08008728 init(clocks);
8729
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008730 if (systemDir != null) {
8731 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"),
8732 new File(systemDir, "batterystats.bin.tmp"));
8733 } else {
8734 mFile = null;
8735 }
8736 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008737 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
Jeff Brown6f357d32014-01-15 20:40:55 -08008738 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008739 mStartCount++;
Joe Onoratoabded112016-02-08 16:49:39 -08008740 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07008741 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08008742 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008743 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07008744 }
Joe Onoratoabded112016-02-08 16:49:39 -08008745 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase);
8746 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null,
8747 mOnBatteryTimeBase);
8748 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null,
8749 mOnBatteryTimeBase);
8750 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase);
8751 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase);
8752 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase);
8753 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase);
8754 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
8755 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null,
8756 mOnBatteryTimeBase);
8757 }
8758 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null,
8759 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07008760 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08008761 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008762 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07008763 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008764 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008765 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
8766 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07008767 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08008768 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS);
8769 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
8770 NUM_BT_TX_LEVELS);
8771 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
8772 ModemActivityInfo.TX_POWER_LEVELS);
Joe Onoratoabded112016-02-08 16:49:39 -08008773 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase);
8774 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null,
8775 mOnBatteryTimeBase);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07008776 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008777 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
8778 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
Joe Onoratoabded112016-02-08 16:49:39 -08008779 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase);
8780 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08008781 for (int i=0; i<NUM_WIFI_STATES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08008782 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null,
Dianne Hackborn3251b902014-06-20 14:40:53 -07008783 mOnBatteryTimeBase);
8784 }
Joe Onoratoabded112016-02-08 16:49:39 -08008785 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
8786 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null,
8787 mOnBatteryTimeBase);
8788 }
8789 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
8790 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null,
8791 mOnBatteryTimeBase);
8792 }
8793 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase);
8794 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase);
8795 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase);
8796 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase);
8797 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase);
Adam Lesinski3ee3f632016-06-08 13:55:55 -07008798 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase);
8799 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008800 mOnBattery = mOnBatteryInternal = false;
Joe Onoratoabded112016-02-08 16:49:39 -08008801 long uptime = mClocks.uptimeMillis() * 1000;
8802 long realtime = mClocks.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008803 initTimes(uptime, realtime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07008804 mStartPlatformVersion = mEndPlatformVersion = Build.ID;
Evan Millar633a1742009-04-02 16:36:33 -07008805 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008806 mDischargeUnplugLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008807 mDischargePlugLevel = -1;
Evan Millar633a1742009-04-02 16:36:33 -07008808 mDischargeCurrentLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07008809 mCurrentBatteryLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08008810 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008811 clearHistoryLocked();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008812 updateDailyDeadlineLocked();
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07008813 mPlatformIdleStateCallback = cb;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -07008814 mUserInfoProvider = userInfoProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008815 }
8816
8817 public BatteryStatsImpl(Parcel p) {
Joe Onoratoabded112016-02-08 16:49:39 -08008818 this(new SystemClocks(), p);
8819 }
8820
8821 public BatteryStatsImpl(Clocks clocks, Parcel p) {
8822 init(clocks);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07008823 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07008824 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008825 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07008826 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008827 mExternalSync = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07008828 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008829 readFromParcel(p);
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07008830 mPlatformIdleStateCallback = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008831 }
8832
Adam Lesinski14ae39a2017-05-26 11:50:40 -07008833 public void setPowerProfileLocked(PowerProfile profile) {
8834 mPowerProfile = profile;
Adam Lesinski6832f392015-09-05 18:05:40 -07008835
Adam Lesinski14ae39a2017-05-26 11:50:40 -07008836 // We need to initialize the KernelCpuSpeedReaders to read from
8837 // the first cpu of each core. Once we have the PowerProfile, we have access to this
8838 // information.
8839 final int numClusters = mPowerProfile.getNumCpuClusters();
8840 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
8841 int firstCpuOfCluster = 0;
8842 for (int i = 0; i < numClusters; i++) {
8843 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i);
8844 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
8845 numSpeedSteps);
8846 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i);
8847 }
Adam Lesinskif9b20a92016-06-17 17:30:01 -07008848
Adam Lesinski14ae39a2017-05-26 11:50:40 -07008849 if (mEstimatedBatteryCapacity == -1) {
8850 // Initialize the estimated battery capacity to a known preset one.
8851 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity();
Adam Lesinskie08af192015-03-25 16:42:59 -07008852 }
8853 }
8854
Dianne Hackborn0d903a82010-09-07 23:51:03 -07008855 public void setCallback(BatteryCallback cb) {
8856 mCallback = cb;
8857 }
8858
Adam Lesinski14ae39a2017-05-26 11:50:40 -07008859 public void setRadioScanningTimeoutLocked(long timeout) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07008860 if (mPhoneSignalScanningTimer != null) {
8861 mPhoneSignalScanningTimer.setTimeout(timeout);
8862 }
8863 }
8864
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07008865 public void setExternalStatsSyncLocked(ExternalStatsSync sync) {
8866 mExternalSync = sync;
8867 }
8868
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008869 public void updateDailyDeadlineLocked() {
8870 // Get the current time.
8871 long currentTime = mDailyStartTime = System.currentTimeMillis();
8872 Calendar calDeadline = Calendar.getInstance();
8873 calDeadline.setTimeInMillis(currentTime);
8874
8875 // Move time up to the next day, ranging from 1am to 3pm.
8876 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1);
8877 calDeadline.set(Calendar.MILLISECOND, 0);
8878 calDeadline.set(Calendar.SECOND, 0);
8879 calDeadline.set(Calendar.MINUTE, 0);
8880 calDeadline.set(Calendar.HOUR_OF_DAY, 1);
8881 mNextMinDailyDeadline = calDeadline.getTimeInMillis();
8882 calDeadline.set(Calendar.HOUR_OF_DAY, 3);
8883 mNextMaxDailyDeadline = calDeadline.getTimeInMillis();
8884 }
8885
8886 public void recordDailyStatsIfNeededLocked(boolean settled) {
8887 long currentTime = System.currentTimeMillis();
8888 if (currentTime >= mNextMaxDailyDeadline) {
8889 recordDailyStatsLocked();
8890 } else if (settled && currentTime >= mNextMinDailyDeadline) {
8891 recordDailyStatsLocked();
8892 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) {
8893 recordDailyStatsLocked();
8894 }
8895 }
8896
8897 public void recordDailyStatsLocked() {
8898 DailyItem item = new DailyItem();
8899 item.mStartTime = mDailyStartTime;
8900 item.mEndTime = System.currentTimeMillis();
8901 boolean hasData = false;
8902 if (mDailyDischargeStepTracker.mNumStepDurations > 0) {
8903 hasData = true;
8904 item.mDischargeSteps = new LevelStepTracker(
8905 mDailyDischargeStepTracker.mNumStepDurations,
8906 mDailyDischargeStepTracker.mStepDurations);
8907 }
8908 if (mDailyChargeStepTracker.mNumStepDurations > 0) {
8909 hasData = true;
8910 item.mChargeSteps = new LevelStepTracker(
8911 mDailyChargeStepTracker.mNumStepDurations,
8912 mDailyChargeStepTracker.mStepDurations);
8913 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008914 if (mDailyPackageChanges != null) {
8915 hasData = true;
8916 item.mPackageChanges = mDailyPackageChanges;
8917 mDailyPackageChanges = null;
8918 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008919 mDailyDischargeStepTracker.init();
8920 mDailyChargeStepTracker.init();
8921 updateDailyDeadlineLocked();
8922
8923 if (hasData) {
8924 mDailyItems.add(item);
8925 while (mDailyItems.size() > MAX_DAILY_ITEMS) {
8926 mDailyItems.remove(0);
8927 }
8928 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
8929 try {
8930 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01008931 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008932 writeDailyItemsLocked(out);
8933 BackgroundThread.getHandler().post(new Runnable() {
8934 @Override
8935 public void run() {
8936 synchronized (mCheckinFile) {
8937 FileOutputStream stream = null;
8938 try {
8939 stream = mDailyFile.startWrite();
8940 memStream.writeTo(stream);
8941 stream.flush();
8942 FileUtils.sync(stream);
8943 stream.close();
8944 mDailyFile.finishWrite(stream);
8945 } catch (IOException e) {
8946 Slog.w("BatteryStats",
8947 "Error writing battery daily items", e);
8948 mDailyFile.failWrite(stream);
8949 }
8950 }
8951 }
8952 });
8953 } catch (IOException e) {
8954 }
8955 }
8956 }
8957
8958 private void writeDailyItemsLocked(XmlSerializer out) throws IOException {
8959 StringBuilder sb = new StringBuilder(64);
8960 out.startDocument(null, true);
8961 out.startTag(null, "daily-items");
8962 for (int i=0; i<mDailyItems.size(); i++) {
8963 final DailyItem dit = mDailyItems.get(i);
8964 out.startTag(null, "item");
8965 out.attribute(null, "start", Long.toString(dit.mStartTime));
8966 out.attribute(null, "end", Long.toString(dit.mEndTime));
8967 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb);
8968 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07008969 if (dit.mPackageChanges != null) {
8970 for (int j=0; j<dit.mPackageChanges.size(); j++) {
8971 PackageChange pc = dit.mPackageChanges.get(j);
8972 if (pc.mUpdate) {
8973 out.startTag(null, "upd");
8974 out.attribute(null, "pkg", pc.mPackageName);
8975 out.attribute(null, "ver", Integer.toString(pc.mVersionCode));
8976 out.endTag(null, "upd");
8977 } else {
8978 out.startTag(null, "rem");
8979 out.attribute(null, "pkg", pc.mPackageName);
8980 out.endTag(null, "rem");
8981 }
8982 }
8983 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08008984 out.endTag(null, "item");
8985 }
8986 out.endTag(null, "daily-items");
8987 out.endDocument();
8988 }
8989
8990 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps,
8991 StringBuilder tmpBuilder) throws IOException {
8992 if (steps != null) {
8993 out.startTag(null, tag);
8994 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations));
8995 for (int i=0; i<steps.mNumStepDurations; i++) {
8996 out.startTag(null, "s");
8997 tmpBuilder.setLength(0);
8998 steps.encodeEntryAt(i, tmpBuilder);
8999 out.attribute(null, "v", tmpBuilder.toString());
9000 out.endTag(null, "s");
9001 }
9002 out.endTag(null, tag);
9003 }
9004 }
9005
9006 public void readDailyStatsLocked() {
9007 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile());
9008 mDailyItems.clear();
9009 FileInputStream stream;
9010 try {
9011 stream = mDailyFile.openRead();
9012 } catch (FileNotFoundException e) {
9013 return;
9014 }
9015 try {
9016 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01009017 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009018 readDailyItemsLocked(parser);
9019 } catch (XmlPullParserException e) {
9020 } finally {
9021 try {
9022 stream.close();
9023 } catch (IOException e) {
9024 }
9025 }
9026 }
9027
9028 private void readDailyItemsLocked(XmlPullParser parser) {
9029 try {
9030 int type;
9031 while ((type = parser.next()) != XmlPullParser.START_TAG
9032 && type != XmlPullParser.END_DOCUMENT) {
9033 ;
9034 }
9035
9036 if (type != XmlPullParser.START_TAG) {
9037 throw new IllegalStateException("no start tag found");
9038 }
9039
9040 int outerDepth = parser.getDepth();
9041 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
9042 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
9043 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
9044 continue;
9045 }
9046
9047 String tagName = parser.getName();
9048 if (tagName.equals("item")) {
9049 readDailyItemTagLocked(parser);
9050 } else {
9051 Slog.w(TAG, "Unknown element under <daily-items>: "
9052 + parser.getName());
9053 XmlUtils.skipCurrentTag(parser);
9054 }
9055 }
9056
9057 } catch (IllegalStateException e) {
9058 Slog.w(TAG, "Failed parsing daily " + e);
9059 } catch (NullPointerException e) {
9060 Slog.w(TAG, "Failed parsing daily " + e);
9061 } catch (NumberFormatException e) {
9062 Slog.w(TAG, "Failed parsing daily " + e);
9063 } catch (XmlPullParserException e) {
9064 Slog.w(TAG, "Failed parsing daily " + e);
9065 } catch (IOException e) {
9066 Slog.w(TAG, "Failed parsing daily " + e);
9067 } catch (IndexOutOfBoundsException e) {
9068 Slog.w(TAG, "Failed parsing daily " + e);
9069 }
9070 }
9071
9072 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException,
9073 XmlPullParserException, IOException {
9074 DailyItem dit = new DailyItem();
9075 String attr = parser.getAttributeValue(null, "start");
9076 if (attr != null) {
9077 dit.mStartTime = Long.parseLong(attr);
9078 }
9079 attr = parser.getAttributeValue(null, "end");
9080 if (attr != null) {
9081 dit.mEndTime = Long.parseLong(attr);
9082 }
9083 int outerDepth = parser.getDepth();
9084 int type;
9085 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
9086 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
9087 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
9088 continue;
9089 }
9090
9091 String tagName = parser.getName();
9092 if (tagName.equals("dis")) {
9093 readDailyItemTagDetailsLocked(parser, dit, false, "dis");
9094 } else if (tagName.equals("chg")) {
9095 readDailyItemTagDetailsLocked(parser, dit, true, "chg");
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009096 } else if (tagName.equals("upd")) {
9097 if (dit.mPackageChanges == null) {
9098 dit.mPackageChanges = new ArrayList<>();
9099 }
9100 PackageChange pc = new PackageChange();
9101 pc.mUpdate = true;
9102 pc.mPackageName = parser.getAttributeValue(null, "pkg");
9103 String verStr = parser.getAttributeValue(null, "ver");
9104 pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0;
9105 dit.mPackageChanges.add(pc);
9106 XmlUtils.skipCurrentTag(parser);
9107 } else if (tagName.equals("rem")) {
9108 if (dit.mPackageChanges == null) {
9109 dit.mPackageChanges = new ArrayList<>();
9110 }
9111 PackageChange pc = new PackageChange();
9112 pc.mUpdate = false;
9113 pc.mPackageName = parser.getAttributeValue(null, "pkg");
9114 dit.mPackageChanges.add(pc);
9115 XmlUtils.skipCurrentTag(parser);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009116 } else {
9117 Slog.w(TAG, "Unknown element under <item>: "
9118 + parser.getName());
9119 XmlUtils.skipCurrentTag(parser);
9120 }
9121 }
9122 mDailyItems.add(dit);
9123 }
9124
9125 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge,
9126 String tag)
9127 throws NumberFormatException, XmlPullParserException, IOException {
9128 final String numAttr = parser.getAttributeValue(null, "n");
9129 if (numAttr == null) {
9130 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription());
9131 XmlUtils.skipCurrentTag(parser);
9132 return;
9133 }
9134 final int num = Integer.parseInt(numAttr);
9135 LevelStepTracker steps = new LevelStepTracker(num);
9136 if (isCharge) {
9137 dit.mChargeSteps = steps;
9138 } else {
9139 dit.mDischargeSteps = steps;
9140 }
9141 int i = 0;
9142 int outerDepth = parser.getDepth();
9143 int type;
9144 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
9145 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
9146 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
9147 continue;
9148 }
9149
9150 String tagName = parser.getName();
9151 if ("s".equals(tagName)) {
9152 if (i < num) {
9153 String valueAttr = parser.getAttributeValue(null, "v");
9154 if (valueAttr != null) {
9155 steps.decodeEntryAt(i, valueAttr);
9156 i++;
9157 }
9158 }
9159 } else {
9160 Slog.w(TAG, "Unknown element under <" + tag + ">: "
9161 + parser.getName());
9162 XmlUtils.skipCurrentTag(parser);
9163 }
9164 }
9165 steps.mNumStepDurations = i;
9166 }
9167
9168 @Override
9169 public DailyItem getDailyItemLocked(int daysAgo) {
9170 int index = mDailyItems.size()-1-daysAgo;
9171 return index >= 0 ? mDailyItems.get(index) : null;
9172 }
9173
9174 @Override
9175 public long getCurrentDailyStartTime() {
9176 return mDailyStartTime;
9177 }
9178
9179 @Override
9180 public long getNextMinDailyDeadline() {
9181 return mNextMinDailyDeadline;
9182 }
9183
9184 @Override
9185 public long getNextMaxDailyDeadline() {
9186 return mNextMaxDailyDeadline;
9187 }
9188
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009189 @Override
9190 public boolean startIteratingOldHistoryLocked() {
9191 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
9192 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009193 if ((mHistoryIterator = mHistory) == null) {
9194 return false;
9195 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009196 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07009197 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009198 mReadOverflow = false;
9199 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009200 return true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009201 }
9202
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009203 @Override
9204 public boolean getNextOldHistoryLocked(HistoryItem out) {
9205 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
9206 if (!end) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009207 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07009208 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009209 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009210 HistoryItem cur = mHistoryIterator;
9211 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009212 if (!mReadOverflow && !end) {
9213 Slog.w(TAG, "Old history ends before new history!");
9214 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009215 return false;
9216 }
9217 out.setTo(cur);
9218 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009219 if (!mReadOverflow) {
9220 if (end) {
9221 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07009222 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn8c841092013-06-24 13:46:13 -07009223 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009224 pw.println("Histories differ!");
9225 pw.println("Old history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07009226 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009227 pw.println("New history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07009228 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false,
9229 true);
Dianne Hackborn8c841092013-06-24 13:46:13 -07009230 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009231 }
9232 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009233 return true;
9234 }
9235
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009236 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009237 public void finishIteratingOldHistoryLocked() {
9238 mIteratingHistory = false;
9239 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009240 mHistoryIterator = null;
9241 }
9242
9243 public int getHistoryTotalSize() {
9244 return MAX_HISTORY_BUFFER;
9245 }
9246
9247 public int getHistoryUsedSize() {
9248 return mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009249 }
9250
9251 @Override
9252 public boolean startIteratingHistoryLocked() {
9253 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
9254 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009255 if (mHistoryBuffer.dataSize() <= 0) {
9256 return false;
9257 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009258 mHistoryBuffer.setDataPosition(0);
9259 mReadOverflow = false;
9260 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009261 mReadHistoryStrings = new String[mHistoryTagPool.size()];
9262 mReadHistoryUids = new int[mHistoryTagPool.size()];
9263 mReadHistoryChars = 0;
9264 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
9265 final HistoryTag tag = ent.getKey();
9266 final int idx = ent.getValue();
9267 mReadHistoryStrings[idx] = tag.string;
9268 mReadHistoryUids[idx] = tag.uid;
9269 mReadHistoryChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08009270 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009271 return true;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009272 }
9273
9274 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08009275 public int getHistoryStringPoolSize() {
9276 return mReadHistoryStrings.length;
9277 }
9278
9279 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009280 public int getHistoryStringPoolBytes() {
9281 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
9282 // Each string character is 2 bytes.
9283 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
9284 }
9285
9286 @Override
9287 public String getHistoryTagPoolString(int index) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08009288 return mReadHistoryStrings[index];
9289 }
9290
9291 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009292 public int getHistoryTagPoolUid(int index) {
9293 return mReadHistoryUids[index];
9294 }
9295
9296 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009297 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07009298 final int pos = mHistoryBuffer.dataPosition();
9299 if (pos == 0) {
9300 out.clear();
9301 }
9302 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009303 if (end) {
9304 return false;
9305 }
9306
Dianne Hackborn99009ea2014-04-18 16:23:42 -07009307 final long lastRealtime = out.time;
9308 final long lastWalltime = out.currentTime;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009309 readHistoryDelta(mHistoryBuffer, out);
Dianne Hackborn37de0982014-05-09 09:32:18 -07009310 if (out.cmd != HistoryItem.CMD_CURRENT_TIME
9311 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
Dianne Hackborn99009ea2014-04-18 16:23:42 -07009312 out.currentTime = lastWalltime + (out.time - lastRealtime);
9313 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009314 return true;
9315 }
9316
9317 @Override
9318 public void finishIteratingHistoryLocked() {
9319 mIteratingHistory = false;
9320 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn099bc622014-01-22 13:39:16 -08009321 mReadHistoryStrings = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009322 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009323
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009324 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07009325 public long getHistoryBaseTime() {
9326 return mHistoryBaseTime;
9327 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009328
Dianne Hackbornb5e31652010-09-07 12:13:55 -07009329 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009330 public int getStartCount() {
9331 return mStartCount;
9332 }
9333
9334 public boolean isOnBattery() {
9335 return mOnBattery;
9336 }
9337
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07009338 public boolean isCharging() {
9339 return mCharging;
9340 }
9341
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07009342 public boolean isScreenOn() {
Jeff Browne95c3cd2014-05-02 16:59:26 -07009343 return mScreenState == Display.STATE_ON;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07009344 }
9345
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009346 void initTimes(long uptime, long realtime) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009347 mStartClockTime = System.currentTimeMillis();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009348 mOnBatteryTimeBase.init(uptime, realtime);
9349 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
Dianne Hackborn4590e522014-03-24 13:36:46 -07009350 mRealtime = 0;
9351 mUptime = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009352 mRealtimeStart = realtime;
Dianne Hackborn4590e522014-03-24 13:36:46 -07009353 mUptimeStart = uptime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009354 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009355
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009356 void initDischarge() {
9357 mLowDischargeAmountSinceCharge = 0;
9358 mHighDischargeAmountSinceCharge = 0;
9359 mDischargeAmountScreenOn = 0;
9360 mDischargeAmountScreenOnSinceCharge = 0;
9361 mDischargeAmountScreenOff = 0;
9362 mDischargeAmountScreenOffSinceCharge = 0;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009363 mDischargeStepTracker.init();
9364 mChargeStepTracker.init();
Adam Lesinski3ee3f632016-06-08 13:55:55 -07009365 mDischargeScreenOffCounter.reset(false);
9366 mDischargeCounter.reset(false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009367 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009368
9369 public void resetAllStatsCmdLocked() {
9370 resetAllStatsLocked();
Joe Onoratoabded112016-02-08 16:49:39 -08009371 final long mSecUptime = mClocks.uptimeMillis();
Dianne Hackborn40c87252014-03-19 16:55:40 -07009372 long uptime = mSecUptime * 1000;
Joe Onoratoabded112016-02-08 16:49:39 -08009373 long mSecRealtime = mClocks.elapsedRealtime();
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009374 long realtime = mSecRealtime * 1000;
9375 mDischargeStartLevel = mHistoryCur.batteryLevel;
9376 pullPendingStateUpdatesLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07009377 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009378 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
9379 = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009380 mOnBatteryTimeBase.reset(uptime, realtime);
9381 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
9382 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07009383 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009384 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
9385 mDischargeScreenOffUnplugLevel = 0;
9386 } else {
9387 mDischargeScreenOnUnplugLevel = 0;
9388 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
9389 }
9390 mDischargeAmountScreenOn = 0;
9391 mDischargeAmountScreenOff = 0;
9392 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07009393 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009394 }
9395
9396 private void resetAllStatsLocked() {
Adam Lesinski8ce36942016-05-26 16:05:35 -07009397 final long uptimeMillis = mClocks.uptimeMillis();
9398 final long elapsedRealtimeMillis = mClocks.elapsedRealtime();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009399 mStartCount = 0;
Adam Lesinski8ce36942016-05-26 16:05:35 -07009400 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009401 mScreenOnTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009402 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009403 mScreenBrightnessTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009404 }
Adam Lesinski1a76a622016-06-22 10:28:47 -07009405
9406 if (mPowerProfile != null) {
9407 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity();
9408 } else {
9409 mEstimatedBatteryCapacity = -1;
9410 }
Jocelyn Dangc627d102017-04-14 13:15:14 -07009411 mMinLearnedBatteryCapacity = -1;
9412 mMaxLearnedBatteryCapacity = -1;
Jeff Browne95c3cd2014-05-02 16:59:26 -07009413 mInteractiveTimer.reset(false);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009414 mPowerSaveModeEnabledTimer.reset(false);
Adam Lesinski8ce36942016-05-26 16:05:35 -07009415 mLastIdleTimeStart = elapsedRealtimeMillis;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07009416 mLongestLightIdleTime = 0;
9417 mLongestFullIdleTime = 0;
9418 mDeviceIdleModeLightTimer.reset(false);
9419 mDeviceIdleModeFullTimer.reset(false);
9420 mDeviceLightIdlingTimer.reset(false);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009421 mDeviceIdlingTimer.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009422 mPhoneOnTimer.reset(false);
9423 mAudioOnTimer.reset(false);
9424 mVideoOnTimer.reset(false);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009425 mFlashlightOnTimer.reset(false);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07009426 mCameraOnTimer.reset(false);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08009427 mBluetoothScanTimer.reset(false);
Wink Saville52840902011-02-18 12:40:47 -08009428 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009429 mPhoneSignalStrengthsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009430 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009431 mPhoneSignalScanningTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009432 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009433 mPhoneDataConnectionsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009434 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009435 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009436 mNetworkByteActivityCounters[i].reset(false);
9437 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009438 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009439 mMobileRadioActiveTimer.reset(false);
9440 mMobileRadioActivePerAppTimer.reset(false);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009441 mMobileRadioActiveAdjustedTime.reset(false);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009442 mMobileRadioActiveUnknownTime.reset(false);
9443 mMobileRadioActiveUnknownCount.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009444 mWifiOnTimer.reset(false);
9445 mGlobalWifiRunningTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009446 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009447 mWifiStateTimer[i].reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009448 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009449 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9450 mWifiSupplStateTimer[i].reset(false);
9451 }
9452 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9453 mWifiSignalStrengthsTimer[i].reset(false);
9454 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009455 mWifiActivity.reset(false);
9456 mBluetoothActivity.reset(false);
9457 mModemActivity.reset(false);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009458 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009459
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009460 for (int i=0; i<mUidStats.size(); i++) {
9461 if (mUidStats.valueAt(i).reset()) {
9462 mUidStats.remove(mUidStats.keyAt(i));
9463 i--;
9464 }
9465 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009466
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009467 if (mKernelWakelockStats.size() > 0) {
9468 for (SamplingTimer timer : mKernelWakelockStats.values()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009469 mOnBatteryScreenOffTimeBase.remove(timer);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009470 }
9471 mKernelWakelockStats.clear();
9472 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009473
James Carr3a226052016-07-01 14:49:52 -07009474 if (mKernelMemoryStats.size() > 0) {
9475 for (int i = 0; i < mKernelMemoryStats.size(); i++) {
9476 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i));
9477 }
9478 mKernelMemoryStats.clear();
9479 }
9480
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009481 if (mWakeupReasonStats.size() > 0) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009482 for (SamplingTimer timer : mWakeupReasonStats.values()) {
9483 mOnBatteryTimeBase.remove(timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009484 }
9485 mWakeupReasonStats.clear();
9486 }
9487
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08009488 mLastHistoryStepDetails = null;
9489 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0;
9490 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0;
9491 mLastStepCpuUserTime = mCurStepCpuUserTime = 0;
9492 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0;
9493 mLastStepStatUserTime = mCurStepStatUserTime = 0;
9494 mLastStepStatSystemTime = mCurStepStatSystemTime = 0;
9495 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0;
9496 mLastStepStatIrqTime = mCurStepStatIrqTime = 0;
9497 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0;
9498 mLastStepStatIdleTime = mCurStepStatIdleTime = 0;
9499
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009500 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009501
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009502 clearHistoryLocked();
9503 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009504
Dianne Hackborn40c87252014-03-19 16:55:40 -07009505 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08009506 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009507 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) {
9508 // Not recording process starts/stops.
9509 continue;
9510 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07009511 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08009512 if (active == null) {
9513 continue;
9514 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07009515 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
9516 SparseIntArray uids = ent.getValue();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08009517 for (int j=0; j<uids.size(); j++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07009518 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
9519 uids.keyAt(j));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08009520 }
9521 }
9522 }
9523 }
9524
Dianne Hackborn32de2f62011-03-09 14:03:35 -08009525 void updateDischargeScreenLevelsLocked(boolean oldScreenOn, boolean newScreenOn) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009526 if (oldScreenOn) {
9527 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
9528 if (diff > 0) {
9529 mDischargeAmountScreenOn += diff;
9530 mDischargeAmountScreenOnSinceCharge += diff;
9531 }
9532 } else {
9533 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
9534 if (diff > 0) {
9535 mDischargeAmountScreenOff += diff;
9536 mDischargeAmountScreenOffSinceCharge += diff;
9537 }
9538 }
9539 if (newScreenOn) {
9540 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
9541 mDischargeScreenOffUnplugLevel = 0;
9542 } else {
9543 mDischargeScreenOnUnplugLevel = 0;
9544 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
9545 }
9546 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009547
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009548 public void pullPendingStateUpdatesLocked() {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08009549 if (mOnBatteryInternal) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07009550 final boolean screenOn = mScreenState == Display.STATE_ON;
9551 updateDischargeScreenLevelsLocked(screenOn, screenOn);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08009552 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009553 }
9554
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009555 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
9556 private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6);
9557
9558 private final Object mWifiNetworkLock = new Object();
9559
9560 @GuardedBy("mWifiNetworkLock")
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009561 private String[] mWifiIfaces = EmptyArray.STRING;
9562
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009563 @GuardedBy("mWifiNetworkLock")
9564 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009565
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009566 private final Object mModemNetworkLock = new Object();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009567
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009568 @GuardedBy("mModemNetworkLock")
9569 private String[] mModemIfaces = EmptyArray.STRING;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009570
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009571 @GuardedBy("mModemNetworkLock")
9572 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1);
9573
9574 private NetworkStats readNetworkStatsLocked(String[] ifaces) {
9575 try {
9576 if (!ArrayUtils.isEmpty(ifaces)) {
9577 return mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces,
9578 NetworkStats.TAG_NONE, mNetworkStatsPool.acquire());
9579 }
9580 } catch (IOException e) {
9581 Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces));
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009582 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009583 return null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009584 }
9585
9586 /**
9587 * Distribute WiFi energy info and network traffic to apps.
9588 * @param info The energy information from the WiFi controller.
9589 */
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009590 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -07009591 if (DEBUG_ENERGY) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009592 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces));
Adam Lesinskia7c90c82015-06-18 14:52:24 -07009593 }
9594
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009595 // Grab a separate lock to acquire the network stats, which may do I/O.
Adam Lesinskie08af192015-03-25 16:42:59 -07009596 NetworkStats delta = null;
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009597 synchronized (mWifiNetworkLock) {
9598 final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces);
9599 if (latestStats != null) {
9600 delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null,
9601 mNetworkStatsPool.acquire());
9602 mNetworkStatsPool.release(mLastWifiNetworkStats);
9603 mLastWifiNetworkStats = latestStats;
Adam Lesinskie08af192015-03-25 16:42:59 -07009604 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009605 }
9606
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009607 synchronized (this) {
9608 if (!mOnBatteryInternal) {
9609 if (delta != null) {
9610 mNetworkStatsPool.release(delta);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009611 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009612 return;
9613 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009614
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009615 final long elapsedRealtimeMs = mClocks.elapsedRealtime();
9616 SparseLongArray rxPackets = new SparseLongArray();
9617 SparseLongArray txPackets = new SparseLongArray();
9618 long totalTxPackets = 0;
9619 long totalRxPackets = 0;
9620 if (delta != null) {
9621 NetworkStats.Entry entry = new NetworkStats.Entry();
9622 final int size = delta.size();
9623 for (int i = 0; i < size; i++) {
9624 entry = delta.getValues(i, entry);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009625
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009626 if (DEBUG_ENERGY) {
9627 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
9628 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
9629 + " txPackets=" + entry.txPackets);
9630 }
9631
9632 if (entry.rxBytes == 0 && entry.txBytes == 0) {
9633 // Skip the lookup below since there is no work to do.
9634 continue;
9635 }
9636
9637 final Uid u = getUidStatsLocked(mapUid(entry.uid));
9638 if (entry.rxBytes != 0) {
9639 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
Amith Yamasani59fe8412017-03-03 16:28:52 -08009640 entry.rxPackets);
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009641 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
9642 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes,
9643 entry.rxPackets);
9644 }
9645 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
9646 entry.rxBytes);
9647 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
9648 entry.rxPackets);
9649
9650 rxPackets.put(u.getUid(), entry.rxPackets);
9651
9652 // Sum the total number of packets so that the Rx Power can
9653 // be evenly distributed amongst the apps.
9654 totalRxPackets += entry.rxPackets;
Amith Yamasani59fe8412017-03-03 16:28:52 -08009655 }
Adam Lesinskie08af192015-03-25 16:42:59 -07009656
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009657 if (entry.txBytes != 0) {
9658 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
Amith Yamasani59fe8412017-03-03 16:28:52 -08009659 entry.txPackets);
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009660 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
9661 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes,
9662 entry.txPackets);
9663 }
9664 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
9665 entry.txBytes);
9666 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
9667 entry.txPackets);
9668
9669 txPackets.put(u.getUid(), entry.txPackets);
9670
9671 // Sum the total number of packets so that the Tx Power can
9672 // be evenly distributed amongst the apps.
9673 totalTxPackets += entry.txPackets;
Amith Yamasani59fe8412017-03-03 16:28:52 -08009674 }
Adam Lesinskiba88e682015-12-08 12:06:55 -08009675 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009676 mNetworkStatsPool.release(delta);
9677 delta = null;
Adam Lesinskie08af192015-03-25 16:42:59 -07009678 }
9679
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009680 if (info != null) {
9681 mHasWifiReporting = true;
Adam Lesinskie08af192015-03-25 16:42:59 -07009682
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009683 // Measured in mAms
9684 final long txTimeMs = info.getControllerTxTimeMillis();
9685 final long rxTimeMs = info.getControllerRxTimeMillis();
9686 final long idleTimeMs = info.getControllerIdleTimeMillis();
9687 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
Adam Lesinskie08af192015-03-25 16:42:59 -07009688
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009689 long leftOverRxTimeMs = rxTimeMs;
9690 long leftOverTxTimeMs = txTimeMs;
Adam Lesinskie08af192015-03-25 16:42:59 -07009691
Adam Lesinskie08af192015-03-25 16:42:59 -07009692 if (DEBUG_ENERGY) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009693 Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
9694 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
9695 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
9696 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
9697 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms");
Adam Lesinskie08af192015-03-25 16:42:59 -07009698 }
Adam Lesinskie08af192015-03-25 16:42:59 -07009699
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009700 long totalWifiLockTimeMs = 0;
9701 long totalScanTimeMs = 0;
9702
9703 // On the first pass, collect some totals so that we can normalize power
9704 // calculations if we need to.
9705 final int uidStatsSize = mUidStats.size();
9706 for (int i = 0; i < uidStatsSize; i++) {
9707 final Uid uid = mUidStats.valueAt(i);
9708
9709 // Sum the total scan power for all apps.
9710 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
9711 elapsedRealtimeMs * 1000) / 1000;
9712
9713 // Sum the total time holding wifi lock for all apps.
9714 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
9715 elapsedRealtimeMs * 1000) / 1000;
9716 }
9717
9718 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
9719 Slog.d(TAG,
9720 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
9721 + rxTimeMs + " ms). Normalizing scan time.");
9722 }
9723 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) {
9724 Slog.d(TAG,
9725 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > "
9726 + txTimeMs + " ms). Normalizing scan time.");
9727 }
9728
9729 // Actually assign and distribute power usage to apps.
9730 for (int i = 0; i < uidStatsSize; i++) {
9731 final Uid uid = mUidStats.valueAt(i);
9732
9733 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
9734 elapsedRealtimeMs * 1000) / 1000;
9735 if (scanTimeSinceMarkMs > 0) {
9736 // Set the new mark so that next time we get new data since this point.
9737 uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
9738
9739 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs;
9740 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs;
9741
9742 // Our total scan time is more than the reported Tx/Rx time.
9743 // This is possible because the cost of a scan is approximate.
9744 // Let's normalize the result so that we evenly blame each app
9745 // scanning.
9746 //
9747 // This means that we may have apps that transmitted/received packets not be
9748 // blamed for this, but this is fine as scans are relatively more expensive.
9749 if (totalScanTimeMs > rxTimeMs) {
9750 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) /
9751 totalScanTimeMs;
9752 }
9753 if (totalScanTimeMs > txTimeMs) {
9754 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) /
9755 totalScanTimeMs;
9756 }
9757
9758 if (DEBUG_ENERGY) {
9759 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:"
9760 + scanRxTimeSinceMarkMs + " ms Tx:"
9761 + scanTxTimeSinceMarkMs + " ms)");
9762 }
9763
9764 ControllerActivityCounterImpl activityCounter =
9765 uid.getOrCreateWifiControllerActivityLocked();
9766 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs);
9767 activityCounter.getTxTimeCounters()[0].addCountLocked(
9768 scanTxTimeSinceMarkMs);
9769 leftOverRxTimeMs -= scanRxTimeSinceMarkMs;
9770 leftOverTxTimeMs -= scanTxTimeSinceMarkMs;
9771 }
9772
9773 // Distribute evenly the power consumed while Idle to each app holding a WiFi
9774 // lock.
9775 final long wifiLockTimeSinceMarkMs =
9776 uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
9777 elapsedRealtimeMs * 1000) / 1000;
9778 if (wifiLockTimeSinceMarkMs > 0) {
9779 // Set the new mark so that next time we get new data since this point.
9780 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
9781
9782 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
9783 / totalWifiLockTimeMs;
9784 if (DEBUG_ENERGY) {
9785 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": "
9786 + myIdleTimeMs + " ms");
9787 }
9788 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter()
9789 .addCountLocked(myIdleTimeMs);
9790 }
9791 }
9792
Adam Lesinskie08af192015-03-25 16:42:59 -07009793 if (DEBUG_ENERGY) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009794 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
9795 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms");
Adam Lesinskie08af192015-03-25 16:42:59 -07009796 }
Adam Lesinskie08af192015-03-25 16:42:59 -07009797
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009798 // Distribute the remaining Tx power appropriately between all apps that transmitted
9799 // packets.
9800 for (int i = 0; i < txPackets.size(); i++) {
9801 final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
9802 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs)
9803 / totalTxPackets;
9804 if (DEBUG_ENERGY) {
9805 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
9806 }
9807 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0]
9808 .addCountLocked(myTxTimeMs);
9809 }
Adam Lesinskie08af192015-03-25 16:42:59 -07009810
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009811 // Distribute the remaining Rx power appropriately between all apps that received
9812 // packets.
9813 for (int i = 0; i < rxPackets.size(); i++) {
9814 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i));
9815 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs)
9816 / totalRxPackets;
9817 if (DEBUG_ENERGY) {
9818 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
9819 }
9820 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter()
9821 .addCountLocked(myRxTimeMs);
9822 }
Adam Lesinskie08af192015-03-25 16:42:59 -07009823
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009824 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
9825
9826
9827 // Update WiFi controller stats.
9828 mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis());
9829 mWifiActivity.getTxTimeCounters()[0].addCountLocked(
9830 info.getControllerTxTimeMillis());
9831 mWifiActivity.getIdleTimeCounter().addCountLocked(
9832 info.getControllerIdleTimeMillis());
9833
9834 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
9835 final double opVolt = mPowerProfile.getAveragePower(
9836 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
9837 if (opVolt != 0) {
9838 // We store the power drain as mAms.
9839 mWifiActivity.getPowerCounter().addCountLocked(
9840 (long) (info.getControllerEnergyUsed() / opVolt));
9841 }
Adam Lesinskie08af192015-03-25 16:42:59 -07009842 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009843 }
9844 }
9845
9846 /**
9847 * Distribute Cell radio energy info and network traffic to apps.
9848 */
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009849 public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -07009850 if (DEBUG_ENERGY) {
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009851 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo);
Adam Lesinskia7c90c82015-06-18 14:52:24 -07009852 }
9853
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009854 // Grab a separate lock to acquire the network stats, which may do I/O.
Adam Lesinskie08af192015-03-25 16:42:59 -07009855 NetworkStats delta = null;
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009856 synchronized (mModemNetworkLock) {
9857 final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces);
9858 if (latestStats != null) {
9859 delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null,
9860 mNetworkStatsPool.acquire());
9861 mNetworkStatsPool.release(mLastModemNetworkStats);
9862 mLastModemNetworkStats = latestStats;
Adam Lesinskie08af192015-03-25 16:42:59 -07009863 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009864 }
9865
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009866 synchronized (this) {
9867 if (!mOnBatteryInternal) {
9868 if (delta != null) {
9869 mNetworkStatsPool.release(delta);
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009870 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009871 return;
Adam Lesinskie08af192015-03-25 16:42:59 -07009872 }
9873
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07009874 final long elapsedRealtimeMs = mClocks.elapsedRealtime();
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009875 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
9876 elapsedRealtimeMs * 1000);
9877 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
9878
9879 long totalRxPackets = 0;
9880 long totalTxPackets = 0;
9881 if (delta != null) {
9882 NetworkStats.Entry entry = new NetworkStats.Entry();
9883 final int size = delta.size();
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009884 for (int i = 0; i < size; i++) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009885 entry = delta.getValues(i, entry);
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009886 if (entry.rxPackets == 0 && entry.txPackets == 0) {
9887 continue;
9888 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009889
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009890 if (DEBUG_ENERGY) {
9891 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
9892 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
9893 + " txPackets=" + entry.txPackets);
9894 }
9895
9896 totalRxPackets += entry.rxPackets;
9897 totalTxPackets += entry.txPackets;
9898
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009899 final Uid u = getUidStatsLocked(mapUid(entry.uid));
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009900 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
9901 entry.rxPackets);
9902 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
9903 entry.txPackets);
9904 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
9905 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA,
9906 entry.rxBytes, entry.rxPackets);
9907 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA,
9908 entry.txBytes, entry.txPackets);
9909 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009910
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009911 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
9912 entry.rxBytes);
9913 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
9914 entry.txBytes);
9915 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
9916 entry.rxPackets);
9917 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
9918 entry.txPackets);
9919 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009920
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009921 // Now distribute proportional blame to the apps that did networking.
9922 long totalPackets = totalRxPackets + totalTxPackets;
9923 if (totalPackets > 0) {
9924 for (int i = 0; i < size; i++) {
9925 entry = delta.getValues(i, entry);
9926 if (entry.rxPackets == 0 && entry.txPackets == 0) {
9927 continue;
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009928 }
9929
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009930 final Uid u = getUidStatsLocked(mapUid(entry.uid));
9931
9932 // Distribute total radio active time in to this app.
9933 final long appPackets = entry.rxPackets + entry.txPackets;
9934 final long appRadioTime = (radioTime * appPackets) / totalPackets;
9935 u.noteMobileRadioActiveTimeLocked(appRadioTime);
9936
9937 // Remove this app from the totals, so that we don't lose any time
9938 // due to rounding.
9939 radioTime -= appRadioTime;
9940 totalPackets -= appPackets;
9941
9942 if (activityInfo != null) {
9943 ControllerActivityCounterImpl activityCounter =
9944 u.getOrCreateModemControllerActivityLocked();
9945 if (totalRxPackets > 0 && entry.rxPackets > 0) {
9946 final long rxMs = (entry.rxPackets * activityInfo.getRxTimeMillis())
9947 / totalRxPackets;
9948 activityCounter.getRxTimeCounter().addCountLocked(rxMs);
9949 }
9950
9951 if (totalTxPackets > 0 && entry.txPackets > 0) {
9952 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
9953 long txMs =
9954 entry.txPackets * activityInfo.getTxTimeMillis()[lvl];
9955 txMs /= totalTxPackets;
9956 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs);
9957 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009958 }
9959 }
9960 }
9961 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009962
9963 if (radioTime > 0) {
9964 // Whoops, there is some radio time we can't blame on an app!
9965 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
9966 mMobileRadioActiveUnknownCount.addCountLocked(1);
9967 }
9968
9969 mNetworkStatsPool.release(delta);
9970 delta = null;
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009971 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009972
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009973 if (activityInfo != null) {
9974 mHasModemReporting = true;
9975 mModemActivity.getIdleTimeCounter().addCountLocked(
9976 activityInfo.getIdleTimeMillis());
9977 mModemActivity.getRxTimeCounter().addCountLocked(activityInfo.getRxTimeMillis());
9978 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
9979 mModemActivity.getTxTimeCounters()[lvl]
9980 .addCountLocked(activityInfo.getTxTimeMillis()[lvl]);
9981 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009982
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009983 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
9984 final double opVolt = mPowerProfile.getAveragePower(
9985 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
9986 if (opVolt != 0) {
9987 // We store the power drain as mAms.
9988 mModemActivity.getPowerCounter().addCountLocked(
9989 (long) (activityInfo.getEnergyUsed() / opVolt));
9990 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009991 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009992 }
9993 }
9994
9995 /**
9996 * Distribute Bluetooth energy info and network traffic to apps.
9997 * @param info The energy information from the bluetooth controller.
9998 */
9999 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -070010000 if (DEBUG_ENERGY) {
Adam Lesinski50e47602015-12-04 17:04:54 -080010001 Slog.d(TAG, "Updating bluetooth stats: " + info);
Adam Lesinskia7c90c82015-06-18 14:52:24 -070010002 }
10003
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010004 if (info == null || !mOnBatteryInternal) {
10005 return;
10006 }
Adam Lesinskie283d332015-04-16 12:29:25 -070010007
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010008 mHasBluetoothReporting = true;
10009
Bookatz867c0d72017-03-07 18:23:42 -080010010 final long elapsedRealtimeMs = mClocks.elapsedRealtime();
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010011 final long rxTimeMs = info.getControllerRxTimeMillis();
10012 final long txTimeMs = info.getControllerTxTimeMillis();
10013
10014 if (DEBUG_ENERGY) {
10015 Slog.d(TAG, "------ BEGIN BLE power blaming ------");
10016 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
10017 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
10018 Slog.d(TAG, " Idle Time: " + info.getControllerIdleTimeMillis() + " ms");
10019 }
10020
10021 long totalScanTimeMs = 0;
10022
10023 final int uidCount = mUidStats.size();
10024 for (int i = 0; i < uidCount; i++) {
10025 final Uid u = mUidStats.valueAt(i);
10026 if (u.mBluetoothScanTimer == null) {
10027 continue;
Adam Lesinskie283d332015-04-16 12:29:25 -070010028 }
Adam Lesinski50e47602015-12-04 17:04:54 -080010029
Bookatzaa4594a2017-03-24 12:39:56 -070010030 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked(
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010031 elapsedRealtimeMs * 1000) / 1000;
10032 }
10033
10034 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs);
10035 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs);
10036
10037 if (DEBUG_ENERGY) {
10038 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime
10039 + " TX=" + normalizeScanTxTime);
10040 }
10041
10042 long leftOverRxTimeMs = rxTimeMs;
10043 long leftOverTxTimeMs = txTimeMs;
10044
10045 for (int i = 0; i < uidCount; i++) {
10046 final Uid u = mUidStats.valueAt(i);
10047 if (u.mBluetoothScanTimer == null) {
10048 continue;
10049 }
10050
Bookatzaa4594a2017-03-24 12:39:56 -070010051 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked(
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010052 elapsedRealtimeMs * 1000) / 1000;
10053 if (scanTimeSinceMarkMs > 0) {
10054 // Set the new mark so that next time we get new data since this point.
10055 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs);
10056
10057 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs;
10058 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs;
10059
10060 if (normalizeScanRxTime) {
10061 // Scan time is longer than the total rx time in the controller,
10062 // so distribute the scan time proportionately. This means regular traffic
10063 // will not blamed, but scans are more expensive anyways.
10064 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs;
10065 }
10066
10067 if (normalizeScanTxTime) {
10068 // Scan time is longer than the total tx time in the controller,
10069 // so distribute the scan time proportionately. This means regular traffic
10070 // will not blamed, but scans are more expensive anyways.
10071 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs;
10072 }
10073
10074 final ControllerActivityCounterImpl counter =
10075 u.getOrCreateBluetoothControllerActivityLocked();
10076 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs);
10077 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs);
10078
10079 leftOverRxTimeMs -= scanTimeRxSinceMarkMs;
10080 leftOverTxTimeMs -= scanTimeTxSinceMarkMs;
10081 }
10082 }
10083
10084 if (DEBUG_ENERGY) {
10085 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs
10086 + " TX=" + leftOverTxTimeMs);
10087 }
10088
10089 //
10090 // Now distribute blame to apps that did bluetooth traffic.
10091 //
10092
10093 long totalTxBytes = 0;
10094 long totalRxBytes = 0;
10095
10096 final UidTraffic[] uidTraffic = info.getUidTraffic();
10097 final int numUids = uidTraffic != null ? uidTraffic.length : 0;
10098 for (int i = 0; i < numUids; i++) {
10099 final UidTraffic traffic = uidTraffic[i];
10100
10101 // Add to the global counters.
10102 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(
10103 traffic.getRxBytes());
10104 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(
10105 traffic.getTxBytes());
10106
10107 // Add to the UID counters.
10108 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()));
10109 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, traffic.getRxBytes(), 0);
10110 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, traffic.getTxBytes(), 0);
10111
10112 // Calculate the total traffic.
10113 totalTxBytes += traffic.getTxBytes();
10114 totalRxBytes += traffic.getRxBytes();
10115 }
10116
10117 if ((totalTxBytes != 0 || totalRxBytes != 0) &&
10118 (leftOverRxTimeMs != 0 || leftOverTxTimeMs != 0)) {
Adam Lesinski50e47602015-12-04 17:04:54 -080010119 for (int i = 0; i < numUids; i++) {
10120 final UidTraffic traffic = uidTraffic[i];
10121
Adam Lesinski50e47602015-12-04 17:04:54 -080010122 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()));
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010123 final ControllerActivityCounterImpl counter =
10124 u.getOrCreateBluetoothControllerActivityLocked();
10125
10126 if (totalRxBytes > 0 && traffic.getRxBytes() > 0) {
10127 final long timeRxMs = (leftOverRxTimeMs * traffic.getRxBytes()) / totalRxBytes;
10128
10129 if (DEBUG_ENERGY) {
10130 Slog.d(TAG, "UID=" + traffic.getUid() + " rx_bytes=" + traffic.getRxBytes()
10131 + " rx_time=" + timeRxMs);
10132 }
10133 counter.getRxTimeCounter().addCountLocked(timeRxMs);
10134 leftOverRxTimeMs -= timeRxMs;
10135 }
10136
10137 if (totalTxBytes > 0 && traffic.getTxBytes() > 0) {
10138 final long timeTxMs = (leftOverTxTimeMs * traffic.getTxBytes()) / totalTxBytes;
10139
10140 if (DEBUG_ENERGY) {
10141 Slog.d(TAG, "UID=" + traffic.getUid() + " tx_bytes=" + traffic.getTxBytes()
10142 + " tx_time=" + timeTxMs);
10143 }
10144
10145 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs);
10146 leftOverTxTimeMs -= timeTxMs;
10147 }
Adam Lesinski50e47602015-12-04 17:04:54 -080010148 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010149 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010150
10151 mBluetoothActivity.getRxTimeCounter().addCountLocked(
10152 info.getControllerRxTimeMillis());
10153 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(
10154 info.getControllerTxTimeMillis());
10155 mBluetoothActivity.getIdleTimeCounter().addCountLocked(
10156 info.getControllerIdleTimeMillis());
10157
10158 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
10159 final double opVolt = mPowerProfile.getAveragePower(
10160 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
10161 if (opVolt != 0) {
10162 // We store the power drain as mAms.
10163 mBluetoothActivity.getPowerCounter().addCountLocked(
10164 (long) (info.getControllerEnergyUsed() / opVolt));
10165 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010166 }
10167
10168 /**
10169 * Read and distribute kernel wake lock use across apps.
10170 */
10171 public void updateKernelWakelocksLocked() {
10172 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
10173 mTmpWakelockStats);
10174 if (wakelockStats == null) {
10175 // Not crashing might make board bringup easier.
10176 Slog.w(TAG, "Couldn't get kernel wake lock stats");
10177 return;
10178 }
10179
10180 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
10181 String name = ent.getKey();
10182 KernelWakelockStats.Entry kws = ent.getValue();
10183
10184 SamplingTimer kwlt = mKernelWakelockStats.get(name);
10185 if (kwlt == null) {
Adam Lesinski757c6ea2016-04-21 09:55:41 -070010186 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010187 mKernelWakelockStats.put(name, kwlt);
10188 }
Adam Lesinskid84ad302016-05-17 18:31:02 -070010189
Adam Lesinski757c6ea2016-04-21 09:55:41 -070010190 kwlt.update(kws.mTotalTime, kws.mCount);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010191 kwlt.setUpdateVersion(kws.mVersion);
10192 }
10193
Adam Lesinskifbabe7d2015-08-03 14:37:38 -070010194 int numWakelocksSetStale = 0;
Adam Lesinskid84ad302016-05-17 18:31:02 -070010195 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks)
10196 // this time.
10197 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
10198 SamplingTimer st = ent.getValue();
10199 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
10200 st.endSample();
10201 numWakelocksSetStale++;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010202 }
10203 }
Adam Lesinskifbabe7d2015-08-03 14:37:38 -070010204
Adam Lesinskid84ad302016-05-17 18:31:02 -070010205 // Record whether we've seen a non-zero time (for debugging b/22716723).
10206 if (wakelockStats.isEmpty()) {
Adam Lesinskifbabe7d2015-08-03 14:37:38 -070010207 Slog.wtf(TAG, "All kernel wakelocks had time of zero");
10208 }
10209
10210 if (numWakelocksSetStale == mKernelWakelockStats.size()) {
10211 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" +
10212 wakelockStats.kernelWakelockVersion);
10213 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010214 }
10215
Adam Lesinski72478f02015-06-17 15:39:43 -070010216 // We use an anonymous class to access these variables,
10217 // so they can't live on the stack or they'd have to be
10218 // final MutableLong objects (more allocations).
10219 // Used in updateCpuTimeLocked().
10220 long mTempTotalCpuUserTimeUs;
10221 long mTempTotalCpuSystemTimeUs;
10222
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010223 /**
James Carr3a226052016-07-01 14:49:52 -070010224 * Reads the newest memory stats from the kernel.
10225 */
10226 public void updateKernelMemoryBandwidthLocked() {
10227 mKernelMemoryBandwidthStats.updateStats();
10228 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries();
10229 final int bandwidthEntryCount = bandwidthEntries.size();
10230 int index;
10231 for (int i = 0; i < bandwidthEntryCount; i++) {
10232 SamplingTimer timer;
10233 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) {
10234 timer = mKernelMemoryStats.valueAt(index);
10235 } else {
10236 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase);
10237 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer);
10238 }
10239 timer.update(bandwidthEntries.valueAt(i), 1);
10240 if (DEBUG_MEMORY) {
10241 Slog.d(TAG, String.format("Added entry %d and updated timer to: "
10242 + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i),
10243 mKernelMemoryStats.get(
10244 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime,
10245 mKernelMemoryStats.size()));
10246 }
10247 }
10248 }
10249
10250 /**
Adam Lesinski72478f02015-06-17 15:39:43 -070010251 * Read and distribute CPU usage across apps. If their are partial wakelocks being held
10252 * and we are on battery with screen off, we give more of the cpu time to those apps holding
10253 * wakelocks. If the screen is on, we just assign the actual cpu time an app used.
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010254 */
Sudheer Shanka671985f2017-05-19 11:33:42 -070010255 public void updateCpuTimeLocked(boolean updateCpuFreqData) {
Adam Lesinski52290c9c2015-09-21 16:54:52 -070010256 if (mPowerProfile == null) {
10257 return;
10258 }
10259
Adam Lesinski72478f02015-06-17 15:39:43 -070010260 if (DEBUG_ENERGY_CPU) {
10261 Slog.d(TAG, "!Cpu updating!");
10262 }
10263
10264 // Holding a wakelock costs more than just using the cpu.
10265 // Currently, we assign only half the cpu time to an app that is running but
10266 // not holding a wakelock. The apps holding wakelocks get the rest of the blame.
10267 // If no app is holding a wakelock, then the distribution is normal.
10268 final int wakelockWeight = 50;
10269
Adam Lesinski72478f02015-06-17 15:39:43 -070010270 int numWakelocks = 0;
10271
10272 // Calculate how many wakelocks we have to distribute amongst. The system is excluded.
10273 // Only distribute cpu power to wakelocks if the screen is off and we're on battery.
10274 final int numPartialTimers = mPartialTimers.size();
10275 if (mOnBatteryScreenOffTimeBase.isRunning()) {
10276 for (int i = 0; i < numPartialTimers; i++) {
10277 final StopwatchTimer timer = mPartialTimers.get(i);
10278 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
10279 // Since the collection and blaming of wakelocks can be scheduled to run after
10280 // some delay, the mPartialTimers list may have new entries. We can't blame
10281 // the newly added timer for past cpu time, so we only consider timers that
10282 // were present for one round of collection. Once a timer has gone through
10283 // a round of collection, its mInList field is set to true.
10284 numWakelocks++;
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010285 }
Adam Lesinski72478f02015-06-17 15:39:43 -070010286 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010287 }
Adam Lesinski72478f02015-06-17 15:39:43 -070010288
10289 final int numWakelocksF = numWakelocks;
10290 mTempTotalCpuUserTimeUs = 0;
10291 mTempTotalCpuSystemTimeUs = 0;
10292
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010293 final SparseLongArray updatedUids = new SparseLongArray();
10294
Adam Lesinski72478f02015-06-17 15:39:43 -070010295 // Read the CPU data for each UID. This will internally generate a snapshot so next time
10296 // we read, we get a delta. If we are to distribute the cpu time, then do so. Otherwise
10297 // we just ignore the data.
Amith Yamasanid0ddeba2017-05-26 09:46:58 -070010298 final long startTimeMs = mClocks.uptimeMillis();
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070010299 mUserInfoProvider.refreshUserIds();
Adam Lesinski72478f02015-06-17 15:39:43 -070010300 mKernelUidCpuTimeReader.readDelta(!mOnBatteryInternal ? null :
10301 new KernelUidCpuTimeReader.Callback() {
10302 @Override
Adam Lesinskid4abd1e2017-04-12 11:29:13 -070010303 public void onUidCpuTime(int uid, long userTimeUs, long systemTimeUs) {
Sudheer Shankaea87a4b2017-06-02 16:48:13 -070010304 uid = mapUid(uid);
10305 if (Process.isIsolated(uid)) {
10306 // This could happen if the isolated uid mapping was removed before
10307 // that process was actually killed.
10308 mKernelUidCpuTimeReader.removeUid(uid);
10309 Slog.d(TAG, "Got readings for an isolated uid with"
10310 + " no mapping to owning uid: " + uid);
10311 return;
10312 }
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070010313 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
10314 Slog.d(TAG, "Got readings for an invalid user's uid " + uid);
10315 mKernelUidCpuTimeReader.removeUid(uid);
10316 return;
10317 }
Sudheer Shankaea87a4b2017-06-02 16:48:13 -070010318 final Uid u = getUidStatsLocked(uid);
Adam Lesinski72478f02015-06-17 15:39:43 -070010319
10320 // Accumulate the total system and user time.
10321 mTempTotalCpuUserTimeUs += userTimeUs;
10322 mTempTotalCpuSystemTimeUs += systemTimeUs;
10323
10324 StringBuilder sb = null;
10325 if (DEBUG_ENERGY_CPU) {
10326 sb = new StringBuilder();
10327 sb.append(" got time for uid=").append(u.mUid).append(": u=");
10328 TimeUtils.formatDuration(userTimeUs / 1000, sb);
10329 sb.append(" s=");
10330 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
Adam Lesinskid4abd1e2017-04-12 11:29:13 -070010331 sb.append("\n");
Adam Lesinski72478f02015-06-17 15:39:43 -070010332 }
10333
10334 if (numWakelocksF > 0) {
10335 // We have wakelocks being held, so only give a portion of the
10336 // time to the process. The rest will be distributed among wakelock
10337 // holders.
10338 userTimeUs = (userTimeUs * wakelockWeight) / 100;
10339 systemTimeUs = (systemTimeUs * wakelockWeight) / 100;
10340 }
10341
10342 if (sb != null) {
10343 sb.append(" adding to uid=").append(u.mUid).append(": u=");
10344 TimeUtils.formatDuration(userTimeUs / 1000, sb);
10345 sb.append(" s=");
10346 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
10347 Slog.d(TAG, sb.toString());
10348 }
10349
10350 u.mUserCpuTime.addCountLocked(userTimeUs);
10351 u.mSystemCpuTime.addCountLocked(systemTimeUs);
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010352 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs);
Adam Lesinski72478f02015-06-17 15:39:43 -070010353 }
10354 });
10355
Sudheer Shanka671985f2017-05-19 11:33:42 -070010356 if (updateCpuFreqData) {
10357 readKernelUidCpuFreqTimesLocked();
10358 }
Sudheer Shanka9b735c52017-05-09 18:26:18 -070010359
Amith Yamasanid0ddeba2017-05-26 09:46:58 -070010360 final long elapse = (mClocks.uptimeMillis() - startTimeMs);
Makoto Onuki3f8e2972017-05-11 10:52:37 -070010361 if (DEBUG_ENERGY_CPU || (elapse >= 100)) {
10362 Slog.d(TAG, "Reading cpu stats took " + elapse + " ms");
Adam Lesinski72478f02015-06-17 15:39:43 -070010363 }
10364
10365 if (mOnBatteryInternal && numWakelocks > 0) {
10366 // Distribute a portion of the total cpu time to wakelock holders.
10367 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - wakelockWeight)) / 100;
10368 mTempTotalCpuSystemTimeUs =
10369 (mTempTotalCpuSystemTimeUs * (100 - wakelockWeight)) / 100;
10370
10371 for (int i = 0; i < numPartialTimers; i++) {
10372 final StopwatchTimer timer = mPartialTimers.get(i);
10373
10374 // The system does not share any blame, as it is usually holding the wakelock
10375 // on behalf of an app.
10376 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
10377 int userTimeUs = (int) (mTempTotalCpuUserTimeUs / numWakelocks);
10378 int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / numWakelocks);
10379
10380 if (DEBUG_ENERGY_CPU) {
10381 StringBuilder sb = new StringBuilder();
10382 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid)
10383 .append(": u=");
10384 TimeUtils.formatDuration(userTimeUs / 1000, sb);
10385 sb.append(" s=");
10386 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
10387 Slog.d(TAG, sb.toString());
10388 }
10389
10390 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs);
10391 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs);
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010392 final int uid = timer.mUid.getUid();
10393 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs);
Adam Lesinski72478f02015-06-17 15:39:43 -070010394
10395 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*");
Adam Lesinski062e66c2015-07-14 12:02:44 -070010396 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000);
Adam Lesinski72478f02015-06-17 15:39:43 -070010397
10398 mTempTotalCpuUserTimeUs -= userTimeUs;
10399 mTempTotalCpuSystemTimeUs -= systemTimeUs;
10400 numWakelocks--;
10401 }
10402 }
10403
10404 if (mTempTotalCpuUserTimeUs > 0 || mTempTotalCpuSystemTimeUs > 0) {
10405 // Anything left over is given to the system.
10406 if (DEBUG_ENERGY_CPU) {
10407 StringBuilder sb = new StringBuilder();
10408 sb.append(" Distributing lost time to system: u=");
10409 TimeUtils.formatDuration(mTempTotalCpuUserTimeUs / 1000, sb);
10410 sb.append(" s=");
10411 TimeUtils.formatDuration(mTempTotalCpuSystemTimeUs / 1000, sb);
10412 Slog.d(TAG, sb.toString());
10413 }
10414
10415 final Uid u = getUidStatsLocked(Process.SYSTEM_UID);
10416 u.mUserCpuTime.addCountLocked(mTempTotalCpuUserTimeUs);
10417 u.mSystemCpuTime.addCountLocked(mTempTotalCpuSystemTimeUs);
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010418 updatedUids.put(Process.SYSTEM_UID, updatedUids.get(Process.SYSTEM_UID, 0)
10419 + mTempTotalCpuUserTimeUs + mTempTotalCpuSystemTimeUs);
Adam Lesinski72478f02015-06-17 15:39:43 -070010420
10421 final Uid.Proc proc = u.getProcessStatsLocked("*lost*");
Adam Lesinski062e66c2015-07-14 12:02:44 -070010422 proc.addCpuTimeLocked((int) mTempTotalCpuUserTimeUs / 1000,
10423 (int) mTempTotalCpuSystemTimeUs / 1000);
Adam Lesinski72478f02015-06-17 15:39:43 -070010424 }
10425 }
10426
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010427 long totalCpuClustersTime = 0;
10428 // Read the time spent for each cluster at various cpu frequencies.
10429 final long[][] clusterSpeeds = new long[mKernelCpuSpeedReaders.length][];
10430 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
10431 clusterSpeeds[cluster] = mKernelCpuSpeedReaders[cluster].readDelta();
10432 if (clusterSpeeds[cluster] != null) {
10433 for (int speed = clusterSpeeds[cluster].length - 1; speed >= 0; --speed) {
10434 totalCpuClustersTime += clusterSpeeds[cluster][speed];
10435 }
10436 }
10437 }
10438 if (totalCpuClustersTime != 0) {
10439 // We have cpu times per freq aggregated over all uids but we need the times per uid.
10440 // So, we distribute total time spent by an uid to different cpu freqs based on the
10441 // amount of time cpu was running at that freq.
10442 final int updatedUidsCount = updatedUids.size();
10443 for (int i = 0; i < updatedUidsCount; ++i) {
10444 final Uid u = getUidStatsLocked(updatedUids.keyAt(i));
10445 final long appCpuTimeMs = updatedUids.valueAt(i) / 1000;
10446 // Add the cpu speeds to this UID.
10447 final int numClusters = mPowerProfile.getNumCpuClusters();
10448 if (u.mCpuClusterSpeed == null || u.mCpuClusterSpeed.length !=
10449 numClusters) {
10450 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][];
10451 }
10452
10453 for (int cluster = 0; cluster < clusterSpeeds.length; cluster++) {
10454 final int speedsInCluster = clusterSpeeds[cluster].length;
10455 if (u.mCpuClusterSpeed[cluster] == null || speedsInCluster !=
10456 u.mCpuClusterSpeed[cluster].length) {
10457 u.mCpuClusterSpeed[cluster] = new LongSamplingCounter[speedsInCluster];
10458 }
10459
10460 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeed[cluster];
10461 for (int speed = 0; speed < speedsInCluster; speed++) {
10462 if (cpuSpeeds[speed] == null) {
10463 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
10464 }
10465 cpuSpeeds[speed].addCountLocked(appCpuTimeMs * clusterSpeeds[cluster][speed]
10466 / totalCpuClustersTime);
10467 }
10468 }
10469 }
10470 }
10471
Adam Lesinski72478f02015-06-17 15:39:43 -070010472 // See if there is a difference in wakelocks between this collection and the last
10473 // collection.
10474 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) {
10475 // No difference, so each timer is now considered for the next collection.
10476 for (int i = 0; i < numPartialTimers; i++) {
10477 mPartialTimers.get(i).mInList = true;
10478 }
10479 } else {
10480 // The lists are different, meaning we added (or removed a timer) since the last
10481 // collection.
10482 final int numLastPartialTimers = mLastPartialTimers.size();
10483 for (int i = 0; i < numLastPartialTimers; i++) {
10484 mLastPartialTimers.get(i).mInList = false;
10485 }
10486 mLastPartialTimers.clear();
10487
10488 // Mark the current timers as gone through a collection.
10489 for (int i = 0; i < numPartialTimers; i++) {
10490 final StopwatchTimer timer = mPartialTimers.get(i);
10491 timer.mInList = true;
10492 mLastPartialTimers.add(timer);
10493 }
10494 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010495 }
10496
Sudheer Shanka9b735c52017-05-09 18:26:18 -070010497 void readKernelUidCpuFreqTimesLocked() {
10498 mKernelUidCpuFreqTimeReader.readDelta(!mOnBatteryInternal ? null :
10499 new KernelUidCpuFreqTimeReader.Callback() {
10500 @Override
10501 public void onCpuFreqs(long[] cpuFreqs) {
10502 mCpuFreqs = cpuFreqs;
10503 }
10504
10505 @Override
10506 public void onUidCpuFreqTime(int uid, long[] cpuFreqTimeMs) {
Sudheer Shankaea87a4b2017-06-02 16:48:13 -070010507 uid = mapUid(uid);
10508 if (Process.isIsolated(uid)) {
Sudheer Shanka6d8dcec2017-06-01 12:09:03 -070010509 mKernelUidCpuFreqTimeReader.removeUid(uid);
10510 Slog.d(TAG, "Got freq readings for an isolated uid with"
10511 + " no mapping to owning uid: " + uid);
Sudheer Shankaea87a4b2017-06-02 16:48:13 -070010512 return;
10513 }
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070010514 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
10515 Slog.d(TAG, "Got readings for an invalid user's uid " + uid);
10516 mKernelUidCpuFreqTimeReader.removeUid(uid);
10517 return;
10518 }
Sudheer Shankaea87a4b2017-06-02 16:48:13 -070010519 final Uid u = getUidStatsLocked(uid);
Sudheer Shanka9b735c52017-05-09 18:26:18 -070010520 if (u.mCpuFreqTimeMs == null) {
10521 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase);
10522 }
10523 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs);
10524 if (u.mScreenOffCpuFreqTimeMs == null) {
10525 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
10526 mOnBatteryScreenOffTimeBase);
10527 }
10528 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs);
10529 }
10530 });
10531 }
10532
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010533 boolean setChargingLocked(boolean charging) {
10534 if (mCharging != charging) {
10535 mCharging = charging;
10536 if (charging) {
Dianne Hackborn0c820db2015-04-14 17:47:34 -070010537 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010538 } else {
Dianne Hackborn0c820db2015-04-14 17:47:34 -070010539 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010540 }
10541 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING);
10542 return true;
10543 }
10544 return false;
10545 }
10546
Dianne Hackborn40c87252014-03-19 16:55:40 -070010547 void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime, final boolean onBattery,
Adam Lesinskif9b20a92016-06-17 17:30:01 -070010548 final int oldStatus, final int level, final int chargeUAh) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010549 boolean doWrite = false;
10550 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
10551 m.arg1 = onBattery ? 1 : 0;
10552 mHandler.sendMessage(m);
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010553
Dianne Hackborn40c87252014-03-19 16:55:40 -070010554 final long uptime = mSecUptime * 1000;
10555 final long realtime = mSecRealtime * 1000;
Jeff Browne95c3cd2014-05-02 16:59:26 -070010556 final boolean screenOn = mScreenState == Display.STATE_ON;
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010557 if (onBattery) {
10558 // We will reset our status if we are unplugging after the
10559 // battery was last full, or the level is at 100, or
10560 // we have gone through a significant charge (from a very low
10561 // level to a now very high level).
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080010562 boolean reset = false;
Dianne Hackborn9a755432014-05-15 17:05:22 -070010563 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010564 || level >= 90
Dianne Hackbornfb3809c2014-09-29 18:31:22 -070010565 || (mDischargeCurrentLevel < 20 && level >= 80)
10566 || (getHighDischargeAmountSinceCharge() >= 200
10567 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -070010568 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
Dianne Hackbornfb3809c2014-09-29 18:31:22 -070010569 + " dischargeLevel=" + mDischargeCurrentLevel
Dianne Hackborn73d6a822014-09-29 10:52:47 -070010570 + " lowAmount=" + getLowDischargeAmountSinceCharge()
10571 + " highAmount=" + getHighDischargeAmountSinceCharge());
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070010572 // Before we write, collect a snapshot of the final aggregated
10573 // stats to be reported in the next checkin. Only do this if we have
10574 // a sufficient amount of data to make it interesting.
10575 if (getLowDischargeAmountSinceCharge() >= 20) {
10576 final Parcel parcel = Parcel.obtain();
10577 writeSummaryToParcel(parcel, true);
10578 BackgroundThread.getHandler().post(new Runnable() {
10579 @Override public void run() {
10580 synchronized (mCheckinFile) {
10581 FileOutputStream stream = null;
10582 try {
10583 stream = mCheckinFile.startWrite();
10584 stream.write(parcel.marshall());
10585 stream.flush();
10586 FileUtils.sync(stream);
10587 stream.close();
10588 mCheckinFile.finishWrite(stream);
10589 } catch (IOException e) {
10590 Slog.w("BatteryStats",
10591 "Error writing checkin battery statistics", e);
10592 mCheckinFile.failWrite(stream);
10593 } finally {
10594 parcel.recycle();
10595 }
10596 }
10597 }
10598 });
10599 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010600 doWrite = true;
10601 resetAllStatsLocked();
Ying Wai (Daniel) Fan442ab762017-01-31 22:00:10 -080010602 if (chargeUAh > 0 && level > 0) {
Adam Lesinskif9b20a92016-06-17 17:30:01 -070010603 // Only use the reported coulomb charge value if it is supported and reported.
Ying Wai (Daniel) Fan9238b612017-01-18 15:50:19 -080010604 mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0));
Adam Lesinskif9b20a92016-06-17 17:30:01 -070010605 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010606 mDischargeStartLevel = level;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080010607 reset = true;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080010608 mDischargeStepTracker.init();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070010609 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010610 if (mCharging) {
10611 setChargingLocked(false);
10612 }
10613 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -080010614 mOnBattery = mOnBatteryInternal = true;
Dianne Hackborn260c5022014-04-29 11:23:16 -070010615 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -070010616 mMinDischargeStepLevel = level;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080010617 mDischargeStepTracker.clearTime();
10618 mDailyDischargeStepTracker.clearTime();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070010619 mInitStepMode = mCurStepMode;
10620 mModStepMode = 0;
Dianne Hackborna7c837f2014-01-15 16:20:44 -080010621 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010622 mHistoryCur.batteryLevel = (byte)level;
10623 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
10624 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
10625 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010626 if (reset) {
10627 mRecordingHistory = true;
10628 startRecordingHistory(mSecRealtime, mSecUptime, reset);
10629 }
Dianne Hackborn40c87252014-03-19 16:55:40 -070010630 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010631 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
Jeff Browne95c3cd2014-05-02 16:59:26 -070010632 if (screenOn) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010633 mDischargeScreenOnUnplugLevel = level;
10634 mDischargeScreenOffUnplugLevel = 0;
10635 } else {
10636 mDischargeScreenOnUnplugLevel = 0;
10637 mDischargeScreenOffUnplugLevel = level;
10638 }
10639 mDischargeAmountScreenOn = 0;
10640 mDischargeAmountScreenOff = 0;
Jeff Browne95c3cd2014-05-02 16:59:26 -070010641 updateTimeBasesLocked(true, !screenOn, uptime, realtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010642 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010643 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -080010644 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborna7c837f2014-01-15 16:20:44 -080010645 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010646 mHistoryCur.batteryLevel = (byte)level;
10647 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
10648 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
10649 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -070010650 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070010651 mDischargeCurrentLevel = mDischargePlugLevel = level;
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010652 if (level < mDischargeUnplugLevel) {
10653 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
10654 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
10655 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070010656 updateDischargeScreenLevelsLocked(screenOn, screenOn);
10657 updateTimeBasesLocked(false, !screenOn, uptime, realtime);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080010658 mChargeStepTracker.init();
Dianne Hackborn260c5022014-04-29 11:23:16 -070010659 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -070010660 mMaxChargeStepLevel = level;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070010661 mInitStepMode = mCurStepMode;
10662 mModStepMode = 0;
Dianne Hackborn32de2f62011-03-09 14:03:35 -080010663 }
10664 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
10665 if (mFile != null) {
10666 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010667 }
10668 }
10669 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070010670
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010671 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
10672 boolean reset) {
10673 mRecordingHistory = true;
10674 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn37de0982014-05-09 09:32:18 -070010675 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
10676 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
Dianne Hackborna1bd7922014-03-21 11:07:11 -070010677 mHistoryCur);
10678 mHistoryCur.currentTime = 0;
10679 if (reset) {
10680 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
10681 }
10682 }
10683
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070010684 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs,
10685 final long uptimeMs) {
10686 if (mRecordingHistory) {
10687 mHistoryCur.currentTime = currentTime;
10688 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
10689 mHistoryCur);
10690 mHistoryCur.currentTime = 0;
10691 }
10692 }
10693
Dianne Hackborn29cd7f12015-01-08 10:37:05 -080010694 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
10695 if (mRecordingHistory) {
10696 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn29cd7f12015-01-08 10:37:05 -080010697 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN,
10698 mHistoryCur);
10699 mHistoryCur.currentTime = 0;
10700 }
10701 }
10702
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010703 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010704 if (mExternalSync != null) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010705 mExternalSync.scheduleSync(reason, updateFlags);
Adam Lesinskia7c90c82015-06-18 14:52:24 -070010706 }
10707 }
10708
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070010709 // This should probably be exposed in the API, though it's not critical
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010710 public static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070010711
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010712 public void setBatteryStateLocked(int status, int health, int plugType, int level,
Adam Lesinski041d9172016-12-12 12:03:56 -080010713 int temp, int volt, int chargeUAh, int chargeFullUAh) {
Adam Lesinski29ddfe52017-03-29 19:29:00 -070010714 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
10715 temp = Math.max(0, temp);
10716
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010717 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
Joe Onoratoabded112016-02-08 16:49:39 -080010718 final long uptime = mClocks.uptimeMillis();
10719 final long elapsedRealtime = mClocks.elapsedRealtime();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010720 if (!mHaveBatteryLevel) {
10721 mHaveBatteryLevel = true;
10722 // We start out assuming that the device is plugged in (not
10723 // on battery). If our first report is now that we are indeed
10724 // plugged in, then twiddle our state to correctly reflect that
10725 // since we won't be going through the full setOnBattery().
10726 if (onBattery == mOnBattery) {
Dianne Hackborn260c5022014-04-29 11:23:16 -070010727 if (onBattery) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010728 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -070010729 } else {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010730 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -070010731 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070010732 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010733 // Always start out assuming charging, that will be updated later.
Dianne Hackborn0c820db2015-04-14 17:47:34 -070010734 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010735 mHistoryCur.batteryStatus = (byte)status;
10736 mHistoryCur.batteryLevel = (byte)level;
Adam Lesinski3ee3f632016-06-08 13:55:55 -070010737 mHistoryCur.batteryChargeUAh = chargeUAh;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010738 mMaxChargeStepLevel = mMinDischargeStepLevel =
10739 mLastChargeStepLevel = mLastDischargeStepLevel = level;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010740 mLastChargingStateLevel = level;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010741 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
10742 recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
10743 }
10744 int oldStatus = mHistoryCur.batteryStatus;
10745 if (onBattery) {
10746 mDischargeCurrentLevel = level;
10747 if (!mRecordingHistory) {
10748 mRecordingHistory = true;
10749 startRecordingHistory(elapsedRealtime, uptime, true);
10750 }
10751 } else if (level < 96) {
10752 if (!mRecordingHistory) {
10753 mRecordingHistory = true;
10754 startRecordingHistory(elapsedRealtime, uptime, true);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070010755 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -070010756 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010757 mCurrentBatteryLevel = level;
10758 if (mDischargePlugLevel < 0) {
10759 mDischargePlugLevel = level;
Marco Nelissend8593312009-04-30 14:45:06 -070010760 }
Adam Lesinski926969b2016-04-28 17:31:12 -070010761
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010762 if (onBattery != mOnBattery) {
10763 mHistoryCur.batteryLevel = (byte)level;
10764 mHistoryCur.batteryStatus = (byte)status;
10765 mHistoryCur.batteryHealth = (byte)health;
10766 mHistoryCur.batteryPlugType = (byte)plugType;
10767 mHistoryCur.batteryTemperature = (short)temp;
10768 mHistoryCur.batteryVoltage = (char)volt;
Adam Lesinski3ee3f632016-06-08 13:55:55 -070010769 if (chargeUAh < mHistoryCur.batteryChargeUAh) {
10770 // Only record discharges
10771 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh;
10772 mDischargeCounter.addCountLocked(chargeDiff);
10773 mDischargeScreenOffCounter.addCountLocked(chargeDiff);
10774 }
Adam Lesinskia8018ac2016-05-03 10:18:10 -070010775 mHistoryCur.batteryChargeUAh = chargeUAh;
Adam Lesinskif9b20a92016-06-17 17:30:01 -070010776 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010777 } else {
10778 boolean changed = false;
10779 if (mHistoryCur.batteryLevel != level) {
10780 mHistoryCur.batteryLevel = (byte)level;
10781 changed = true;
Marco Nelissend8593312009-04-30 14:45:06 -070010782
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010783 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
10784 // which will pull external stats.
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010785 scheduleSyncExternalStatsLocked("battery-level", ExternalStatsSync.UPDATE_ALL);
Evan Millarc64edde2009-04-18 12:26:32 -070010786 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010787 if (mHistoryCur.batteryStatus != status) {
10788 mHistoryCur.batteryStatus = (byte)status;
10789 changed = true;
10790 }
10791 if (mHistoryCur.batteryHealth != health) {
10792 mHistoryCur.batteryHealth = (byte)health;
10793 changed = true;
10794 }
10795 if (mHistoryCur.batteryPlugType != plugType) {
10796 mHistoryCur.batteryPlugType = (byte)plugType;
10797 changed = true;
10798 }
10799 if (temp >= (mHistoryCur.batteryTemperature+10)
10800 || temp <= (mHistoryCur.batteryTemperature-10)) {
10801 mHistoryCur.batteryTemperature = (short)temp;
10802 changed = true;
10803 }
10804 if (volt > (mHistoryCur.batteryVoltage+20)
10805 || volt < (mHistoryCur.batteryVoltage-20)) {
10806 mHistoryCur.batteryVoltage = (char)volt;
10807 changed = true;
10808 }
Adam Lesinskia8018ac2016-05-03 10:18:10 -070010809 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10)
10810 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) {
Adam Lesinski3ee3f632016-06-08 13:55:55 -070010811 if (chargeUAh < mHistoryCur.batteryChargeUAh) {
10812 // Only record discharges
10813 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh;
10814 mDischargeCounter.addCountLocked(chargeDiff);
10815 mDischargeScreenOffCounter.addCountLocked(chargeDiff);
10816 }
Adam Lesinskia8018ac2016-05-03 10:18:10 -070010817 mHistoryCur.batteryChargeUAh = chargeUAh;
Adam Lesinski926969b2016-04-28 17:31:12 -070010818 changed = true;
10819 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010820 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
10821 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
10822 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
10823 if (onBattery) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010824 changed |= setChargingLocked(false);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010825 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
10826 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
10827 modeBits, elapsedRealtime);
10828 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
10829 modeBits, elapsedRealtime);
10830 mLastDischargeStepLevel = level;
10831 mMinDischargeStepLevel = level;
10832 mInitStepMode = mCurStepMode;
10833 mModStepMode = 0;
10834 }
10835 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010836 if (level >= 90) {
10837 // If the battery level is at least 90%, always consider the device to be
10838 // charging even if it happens to go down a level.
10839 changed |= setChargingLocked(true);
10840 mLastChargeStepLevel = level;
10841 } if (!mCharging) {
10842 if (mLastChargeStepLevel < level) {
10843 // We have not reporting that we are charging, but the level has now
10844 // gone up, so consider the state to be charging.
10845 changed |= setChargingLocked(true);
10846 mLastChargeStepLevel = level;
10847 }
10848 } else {
10849 if (mLastChargeStepLevel > level) {
10850 // We had reported that the device was charging, but here we are with
10851 // power connected and the level going down. Looks like the current
10852 // power supplied isn't enough, so consider the device to now be
10853 // discharging.
10854 changed |= setChargingLocked(false);
10855 mLastChargeStepLevel = level;
10856 }
10857 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010858 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
10859 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
10860 modeBits, elapsedRealtime);
10861 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
10862 modeBits, elapsedRealtime);
10863 mLastChargeStepLevel = level;
10864 mMaxChargeStepLevel = level;
10865 mInitStepMode = mCurStepMode;
10866 mModStepMode = 0;
Evan Millarc64edde2009-04-18 12:26:32 -070010867 }
10868 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010869 if (changed) {
10870 addHistoryRecordLocked(elapsedRealtime, uptime);
10871 }
Evan Millarc64edde2009-04-18 12:26:32 -070010872 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010873 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
10874 // We don't record history while we are plugged in and fully charged.
10875 // The next time we are unplugged, history will be cleared.
10876 mRecordingHistory = DEBUG;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080010877 }
Adam Lesinski041d9172016-12-12 12:03:56 -080010878
Jocelyn Dangc627d102017-04-14 13:15:14 -070010879 if (mMinLearnedBatteryCapacity == -1) {
10880 mMinLearnedBatteryCapacity = chargeFullUAh;
10881 } else {
10882 Math.min(mMinLearnedBatteryCapacity, chargeFullUAh);
Adam Lesinski041d9172016-12-12 12:03:56 -080010883 }
Jocelyn Dangc627d102017-04-14 13:15:14 -070010884 mMaxLearnedBatteryCapacity = Math.max(mMaxLearnedBatteryCapacity, chargeFullUAh);
Adam Lesinski33dac552015-03-09 15:24:48 -070010885 }
10886
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010887 public long getAwakeTimeBattery() {
10888 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
10889 }
10890
10891 public long getAwakeTimePlugged() {
Joe Onoratoabded112016-02-08 16:49:39 -080010892 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010893 }
10894
10895 @Override
10896 public long computeUptime(long curTime, int which) {
10897 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070010898 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010899 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -070010900 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010901 }
10902 return 0;
10903 }
10904
10905 @Override
10906 public long computeRealtime(long curTime, int which) {
10907 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070010908 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010909 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -070010910 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010911 }
10912 return 0;
10913 }
10914
10915 @Override
10916 public long computeBatteryUptime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010917 return mOnBatteryTimeBase.computeUptime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010918 }
10919
10920 @Override
10921 public long computeBatteryRealtime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010922 return mOnBatteryTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010923 }
10924
Dianne Hackborn97ae5382014-03-05 16:43:25 -080010925 @Override
10926 public long computeBatteryScreenOffUptime(long curTime, int which) {
10927 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
10928 }
10929
10930 @Override
10931 public long computeBatteryScreenOffRealtime(long curTime, int which) {
10932 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010933 }
10934
Dianne Hackborn260c5022014-04-29 11:23:16 -070010935 private long computeTimePerLevel(long[] steps, int numSteps) {
10936 // For now we'll do a simple average across all steps.
10937 if (numSteps <= 0) {
10938 return -1;
10939 }
10940 long total = 0;
10941 for (int i=0; i<numSteps; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070010942 total += steps[i] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -070010943 }
10944 return total / numSteps;
10945 /*
10946 long[] buckets = new long[numSteps];
10947 int numBuckets = 0;
10948 int numToAverage = 4;
10949 int i = 0;
10950 while (i < numSteps) {
10951 long totalTime = 0;
10952 int num = 0;
10953 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070010954 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -070010955 num++;
10956 }
10957 buckets[numBuckets] = totalTime / num;
10958 numBuckets++;
10959 numToAverage *= 2;
10960 i += num;
10961 }
10962 if (numBuckets < 1) {
10963 return -1;
10964 }
10965 long averageTime = buckets[numBuckets-1];
10966 for (i=numBuckets-2; i>=0; i--) {
10967 averageTime = (averageTime + buckets[i]) / 2;
10968 }
10969 return averageTime;
10970 */
10971 }
10972
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070010973 @Override
10974 public long computeBatteryTimeRemaining(long curTime) {
10975 if (!mOnBattery) {
10976 return -1;
10977 }
Dianne Hackborn260c5022014-04-29 11:23:16 -070010978 /* Simple implementation just looks at the average discharge per level across the
10979 entire sample period.
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070010980 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2;
10981 if (discharge < 2) {
10982 return -1;
10983 }
10984 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED);
10985 if (duration < 1000*1000) {
10986 return -1;
10987 }
10988 long usPerLevel = duration/discharge;
10989 return usPerLevel * mCurrentBatteryLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -070010990 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080010991 if (mDischargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -070010992 return -1;
10993 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080010994 long msPerLevel = mDischargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -070010995 if (msPerLevel <= 0) {
10996 return -1;
10997 }
10998 return (msPerLevel * mCurrentBatteryLevel) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070010999 }
11000
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011001 @Override
11002 public LevelStepTracker getDischargeLevelStepTracker() {
11003 return mDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -070011004 }
11005
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011006 @Override
11007 public LevelStepTracker getDailyDischargeLevelStepTracker() {
11008 return mDailyDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -070011009 }
11010
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011011 @Override
11012 public long computeChargeTimeRemaining(long curTime) {
Dianne Hackborn260c5022014-04-29 11:23:16 -070011013 if (mOnBattery) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011014 // Not yet working.
11015 return -1;
11016 }
Dianne Hackborn260c5022014-04-29 11:23:16 -070011017 /* Broken
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011018 int curLevel = mCurrentBatteryLevel;
11019 int plugLevel = mDischargePlugLevel;
11020 if (plugLevel < 0 || curLevel < (plugLevel+1)) {
11021 return -1;
11022 }
11023 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED);
11024 if (duration < 1000*1000) {
11025 return -1;
11026 }
11027 long usPerLevel = duration/(curLevel-plugLevel);
11028 return usPerLevel * (100-curLevel);
Dianne Hackborn260c5022014-04-29 11:23:16 -070011029 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011030 if (mChargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -070011031 return -1;
11032 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011033 long msPerLevel = mChargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -070011034 if (msPerLevel <= 0) {
11035 return -1;
11036 }
11037 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011038 }
11039
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011040 @Override
11041 public LevelStepTracker getChargeLevelStepTracker() {
11042 return mChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -070011043 }
11044
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011045 @Override
11046 public LevelStepTracker getDailyChargeLevelStepTracker() {
11047 return mDailyChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -070011048 }
11049
Dianne Hackborn88e98df2015-03-23 13:29:14 -070011050 @Override
11051 public ArrayList<PackageChange> getDailyPackageChanges() {
11052 return mDailyPackageChanges;
11053 }
11054
Joe Onoratoe1acd632016-02-23 13:25:10 -080011055 protected long getBatteryUptimeLocked() {
Joe Onoratoabded112016-02-08 16:49:39 -080011056 return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011057 }
11058
11059 @Override
11060 public long getBatteryUptime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011061 return mOnBatteryTimeBase.getUptime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011062 }
11063
11064 @Override
11065 public long getBatteryRealtime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011066 return mOnBatteryTimeBase.getRealtime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011067 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -070011068
The Android Open Source Project10592532009-03-18 17:39:46 -070011069 @Override
Evan Millar633a1742009-04-02 16:36:33 -070011070 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -070011071 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -070011072 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -070011073 }
11074 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011075
Evan Millar633a1742009-04-02 16:36:33 -070011076 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011077 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -070011078 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011079
The Android Open Source Project10592532009-03-18 17:39:46 -070011080 @Override
Evan Millar633a1742009-04-02 16:36:33 -070011081 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -070011082 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -070011083 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -070011084 }
11085 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011086
Evan Millar633a1742009-04-02 16:36:33 -070011087 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -080011088 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -070011089 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011090
Amith Yamasanie43530a2009-08-21 13:11:37 -070011091 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070011092 public int getLowDischargeAmountSinceCharge() {
11093 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -080011094 int val = mLowDischargeAmountSinceCharge;
11095 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
11096 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
11097 }
11098 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070011099 }
11100 }
11101
11102 @Override
11103 public int getHighDischargeAmountSinceCharge() {
11104 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -080011105 int val = mHighDischargeAmountSinceCharge;
11106 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
11107 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
11108 }
11109 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070011110 }
11111 }
Dianne Hackborn40c87252014-03-19 16:55:40 -070011112
11113 @Override
11114 public int getDischargeAmount(int which) {
11115 int dischargeAmount = which == STATS_SINCE_CHARGED
11116 ? getHighDischargeAmountSinceCharge()
11117 : (getDischargeStartLevel() - getDischargeCurrentLevel());
11118 if (dischargeAmount < 0) {
11119 dischargeAmount = 0;
11120 }
11121 return dischargeAmount;
11122 }
11123
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011124 public int getDischargeAmountScreenOn() {
11125 synchronized(this) {
11126 int val = mDischargeAmountScreenOn;
Jeff Browne95c3cd2014-05-02 16:59:26 -070011127 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011128 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
11129 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
11130 }
11131 return val;
11132 }
11133 }
11134
11135 public int getDischargeAmountScreenOnSinceCharge() {
11136 synchronized(this) {
11137 int val = mDischargeAmountScreenOnSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -070011138 if (mOnBattery && mScreenState == Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011139 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
11140 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
11141 }
11142 return val;
11143 }
11144 }
11145
11146 public int getDischargeAmountScreenOff() {
11147 synchronized(this) {
11148 int val = mDischargeAmountScreenOff;
Jeff Browne95c3cd2014-05-02 16:59:26 -070011149 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011150 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
11151 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
11152 }
11153 return val;
11154 }
11155 }
11156
11157 public int getDischargeAmountScreenOffSinceCharge() {
11158 synchronized(this) {
11159 int val = mDischargeAmountScreenOffSinceCharge;
Jeff Browne95c3cd2014-05-02 16:59:26 -070011160 if (mOnBattery && mScreenState != Display.STATE_ON
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011161 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
11162 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
11163 }
11164 return val;
11165 }
11166 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070011167
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011168 /**
11169 * Retrieve the statistics object for a particular uid, creating if needed.
11170 */
11171 public Uid getUidStatsLocked(int uid) {
11172 Uid u = mUidStats.get(uid);
11173 if (u == null) {
Joe Onoratoabded112016-02-08 16:49:39 -080011174 u = new Uid(this, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011175 mUidStats.put(uid, u);
11176 }
11177 return u;
11178 }
11179
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070011180 public void onCleanupUserLocked(int userId) {
11181 final int firstUidForUser = UserHandle.getUid(userId, 0);
11182 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1);
11183 mKernelUidCpuFreqTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
11184 mKernelUidCpuTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
11185 }
11186
11187 public void onUserRemovedLocked(int userId) {
11188 final int firstUidForUser = UserHandle.getUid(userId, 0);
11189 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1);
11190 mUidStats.put(firstUidForUser, null);
11191 mUidStats.put(lastUidForUser, null);
11192 final int firstIndex = mUidStats.indexOfKey(firstUidForUser);
11193 final int lastIndex = mUidStats.indexOfKey(lastUidForUser);
11194 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1);
11195 }
11196
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011197 /**
11198 * Remove the statistics object for a particular uid.
11199 */
11200 public void removeUidStatsLocked(int uid) {
Adam Lesinskib83ffee2015-05-12 14:43:47 -070011201 mKernelUidCpuTimeReader.removeUid(uid);
Sudheer Shanka6d8dcec2017-06-01 12:09:03 -070011202 mKernelUidCpuFreqTimeReader.removeUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011203 mUidStats.remove(uid);
11204 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -070011205
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011206 /**
11207 * Retrieve the statistics object for a particular process, creating
11208 * if needed.
11209 */
11210 public Uid.Proc getProcessStatsLocked(int uid, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -070011211 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011212 Uid u = getUidStatsLocked(uid);
11213 return u.getProcessStatsLocked(name);
11214 }
11215
11216 /**
11217 * Retrieve the statistics object for a particular process, creating
11218 * if needed.
11219 */
11220 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -070011221 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011222 Uid u = getUidStatsLocked(uid);
11223 return u.getPackageStatsLocked(pkg);
11224 }
11225
11226 /**
11227 * Retrieve the statistics object for a particular service, creating
11228 * if needed.
11229 */
11230 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -070011231 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011232 Uid u = getUidStatsLocked(uid);
11233 return u.getServiceStatsLocked(pkg, name);
11234 }
11235
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011236 public void shutdownLocked() {
Joe Onoratoabded112016-02-08 16:49:39 -080011237 recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011238 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011239 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011240 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011241
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011242 Parcel mPendingWrite = null;
11243 final ReentrantLock mWriteLock = new ReentrantLock();
11244
11245 public void writeAsyncLocked() {
11246 writeLocked(false);
11247 }
11248
11249 public void writeSyncLocked() {
11250 writeLocked(true);
11251 }
11252
11253 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011254 if (mFile == null) {
11255 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011256 return;
11257 }
11258
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011259 if (mShuttingDown) {
11260 return;
11261 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011262
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011263 Parcel out = Parcel.obtain();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011264 writeSummaryToParcel(out, true);
Joe Onoratoabded112016-02-08 16:49:39 -080011265 mLastWriteTime = mClocks.elapsedRealtime();
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011266
11267 if (mPendingWrite != null) {
11268 mPendingWrite.recycle();
11269 }
11270 mPendingWrite = out;
11271
11272 if (sync) {
11273 commitPendingDataToDisk();
11274 } else {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011275 BackgroundThread.getHandler().post(new Runnable() {
11276 @Override public void run() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011277 commitPendingDataToDisk();
11278 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011279 });
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011280 }
11281 }
11282
11283 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070011284 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011285 synchronized (this) {
11286 next = mPendingWrite;
11287 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070011288 if (next == null) {
11289 return;
11290 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011291 }
11292
Amith Yamasanid2450862017-02-07 15:58:24 -080011293 mWriteLock.lock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011294 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011295 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011296 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011297 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070011298 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011299 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011300 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011301 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011302 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011303 mFile.rollback();
11304 } finally {
11305 next.recycle();
11306 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -070011307 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011308 }
11309
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011310 public void readLocked() {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011311 if (mDailyFile != null) {
11312 readDailyStatsLocked();
11313 }
11314
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011315 if (mFile == null) {
11316 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011317 return;
11318 }
11319
11320 mUidStats.clear();
11321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011322 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011323 File file = mFile.chooseForRead();
11324 if (!file.exists()) {
11325 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011326 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011327 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011328
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011329 byte[] raw = BatteryStatsHelper.readFully(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011330 Parcel in = Parcel.obtain();
11331 in.unmarshall(raw, 0, raw.length);
11332 in.setDataPosition(0);
11333 stream.close();
11334
11335 readSummaryFromParcel(in);
Dianne Hackborn00e25212014-02-19 10:49:24 -080011336 } catch(Exception e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011337 Slog.e("BatteryStats", "Error reading battery statistics", e);
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011338 resetAllStatsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011339 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011340
Dianne Hackborncd0e3352014-08-07 17:08:09 -070011341 mEndPlatformVersion = Build.ID;
11342
Dianne Hackborne5167ca2014-03-08 14:39:10 -080011343 if (mHistoryBuffer.dataPosition() > 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011344 mRecordingHistory = true;
Joe Onoratoabded112016-02-08 16:49:39 -080011345 final long elapsedRealtime = mClocks.elapsedRealtime();
11346 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -080011347 if (USE_OLD_HISTORY) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011348 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
Dianne Hackborne5167ca2014-03-08 14:39:10 -080011349 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011350 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
11351 startRecordingHistory(elapsedRealtime, uptime, false);
Dianne Hackborne8c88e62011-08-17 19:09:09 -070011352 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011353
11354 recordDailyStatsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011355 }
11356
11357 public int describeContents() {
11358 return 0;
11359 }
11360
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011361 void readHistory(Parcel in, boolean andOldHistory) throws ParcelFormatException {
Dianne Hackbornae384452011-06-28 12:33:48 -070011362 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011363
11364 mHistoryBuffer.setDataSize(0);
11365 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011366 mHistoryTagPool.clear();
11367 mNextHistoryTagIdx = 0;
11368 mNumHistoryTagChars = 0;
Dianne Hackborn099bc622014-01-22 13:39:16 -080011369
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011370 int numTags = in.readInt();
11371 for (int i=0; i<numTags; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -080011372 int idx = in.readInt();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011373 String str = in.readString();
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011374 if (str == null) {
11375 throw new ParcelFormatException("null history tag string");
11376 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011377 int uid = in.readInt();
11378 HistoryTag tag = new HistoryTag();
11379 tag.string = str;
11380 tag.uid = uid;
11381 tag.poolIdx = idx;
11382 mHistoryTagPool.put(tag, idx);
11383 if (idx >= mNextHistoryTagIdx) {
11384 mNextHistoryTagIdx = idx+1;
Dianne Hackborn099bc622014-01-22 13:39:16 -080011385 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011386 mNumHistoryTagChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -080011387 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011388
11389 int bufSize = in.readInt();
11390 int curPos = in.dataPosition();
11391 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011392 throw new ParcelFormatException("File corrupt: history data buffer too large " +
11393 bufSize);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011394 } else if ((bufSize&~3) != bufSize) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011395 throw new ParcelFormatException("File corrupt: history data buffer not aligned " +
11396 bufSize);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011397 } else {
11398 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
11399 + " bytes at " + curPos);
11400 mHistoryBuffer.appendFrom(in, curPos, bufSize);
11401 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011402 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011403
Dianne Hackbornae384452011-06-28 12:33:48 -070011404 if (andOldHistory) {
11405 readOldHistory(in);
11406 }
11407
11408 if (DEBUG_HISTORY) {
11409 StringBuilder sb = new StringBuilder(128);
11410 sb.append("****************** OLD mHistoryBaseTime: ");
11411 TimeUtils.formatDuration(mHistoryBaseTime, sb);
11412 Slog.i(TAG, sb.toString());
11413 }
11414 mHistoryBaseTime = historyBaseTime;
11415 if (DEBUG_HISTORY) {
11416 StringBuilder sb = new StringBuilder(128);
11417 sb.append("****************** NEW mHistoryBaseTime: ");
11418 TimeUtils.formatDuration(mHistoryBaseTime, sb);
11419 Slog.i(TAG, sb.toString());
11420 }
11421
11422 // We are just arbitrarily going to insert 1 minute from the sample of
11423 // the last run until samples in this run.
11424 if (mHistoryBaseTime > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -080011425 long oldnow = mClocks.elapsedRealtime();
Dianne Hackbornfdb19562014-07-11 16:03:36 -070011426 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1;
Dianne Hackbornae384452011-06-28 12:33:48 -070011427 if (DEBUG_HISTORY) {
11428 StringBuilder sb = new StringBuilder(128);
11429 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
11430 TimeUtils.formatDuration(mHistoryBaseTime, sb);
11431 Slog.i(TAG, sb.toString());
11432 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -070011433 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011434 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011435
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011436 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -070011437 if (!USE_OLD_HISTORY) {
11438 return;
11439 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011440 mHistory = mHistoryEnd = mHistoryCache = null;
11441 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -070011442 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011443 HistoryItem rec = new HistoryItem(time, in);
11444 addHistoryRecordLocked(rec);
11445 }
11446 }
11447
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011448 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) {
Dianne Hackbornae384452011-06-28 12:33:48 -070011449 if (DEBUG_HISTORY) {
11450 StringBuilder sb = new StringBuilder(128);
11451 sb.append("****************** WRITING mHistoryBaseTime: ");
11452 TimeUtils.formatDuration(mHistoryBaseTime, sb);
Dianne Hackborn40c87252014-03-19 16:55:40 -070011453 sb.append(" mLastHistoryElapsedRealtime: ");
11454 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
Dianne Hackbornae384452011-06-28 12:33:48 -070011455 Slog.i(TAG, sb.toString());
11456 }
Dianne Hackborn40c87252014-03-19 16:55:40 -070011457 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011458 if (!inclData) {
11459 out.writeInt(0);
11460 out.writeInt(0);
11461 return;
11462 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011463 out.writeInt(mHistoryTagPool.size());
11464 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
11465 HistoryTag tag = ent.getKey();
Dianne Hackborn099bc622014-01-22 13:39:16 -080011466 out.writeInt(ent.getValue());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011467 out.writeString(tag.string);
11468 out.writeInt(tag.uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -080011469 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011470 out.writeInt(mHistoryBuffer.dataSize());
11471 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
11472 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
11473 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -070011474
11475 if (andOldHistory) {
11476 writeOldHistory(out);
11477 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011478 }
11479
11480 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -070011481 if (!USE_OLD_HISTORY) {
11482 return;
11483 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011484 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011485 while (rec != null) {
11486 if (rec.time >= 0) rec.writeToParcel(out, 0);
11487 rec = rec.next;
11488 }
11489 out.writeLong(-1);
11490 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011491
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011492 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011493 final int version = in.readInt();
11494 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011495 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011496 + ", expected " + VERSION + "; erasing old stats");
11497 return;
11498 }
11499
Dianne Hackbornae384452011-06-28 12:33:48 -070011500 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011501
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011502 mStartCount = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011503 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011504 mRealtime = in.readLong();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -080011505 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -070011506 mStartPlatformVersion = in.readString();
11507 mEndPlatformVersion = in.readString();
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011508 mOnBatteryTimeBase.readSummaryFromParcel(in);
11509 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011510 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011511 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -070011512 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011513 mCurrentBatteryLevel = in.readInt();
Adam Lesinskif9b20a92016-06-17 17:30:01 -070011514 mEstimatedBatteryCapacity = in.readInt();
Jocelyn Dangc627d102017-04-14 13:15:14 -070011515 mMinLearnedBatteryCapacity = in.readInt();
11516 mMaxLearnedBatteryCapacity = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070011517 mLowDischargeAmountSinceCharge = in.readInt();
11518 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011519 mDischargeAmountScreenOnSinceCharge = in.readInt();
11520 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011521 mDischargeStepTracker.readFromParcel(in);
11522 mChargeStepTracker.readFromParcel(in);
11523 mDailyDischargeStepTracker.readFromParcel(in);
11524 mDailyChargeStepTracker.readFromParcel(in);
Adam Lesinski3ee3f632016-06-08 13:55:55 -070011525 mDischargeCounter.readSummaryFromParcelLocked(in);
11526 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070011527 int NPKG = in.readInt();
11528 if (NPKG > 0) {
11529 mDailyPackageChanges = new ArrayList<>(NPKG);
11530 while (NPKG > 0) {
11531 NPKG--;
11532 PackageChange pc = new PackageChange();
11533 pc.mPackageName = in.readString();
11534 pc.mUpdate = in.readInt() != 0;
11535 pc.mVersionCode = in.readInt();
11536 mDailyPackageChanges.add(pc);
11537 }
11538 } else {
11539 mDailyPackageChanges = null;
11540 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011541 mDailyStartTime = in.readLong();
11542 mNextMinDailyDeadline = in.readLong();
11543 mNextMaxDailyDeadline = in.readLong();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011545 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011546
Jeff Browne95c3cd2014-05-02 16:59:26 -070011547 mScreenState = Display.STATE_UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011548 mScreenOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -070011549 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
11550 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
11551 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070011552 mInteractive = false;
11553 mInteractiveTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011554 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070011555 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn08c47a52015-10-15 12:38:14 -070011556 mLongestLightIdleTime = in.readLong();
11557 mLongestFullIdleTime = in.readLong();
11558 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in);
11559 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in);
11560 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070011561 mDeviceIdlingTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011562 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -080011563 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -070011564 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
11565 }
Amith Yamasanif37447b2009-10-08 18:28:01 -070011566 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -070011567 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
11568 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
11569 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070011570 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080011571 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
11572 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070011573 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011574 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborne13c4c02014-02-11 17:18:35 -080011575 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn77b987f2014-02-26 16:20:52 -080011576 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011577 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
Dianne Hackbornd45665b2014-02-26 12:35:32 -080011578 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
11579 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
Dianne Hackborn0c820db2015-04-14 17:47:34 -070011580 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
The Android Open Source Project10592532009-03-18 17:39:46 -070011581 mWifiOn = false;
11582 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070011583 mGlobalWifiRunning = false;
11584 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -080011585 for (int i=0; i<NUM_WIFI_STATES; i++) {
11586 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
11587 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070011588 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
11589 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in);
11590 }
11591 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
11592 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
11593 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080011594 mWifiActivity.readSummaryFromParcel(in);
11595 mBluetoothActivity.readSummaryFromParcel(in);
11596 mModemActivity.readSummaryFromParcel(in);
11597 mHasWifiReporting = in.readInt() != 0;
11598 mHasBluetoothReporting = in.readInt() != 0;
11599 mHasModemReporting = in.readInt() != 0;
Adam Lesinski33dac552015-03-09 15:24:48 -070011600
Dianne Hackborn1e01d162014-12-04 17:46:42 -080011601 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
Ruben Brunk6d2c3632015-05-26 17:32:16 -070011602 mFlashlightOnNesting = 0;
Dianne Hackbornabc7c492014-06-30 16:57:46 -070011603 mFlashlightOnTimer.readSummaryFromParcelLocked(in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070011604 mCameraOnNesting = 0;
11605 mCameraOnTimer.readSummaryFromParcelLocked(in);
Adam Lesinski9f55cc72016-01-27 20:42:14 -080011606 mBluetoothScanNesting = 0;
11607 mBluetoothScanTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011608
Evan Millarc64edde2009-04-18 12:26:32 -070011609 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011610 if (NKW > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011611 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011612 }
Evan Millarc64edde2009-04-18 12:26:32 -070011613 for (int ikw = 0; ikw < NKW; ikw++) {
11614 if (in.readInt() != 0) {
11615 String kwltName = in.readString();
11616 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
11617 }
11618 }
Amith Yamasanie43530a2009-08-21 13:11:37 -070011619
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011620 int NWR = in.readInt();
11621 if (NWR > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011622 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011623 }
11624 for (int iwr = 0; iwr < NWR; iwr++) {
11625 if (in.readInt() != 0) {
11626 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070011627 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011628 }
11629 }
11630
James Carr3a226052016-07-01 14:49:52 -070011631 int NMS = in.readInt();
11632 for (int ims = 0; ims < NMS; ims++) {
11633 if (in.readInt() != 0) {
11634 long kmstName = in.readLong();
11635 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in);
11636 }
11637 }
11638
Sudheer Shanka9b735c52017-05-09 18:26:18 -070011639 mCpuFreqs = in.createLongArray();
11640
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011641 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011642 if (NU > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011643 throw new ParcelFormatException("File corrupt: too many uids " + NU);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011644 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011645 for (int iu = 0; iu < NU; iu++) {
11646 int uid = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -080011647 Uid u = new Uid(this, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011648 mUidStats.put(uid, u);
11649
Bookatz867c0d72017-03-07 18:23:42 -080011650 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in);
Bookatzc8c44962017-05-11 12:12:54 -070011651 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in);
Bookatz867c0d72017-03-07 18:23:42 -080011652
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070011653 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011654 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070011655 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011656 }
The Android Open Source Project10592532009-03-18 17:39:46 -070011657 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011658 if (in.readInt() != 0) {
11659 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
11660 }
Nick Pelly6ccaa542012-06-15 15:22:47 -070011661 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011662 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -070011663 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011664 }
Robert Greenwalta029ea12013-09-25 16:38:12 -070011665 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
11666 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
11667 if (in.readInt() != 0) {
11668 u.makeWifiBatchedScanBin(i, null);
11669 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
11670 }
11671 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -070011672 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011673 if (in.readInt() != 0) {
11674 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
11675 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011676 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -080011677 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011678 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011679 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -080011680 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
11681 }
11682 if (in.readInt() != 0) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -070011683 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
11684 }
11685 if (in.readInt() != 0) {
11686 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
11687 }
11688 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -070011689 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
11690 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -080011691 if (in.readInt() != 0) {
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -070011692 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in);
11693 }
11694 if (in.readInt() != 0) {
Bookatzc8c44962017-05-11 12:12:54 -070011695 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in);
11696 }
11697 if (in.readInt() != 0) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -080011698 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in);
11699 }
Bookatz956f36bf2017-04-28 09:48:17 -070011700 if (in.readInt() != 0) {
Bookatzb1f04f32017-05-19 13:57:32 -070011701 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in);
11702 }
11703 if (in.readInt() != 0) {
Bookatz956f36bf2017-04-28 09:48:17 -070011704 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in);
11705 }
Bookatzb1f04f32017-05-19 13:57:32 -070011706 if (in.readInt() != 0) {
11707 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in);
11708 }
Dianne Hackborna8d10942015-11-19 17:55:19 -080011709 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
Dianne Hackborn61659e52014-07-09 16:13:01 -070011710 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
11711 if (in.readInt() != 0) {
11712 u.makeProcessState(i, null);
11713 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in);
11714 }
11715 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -070011716 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -080011717 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011718 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -070011719
Dianne Hackborn617f8772009-03-31 15:04:46 -070011720 if (in.readInt() != 0) {
11721 if (u.mUserActivityCounters == null) {
11722 u.initUserActivityLocked();
11723 }
11724 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
11725 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
11726 }
11727 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011728
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070011729 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080011730 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070011731 u.initNetworkActivityLocked();
11732 }
11733 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080011734 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
11735 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070011736 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -080011737 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
11738 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070011739 }
11740
Adam Lesinski06af1fa2015-05-05 17:35:35 -070011741 u.mUserCpuTime.readSummaryFromParcelLocked(in);
11742 u.mSystemCpuTime.readSummaryFromParcelLocked(in);
11743
Adam Lesinski6832f392015-09-05 18:05:40 -070011744 if (in.readInt() != 0) {
11745 final int numClusters = in.readInt();
11746 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) {
11747 throw new ParcelFormatException("Incompatible cpu cluster arrangement");
Adam Lesinski06af1fa2015-05-05 17:35:35 -070011748 }
Adam Lesinski6832f392015-09-05 18:05:40 -070011749
11750 u.mCpuClusterSpeed = new LongSamplingCounter[numClusters][];
11751 for (int cluster = 0; cluster < numClusters; cluster++) {
Adam Lesinski6832f392015-09-05 18:05:40 -070011752 if (in.readInt() != 0) {
Adam Lesinskia57a5402015-09-28 10:21:33 -070011753 final int NSB = in.readInt();
11754 if (mPowerProfile != null &&
11755 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) {
11756 throw new ParcelFormatException("File corrupt: too many speed bins " +
11757 NSB);
11758 }
11759
Adam Lesinski6832f392015-09-05 18:05:40 -070011760 u.mCpuClusterSpeed[cluster] = new LongSamplingCounter[NSB];
11761 for (int speed = 0; speed < NSB; speed++) {
11762 if (in.readInt() != 0) {
11763 u.mCpuClusterSpeed[cluster][speed] = new LongSamplingCounter(
11764 mOnBatteryTimeBase);
11765 u.mCpuClusterSpeed[cluster][speed].readSummaryFromParcelLocked(in);
11766 }
11767 }
Adam Lesinskia57a5402015-09-28 10:21:33 -070011768 } else {
11769 u.mCpuClusterSpeed[cluster] = null;
Adam Lesinski6832f392015-09-05 18:05:40 -070011770 }
11771 }
11772 } else {
11773 u.mCpuClusterSpeed = null;
Adam Lesinski06af1fa2015-05-05 17:35:35 -070011774 }
11775
Sudheer Shanka59f5c002017-05-15 10:57:15 -070011776 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
11777 in, mOnBatteryTimeBase);
11778 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
11779 in, mOnBatteryScreenOffTimeBase);
Sudheer Shanka9b735c52017-05-09 18:26:18 -070011780
11781 if (in.readInt() != 0) {
Adam Lesinski5f056f62016-07-14 16:56:08 -070011782 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase);
11783 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in);
11784 } else {
11785 u.mMobileRadioApWakeupCount = null;
11786 }
11787
11788 if (in.readInt() != 0) {
11789 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase);
11790 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in);
11791 } else {
11792 u.mWifiRadioApWakeupCount = null;
11793 }
11794
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011795 int NW = in.readInt();
Dianne Hackborncb99a722016-10-03 17:00:02 -070011796 if (NW > (MAX_WAKELOCKS_PER_UID+1)) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011797 throw new ParcelFormatException("File corrupt: too many wake locks " + NW);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011798 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011799 for (int iw = 0; iw < NW; iw++) {
11800 String wlName = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -070011801 u.readWakeSummaryFromParcelLocked(wlName, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011802 }
11803
Dianne Hackbornfdb19562014-07-11 16:03:36 -070011804 int NS = in.readInt();
Dianne Hackborncb99a722016-10-03 17:00:02 -070011805 if (NS > (MAX_WAKELOCKS_PER_UID+1)) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011806 throw new ParcelFormatException("File corrupt: too many syncs " + NS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070011807 }
11808 for (int is = 0; is < NS; is++) {
11809 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -070011810 u.readSyncSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070011811 }
11812
11813 int NJ = in.readInt();
Dianne Hackborncb99a722016-10-03 17:00:02 -070011814 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011815 throw new ParcelFormatException("File corrupt: too many job timers " + NJ);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070011816 }
11817 for (int ij = 0; ij < NJ; ij++) {
11818 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -070011819 u.readJobSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070011820 }
11821
Dianne Hackborn94326cb2017-06-28 16:17:20 -070011822 u.readJobCompletionsFromParcelLocked(in);
11823
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011824 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -080011825 if (NP > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011826 throw new ParcelFormatException("File corrupt: too many sensors " + NP);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011827 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011828 for (int is = 0; is < NP; is++) {
11829 int seNumber = in.readInt();
11830 if (in.readInt() != 0) {
Bookatz867c0d72017-03-07 18:23:42 -080011831 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011832 }
11833 }
11834
11835 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -080011836 if (NP > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011837 throw new ParcelFormatException("File corrupt: too many processes " + NP);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011838 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011839 for (int ip = 0; ip < NP; ip++) {
11840 String procName = in.readString();
11841 Uid.Proc p = u.getProcessStatsLocked(procName);
11842 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011843 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -070011844 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011845 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -080011846 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt();
11847 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt();
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011848 p.readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011849 }
11850
11851 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011852 if (NP > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011853 throw new ParcelFormatException("File corrupt: too many packages " + NP);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011854 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011855 for (int ip = 0; ip < NP; ip++) {
11856 String pkgName = in.readString();
11857 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
Dianne Hackborn1e725a72015-03-24 18:23:19 -070011858 final int NWA = in.readInt();
11859 if (NWA > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011860 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA);
Dianne Hackborn1e725a72015-03-24 18:23:19 -070011861 }
11862 p.mWakeupAlarms.clear();
11863 for (int iwa=0; iwa<NWA; iwa++) {
11864 String tag = in.readString();
11865 Counter c = new Counter(mOnBatteryTimeBase);
11866 c.readSummaryFromParcelLocked(in);
11867 p.mWakeupAlarms.put(tag, c);
11868 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -070011869 NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -080011870 if (NS > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011871 throw new ParcelFormatException("File corrupt: too many services " + NS);
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -080011872 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011873 for (int is = 0; is < NS; is++) {
11874 String servName = in.readString();
11875 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
11876 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011877 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011878 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011879 }
11880 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011881 }
11882 }
11883
11884 /**
11885 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
11886 * disk. This format does not allow a lossless round-trip.
11887 *
11888 * @param out the Parcel to be written to.
11889 */
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011890 public void writeSummaryToParcel(Parcel out, boolean inclHistory) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -080011891 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011892
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070011893 // Pull the clock time. This may update the time and make a new history entry
11894 // if we had originally pulled a time before the RTC was set.
11895 long startClockTime = getStartClockTime();
11896
Joe Onoratoabded112016-02-08 16:49:39 -080011897 final long NOW_SYS = mClocks.uptimeMillis() * 1000;
11898 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011899
11900 out.writeInt(VERSION);
11901
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011902 writeHistory(out, inclHistory, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011903
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011904 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011905 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011906 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070011907 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -070011908 out.writeString(mStartPlatformVersion);
11909 out.writeString(mEndPlatformVersion);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011910 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
11911 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011912 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011913 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -070011914 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011915 out.writeInt(mCurrentBatteryLevel);
Adam Lesinskif9b20a92016-06-17 17:30:01 -070011916 out.writeInt(mEstimatedBatteryCapacity);
Jocelyn Dangc627d102017-04-14 13:15:14 -070011917 out.writeInt(mMinLearnedBatteryCapacity);
11918 out.writeInt(mMaxLearnedBatteryCapacity);
Dianne Hackborne4a59512010-12-07 11:08:07 -080011919 out.writeInt(getLowDischargeAmountSinceCharge());
11920 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011921 out.writeInt(getDischargeAmountScreenOnSinceCharge());
11922 out.writeInt(getDischargeAmountScreenOffSinceCharge());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011923 mDischargeStepTracker.writeToParcel(out);
11924 mChargeStepTracker.writeToParcel(out);
11925 mDailyDischargeStepTracker.writeToParcel(out);
11926 mDailyChargeStepTracker.writeToParcel(out);
Adam Lesinski67c134f2016-06-10 15:15:08 -070011927 mDischargeCounter.writeSummaryFromParcelLocked(out);
11928 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070011929 if (mDailyPackageChanges != null) {
11930 final int NPKG = mDailyPackageChanges.size();
11931 out.writeInt(NPKG);
11932 for (int i=0; i<NPKG; i++) {
11933 PackageChange pc = mDailyPackageChanges.get(i);
11934 out.writeString(pc.mPackageName);
11935 out.writeInt(pc.mUpdate ? 1 : 0);
11936 out.writeInt(pc.mVersionCode);
11937 }
11938 } else {
11939 out.writeInt(0);
11940 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011941 out.writeLong(mDailyStartTime);
11942 out.writeLong(mNextMinDailyDeadline);
11943 out.writeLong(mNextMaxDailyDeadline);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011944
11945 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -070011946 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011947 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -070011948 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070011949 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070011950 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn08c47a52015-10-15 12:38:14 -070011951 out.writeLong(mLongestLightIdleTime);
11952 out.writeLong(mLongestFullIdleTime);
11953 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
11954 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
11955 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070011956 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011957 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Wink Saville52840902011-02-18 12:40:47 -080011958 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011959 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -070011960 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011961 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -070011962 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011963 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -070011964 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070011965 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080011966 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
11967 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070011968 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011969 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
11970 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011971 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
Dianne Hackbornd45665b2014-02-26 12:35:32 -080011972 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
11973 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011974 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
11975 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -080011976 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011977 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -080011978 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070011979 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
11980 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
11981 }
11982 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
11983 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
11984 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080011985 mWifiActivity.writeSummaryToParcel(out);
11986 mBluetoothActivity.writeSummaryToParcel(out);
11987 mModemActivity.writeSummaryToParcel(out);
11988 out.writeInt(mHasWifiReporting ? 1 : 0);
11989 out.writeInt(mHasBluetoothReporting ? 1 : 0);
11990 out.writeInt(mHasModemReporting ? 1 : 0);
11991
Dianne Hackborn1e01d162014-12-04 17:46:42 -080011992 out.writeInt(mNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -070011993 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070011994 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Adam Lesinski9f55cc72016-01-27 20:42:14 -080011995 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011996
Evan Millarc64edde2009-04-18 12:26:32 -070011997 out.writeInt(mKernelWakelockStats.size());
11998 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
11999 Timer kwlt = ent.getValue();
12000 if (kwlt != null) {
12001 out.writeInt(1);
12002 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012003 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12004 } else {
12005 out.writeInt(0);
12006 }
12007 }
12008
12009 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070012010 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
12011 SamplingTimer timer = ent.getValue();
12012 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012013 out.writeInt(1);
12014 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070012015 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Evan Millarc64edde2009-04-18 12:26:32 -070012016 } else {
12017 out.writeInt(0);
12018 }
12019 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012020
James Carr3a226052016-07-01 14:49:52 -070012021 out.writeInt(mKernelMemoryStats.size());
12022 for (int i = 0; i < mKernelMemoryStats.size(); i++) {
12023 Timer kmt = mKernelMemoryStats.valueAt(i);
12024 if (kmt != null) {
12025 out.writeInt(1);
12026 out.writeLong(mKernelMemoryStats.keyAt(i));
12027 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12028 } else {
12029 out.writeInt(0);
12030 }
12031 }
12032
Sudheer Shanka9b735c52017-05-09 18:26:18 -070012033 out.writeLongArray(mCpuFreqs);
12034
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012035 final int NU = mUidStats.size();
12036 out.writeInt(NU);
12037 for (int iu = 0; iu < NU; iu++) {
12038 out.writeInt(mUidStats.keyAt(iu));
12039 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012040
Bookatz867c0d72017-03-07 18:23:42 -080012041 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Bookatzc8c44962017-05-11 12:12:54 -070012042 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Bookatz867c0d72017-03-07 18:23:42 -080012043
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070012044 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012045 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012046 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012047 } else {
12048 out.writeInt(0);
12049 }
12050 if (u.mFullWifiLockTimer != null) {
12051 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012052 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012053 } else {
12054 out.writeInt(0);
12055 }
Nick Pelly6ccaa542012-06-15 15:22:47 -070012056 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012057 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012058 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012059 } else {
12060 out.writeInt(0);
12061 }
Robert Greenwalta029ea12013-09-25 16:38:12 -070012062 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
12063 if (u.mWifiBatchedScanTimer[i] != null) {
12064 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012065 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Robert Greenwalta029ea12013-09-25 16:38:12 -070012066 } else {
12067 out.writeInt(0);
12068 }
12069 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012070 if (u.mWifiMulticastTimer != null) {
12071 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012072 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012073 } else {
12074 out.writeInt(0);
12075 }
12076 if (u.mAudioTurnedOnTimer != null) {
12077 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012078 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012079 } else {
12080 out.writeInt(0);
12081 }
12082 if (u.mVideoTurnedOnTimer != null) {
12083 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012084 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012085 } else {
12086 out.writeInt(0);
12087 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012088 if (u.mFlashlightTurnedOnTimer != null) {
12089 out.writeInt(1);
12090 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12091 } else {
12092 out.writeInt(0);
12093 }
12094 if (u.mCameraTurnedOnTimer != null) {
12095 out.writeInt(1);
12096 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12097 } else {
12098 out.writeInt(0);
12099 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -070012100 if (u.mForegroundActivityTimer != null) {
12101 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012102 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Jeff Sharkey3e013e82013-04-25 14:48:19 -070012103 } else {
12104 out.writeInt(0);
12105 }
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -070012106 if (u.mForegroundServiceTimer != null) {
12107 out.writeInt(1);
12108 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12109 } else {
12110 out.writeInt(0);
12111 }
Bookatzc8c44962017-05-11 12:12:54 -070012112 if (u.mAggregatedPartialWakelockTimer != null) {
12113 out.writeInt(1);
12114 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12115 } else {
12116 out.writeInt(0);
12117 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -080012118 if (u.mBluetoothScanTimer != null) {
12119 out.writeInt(1);
12120 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12121 } else {
12122 out.writeInt(0);
12123 }
Bookatzb1f04f32017-05-19 13:57:32 -070012124 if (u.mBluetoothUnoptimizedScanTimer != null) {
12125 out.writeInt(1);
12126 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12127 } else {
12128 out.writeInt(0);
12129 }
Bookatz956f36bf2017-04-28 09:48:17 -070012130 if (u.mBluetoothScanResultCounter != null) {
12131 out.writeInt(1);
12132 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out);
12133 } else {
12134 out.writeInt(0);
12135 }
Bookatzb1f04f32017-05-19 13:57:32 -070012136 if (u.mBluetoothScanResultBgCounter != null) {
12137 out.writeInt(1);
12138 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out);
12139 } else {
12140 out.writeInt(0);
12141 }
Dianne Hackborn61659e52014-07-09 16:13:01 -070012142 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
12143 if (u.mProcessStateTimer[i] != null) {
12144 out.writeInt(1);
12145 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12146 } else {
12147 out.writeInt(0);
12148 }
12149 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -080012150 if (u.mVibratorOnTimer != null) {
12151 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012152 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna06de0f2012-12-11 16:34:47 -080012153 } else {
12154 out.writeInt(0);
12155 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012156
Dianne Hackborn617f8772009-03-31 15:04:46 -070012157 if (u.mUserActivityCounters == null) {
12158 out.writeInt(0);
12159 } else {
12160 out.writeInt(1);
12161 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
12162 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
12163 }
12164 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012165
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080012166 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012167 out.writeInt(0);
12168 } else {
12169 out.writeInt(1);
12170 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080012171 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
12172 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012173 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -080012174 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
12175 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012176 }
12177
Adam Lesinski06af1fa2015-05-05 17:35:35 -070012178 u.mUserCpuTime.writeSummaryFromParcelLocked(out);
12179 u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
12180
Adam Lesinski6832f392015-09-05 18:05:40 -070012181 if (u.mCpuClusterSpeed != null) {
12182 out.writeInt(1);
12183 out.writeInt(u.mCpuClusterSpeed.length);
12184 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeed) {
12185 if (cpuSpeeds != null) {
12186 out.writeInt(1);
12187 out.writeInt(cpuSpeeds.length);
12188 for (LongSamplingCounter c : cpuSpeeds) {
12189 if (c != null) {
12190 out.writeInt(1);
12191 c.writeSummaryFromParcelLocked(out);
12192 } else {
12193 out.writeInt(0);
12194 }
12195 }
12196 } else {
12197 out.writeInt(0);
12198 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -070012199 }
Adam Lesinski6832f392015-09-05 18:05:40 -070012200 } else {
12201 out.writeInt(0);
Adam Lesinski06af1fa2015-05-05 17:35:35 -070012202 }
12203
Sudheer Shanka59f5c002017-05-15 10:57:15 -070012204 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs);
12205 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs);
Sudheer Shanka9b735c52017-05-09 18:26:18 -070012206
Adam Lesinski5f056f62016-07-14 16:56:08 -070012207 if (u.mMobileRadioApWakeupCount != null) {
12208 out.writeInt(1);
12209 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out);
12210 } else {
12211 out.writeInt(0);
12212 }
12213
12214 if (u.mWifiRadioApWakeupCount != null) {
12215 out.writeInt(1);
12216 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out);
12217 } else {
12218 out.writeInt(0);
12219 }
12220
Dianne Hackbornd953c532014-08-16 18:17:38 -070012221 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
12222 int NW = wakeStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012223 out.writeInt(NW);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012224 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -070012225 out.writeString(wakeStats.keyAt(iw));
12226 Uid.Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012227 if (wl.mTimerFull != null) {
12228 out.writeInt(1);
12229 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12230 } else {
12231 out.writeInt(0);
12232 }
12233 if (wl.mTimerPartial != null) {
12234 out.writeInt(1);
12235 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12236 } else {
12237 out.writeInt(0);
12238 }
12239 if (wl.mTimerWindow != null) {
12240 out.writeInt(1);
12241 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12242 } else {
12243 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012244 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -070012245 if (wl.mTimerDraw != null) {
Adam Lesinski9425fe22015-06-19 12:02:13 -070012246 out.writeInt(1);
Jeff Brown6a8bd7b2015-06-19 15:07:51 -070012247 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Adam Lesinski9425fe22015-06-19 12:02:13 -070012248 } else {
12249 out.writeInt(0);
12250 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012251 }
12252
Bookatz2bffb5b2017-04-13 11:59:33 -070012253 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -070012254 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012255 out.writeInt(NS);
12256 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -070012257 out.writeString(syncStats.keyAt(is));
12258 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012259 }
12260
Bookatzaa4594a2017-03-24 12:39:56 -070012261 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -070012262 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012263 out.writeInt(NJ);
12264 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -070012265 out.writeString(jobStats.keyAt(ij));
12266 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012267 }
12268
Dianne Hackborn94326cb2017-06-28 16:17:20 -070012269 u.writeJobCompletionsToParcelLocked(out);
12270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012271 int NSE = u.mSensorStats.size();
12272 out.writeInt(NSE);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012273 for (int ise=0; ise<NSE; ise++) {
12274 out.writeInt(u.mSensorStats.keyAt(ise));
12275 Uid.Sensor se = u.mSensorStats.valueAt(ise);
12276 if (se.mTimer != null) {
12277 out.writeInt(1);
12278 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12279 } else {
12280 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012281 }
12282 }
12283
12284 int NP = u.mProcessStats.size();
12285 out.writeInt(NP);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012286 for (int ip=0; ip<NP; ip++) {
12287 out.writeString(u.mProcessStats.keyAt(ip));
12288 Uid.Proc ps = u.mProcessStats.valueAt(ip);
12289 out.writeLong(ps.mUserTime);
12290 out.writeLong(ps.mSystemTime);
12291 out.writeLong(ps.mForegroundTime);
12292 out.writeInt(ps.mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -080012293 out.writeInt(ps.mNumCrashes);
12294 out.writeInt(ps.mNumAnrs);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012295 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012296 }
12297
12298 NP = u.mPackageStats.size();
12299 out.writeInt(NP);
12300 if (NP > 0) {
12301 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
12302 : u.mPackageStats.entrySet()) {
12303 out.writeString(ent.getKey());
12304 Uid.Pkg ps = ent.getValue();
Dianne Hackborn1e725a72015-03-24 18:23:19 -070012305 final int NWA = ps.mWakeupAlarms.size();
12306 out.writeInt(NWA);
12307 for (int iwa=0; iwa<NWA; iwa++) {
12308 out.writeString(ps.mWakeupAlarms.keyAt(iwa));
12309 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out);
12310 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012311 NS = ps.mServiceStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012312 out.writeInt(NS);
Dianne Hackborn1e725a72015-03-24 18:23:19 -070012313 for (int is=0; is<NS; is++) {
12314 out.writeString(ps.mServiceStats.keyAt(is));
12315 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
12316 long time = ss.getStartTimeToNowLocked(
12317 mOnBatteryTimeBase.getUptime(NOW_SYS));
12318 out.writeLong(time);
12319 out.writeInt(ss.mStarts);
12320 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012321 }
12322 }
12323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012324 }
12325 }
12326
12327 public void readFromParcel(Parcel in) {
12328 readFromParcelLocked(in);
12329 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012331 void readFromParcelLocked(Parcel in) {
12332 int magic = in.readInt();
12333 if (magic != MAGIC) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012334 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012335 }
12336
Dianne Hackbornae384452011-06-28 12:33:48 -070012337 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012339 mStartCount = in.readInt();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -080012340 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -070012341 mStartPlatformVersion = in.readString();
12342 mEndPlatformVersion = in.readString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012343 mUptime = in.readLong();
12344 mUptimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012345 mRealtime = in.readLong();
12346 mRealtimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012347 mOnBattery = in.readInt() != 0;
Adam Lesinskif9b20a92016-06-17 17:30:01 -070012348 mEstimatedBatteryCapacity = in.readInt();
Jocelyn Dangc627d102017-04-14 13:15:14 -070012349 mMinLearnedBatteryCapacity = in.readInt();
12350 mMaxLearnedBatteryCapacity = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012351 mOnBatteryInternal = false; // we are no longer really running.
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012352 mOnBatteryTimeBase.readFromParcel(in);
12353 mOnBatteryScreenOffTimeBase.readFromParcel(in);
12354
Jeff Browne95c3cd2014-05-02 16:59:26 -070012355 mScreenState = Display.STATE_UNKNOWN;
Joe Onoratoabded112016-02-08 16:49:39 -080012356 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012357 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012358 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null,
12359 mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012360 }
Dianne Hackborn29325132014-05-21 15:01:03 -070012361 mInteractive = false;
Joe Onoratoabded112016-02-08 16:49:39 -080012362 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012363 mPhoneOn = false;
Joe Onoratoabded112016-02-08 16:49:39 -080012364 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null,
12365 mOnBatteryTimeBase, in);
Dianne Hackborn08c47a52015-10-15 12:38:14 -070012366 mLongestLightIdleTime = in.readLong();
12367 mLongestFullIdleTime = in.readLong();
Joe Onoratoabded112016-02-08 16:49:39 -080012368 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null,
12369 mOnBatteryTimeBase, in);
12370 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null,
12371 mOnBatteryTimeBase, in);
12372 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null,
12373 mOnBatteryTimeBase, in);
12374 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in);
12375 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012376 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012377 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i,
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012378 null, mOnBatteryTimeBase, in);
12379 }
Joe Onoratoabded112016-02-08 16:49:39 -080012380 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null,
12381 mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012382 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012383 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i,
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012384 null, mOnBatteryTimeBase, in);
12385 }
12386 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
12387 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
12388 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
12389 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012390 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Joe Onoratoabded112016-02-08 16:49:39 -080012391 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null,
12392 mOnBatteryTimeBase, in);
12393 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null,
12394 mOnBatteryTimeBase, in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012395 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012396 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
12397 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn0c820db2015-04-14 17:47:34 -070012398 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012399 mWifiOn = false;
Joe Onoratoabded112016-02-08 16:49:39 -080012400 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012401 mGlobalWifiRunning = false;
Joe Onoratoabded112016-02-08 16:49:39 -080012402 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null,
12403 mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012404 for (int i=0; i<NUM_WIFI_STATES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012405 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i,
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012406 null, mOnBatteryTimeBase, in);
12407 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070012408 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012409 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i,
Dianne Hackborn3251b902014-06-20 14:40:53 -070012410 null, mOnBatteryTimeBase, in);
12411 }
12412 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012413 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i,
Dianne Hackborn3251b902014-06-20 14:40:53 -070012414 null, mOnBatteryTimeBase, in);
12415 }
Adam Lesinski33dac552015-03-09 15:24:48 -070012416
Adam Lesinski21f76aa2016-01-25 12:27:06 -080012417 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
12418 NUM_WIFI_TX_LEVELS, in);
12419 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
12420 NUM_BT_TX_LEVELS, in);
12421 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
12422 ModemActivityInfo.TX_POWER_LEVELS, in);
12423 mHasWifiReporting = in.readInt() != 0;
12424 mHasBluetoothReporting = in.readInt() != 0;
12425 mHasModemReporting = in.readInt() != 0;
12426
Dianne Hackborn1e01d162014-12-04 17:46:42 -080012427 mNumConnectivityChange = in.readInt();
12428 mLoadedNumConnectivityChange = in.readInt();
12429 mUnpluggedNumConnectivityChange = in.readInt();
Dianne Hackborn10eaa852014-07-22 22:54:55 -070012430 mAudioOnNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080012431 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase);
Dianne Hackborn10eaa852014-07-22 22:54:55 -070012432 mVideoOnNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080012433 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012434 mFlashlightOnNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080012435 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012436 mCameraOnNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080012437 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in);
Adam Lesinski9f55cc72016-01-27 20:42:14 -080012438 mBluetoothScanNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080012439 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012440 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012441 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -070012442 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012443 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012444 mLowDischargeAmountSinceCharge = in.readInt();
12445 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080012446 mDischargeAmountScreenOn = in.readInt();
12447 mDischargeAmountScreenOnSinceCharge = in.readInt();
12448 mDischargeAmountScreenOff = in.readInt();
12449 mDischargeAmountScreenOffSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080012450 mDischargeStepTracker.readFromParcel(in);
12451 mChargeStepTracker.readFromParcel(in);
Adam Lesinski3ee3f632016-06-08 13:55:55 -070012452 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
12453 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012454 mLastWriteTime = in.readLong();
12455
Evan Millarc64edde2009-04-18 12:26:32 -070012456 mKernelWakelockStats.clear();
12457 int NKW = in.readInt();
12458 for (int ikw = 0; ikw < NKW; ikw++) {
12459 if (in.readInt() != 0) {
12460 String wakelockName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -080012461 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -070012462 mKernelWakelockStats.put(wakelockName, kwlt);
12463 }
12464 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012465
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012466 mWakeupReasonStats.clear();
12467 int NWR = in.readInt();
12468 for (int iwr = 0; iwr < NWR; iwr++) {
12469 if (in.readInt() != 0) {
12470 String reasonName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -080012471 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in);
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070012472 mWakeupReasonStats.put(reasonName, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012473 }
12474 }
12475
James Carr3a226052016-07-01 14:49:52 -070012476 mKernelMemoryStats.clear();
12477 int nmt = in.readInt();
12478 for (int imt = 0; imt < nmt; imt++) {
12479 if (in.readInt() != 0) {
12480 Long bucket = in.readLong();
12481 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in);
12482 mKernelMemoryStats.put(bucket, kmt);
12483 }
12484 }
12485
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012486 mPartialTimers.clear();
12487 mFullTimers.clear();
12488 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070012489 mWifiRunningTimers.clear();
12490 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -070012491 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -070012492 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070012493 mWifiMulticastTimers.clear();
Dianne Hackborn10eaa852014-07-22 22:54:55 -070012494 mAudioTurnedOnTimers.clear();
12495 mVideoTurnedOnTimers.clear();
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012496 mFlashlightTurnedOnTimers.clear();
12497 mCameraTurnedOnTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012498
Sudheer Shanka9b735c52017-05-09 18:26:18 -070012499 mCpuFreqs = in.createLongArray();
12500
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012501 int numUids = in.readInt();
12502 mUidStats.clear();
12503 for (int i = 0; i < numUids; i++) {
12504 int uid = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -080012505 Uid u = new Uid(this, uid);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012506 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012507 mUidStats.append(uid, u);
12508 }
12509 }
12510
12511 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012512 writeToParcelLocked(out, true, flags);
12513 }
12514
12515 public void writeToParcelWithoutUids(Parcel out, int flags) {
12516 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012517 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012518
12519 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012520 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070012521 // Need to update with current kernel wake lock counts.
Dianne Hackborna7c837f2014-01-15 16:20:44 -080012522 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070012523
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070012524 // Pull the clock time. This may update the time and make a new history entry
12525 // if we had originally pulled a time before the RTC was set.
12526 long startClockTime = getStartClockTime();
12527
Joe Onoratoabded112016-02-08 16:49:39 -080012528 final long uSecUptime = mClocks.uptimeMillis() * 1000;
12529 final long uSecRealtime = mClocks.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012530 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
12531 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012532
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012533 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012534
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070012535 writeHistory(out, true, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012536
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012537 out.writeInt(mStartCount);
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070012538 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -070012539 out.writeString(mStartPlatformVersion);
12540 out.writeString(mEndPlatformVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012541 out.writeLong(mUptime);
12542 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012543 out.writeLong(mRealtime);
12544 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012545 out.writeInt(mOnBattery ? 1 : 0);
Adam Lesinskif9b20a92016-06-17 17:30:01 -070012546 out.writeInt(mEstimatedBatteryCapacity);
Jocelyn Dangc627d102017-04-14 13:15:14 -070012547 out.writeInt(mMinLearnedBatteryCapacity);
12548 out.writeInt(mMaxLearnedBatteryCapacity);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012549 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
12550 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
12551
12552 mScreenOnTimer.writeToParcel(out, uSecRealtime);
12553 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
12554 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
12555 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070012556 mInteractiveTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070012557 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn08c47a52015-10-15 12:38:14 -070012558 out.writeLong(mLongestLightIdleTime);
12559 out.writeLong(mLongestFullIdleTime);
12560 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime);
12561 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime);
12562 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070012563 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012564 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
12565 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
12566 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
12567 }
12568 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
12569 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
12570 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
12571 }
12572 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
12573 mNetworkByteActivityCounters[i].writeToParcel(out);
12574 mNetworkPacketActivityCounters[i].writeToParcel(out);
12575 }
12576 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
12577 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012578 mMobileRadioActiveAdjustedTime.writeToParcel(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012579 mMobileRadioActiveUnknownTime.writeToParcel(out);
12580 mMobileRadioActiveUnknownCount.writeToParcel(out);
12581 mWifiOnTimer.writeToParcel(out, uSecRealtime);
12582 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
12583 for (int i=0; i<NUM_WIFI_STATES; i++) {
12584 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
12585 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070012586 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
12587 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime);
12588 }
12589 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
12590 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
12591 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080012592 mWifiActivity.writeToParcel(out, 0);
12593 mBluetoothActivity.writeToParcel(out, 0);
12594 mModemActivity.writeToParcel(out, 0);
12595 out.writeInt(mHasWifiReporting ? 1 : 0);
12596 out.writeInt(mHasBluetoothReporting ? 1 : 0);
12597 out.writeInt(mHasModemReporting ? 1 : 0);
12598
Dianne Hackborn1e01d162014-12-04 17:46:42 -080012599 out.writeInt(mNumConnectivityChange);
12600 out.writeInt(mLoadedNumConnectivityChange);
12601 out.writeInt(mUnpluggedNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -070012602 mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012603 mCameraOnTimer.writeToParcel(out, uSecRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -080012604 mBluetoothScanTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012605 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012606 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -070012607 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012608 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012609 out.writeInt(mLowDischargeAmountSinceCharge);
12610 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080012611 out.writeInt(mDischargeAmountScreenOn);
12612 out.writeInt(mDischargeAmountScreenOnSinceCharge);
12613 out.writeInt(mDischargeAmountScreenOff);
12614 out.writeInt(mDischargeAmountScreenOffSinceCharge);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080012615 mDischargeStepTracker.writeToParcel(out);
12616 mChargeStepTracker.writeToParcel(out);
Adam Lesinski3ee3f632016-06-08 13:55:55 -070012617 mDischargeCounter.writeToParcel(out);
12618 mDischargeScreenOffCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012619 out.writeLong(mLastWriteTime);
12620
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012621 if (inclUids) {
12622 out.writeInt(mKernelWakelockStats.size());
12623 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
12624 SamplingTimer kwlt = ent.getValue();
12625 if (kwlt != null) {
12626 out.writeInt(1);
12627 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012628 kwlt.writeToParcel(out, uSecRealtime);
12629 } else {
12630 out.writeInt(0);
12631 }
12632 }
12633 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070012634 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
12635 SamplingTimer timer = ent.getValue();
12636 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012637 out.writeInt(1);
12638 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070012639 timer.writeToParcel(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012640 } else {
12641 out.writeInt(0);
12642 }
Evan Millarc64edde2009-04-18 12:26:32 -070012643 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012644 } else {
12645 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -070012646 }
Amith Yamasanie43530a2009-08-21 13:11:37 -070012647
James Carr3a226052016-07-01 14:49:52 -070012648 out.writeInt(mKernelMemoryStats.size());
12649 for (int i = 0; i < mKernelMemoryStats.size(); i++) {
12650 SamplingTimer kmt = mKernelMemoryStats.valueAt(i);
12651 if (kmt != null) {
12652 out.writeInt(1);
12653 out.writeLong(mKernelMemoryStats.keyAt(i));
12654 kmt.writeToParcel(out, uSecRealtime);
12655 } else {
12656 out.writeInt(0);
12657 }
12658 }
12659
Sudheer Shanka9b735c52017-05-09 18:26:18 -070012660 out.writeLongArray(mCpuFreqs);
12661
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012662 if (inclUids) {
12663 int size = mUidStats.size();
12664 out.writeInt(size);
12665 for (int i = 0; i < size; i++) {
12666 out.writeInt(mUidStats.keyAt(i));
12667 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012668
Bookatz867c0d72017-03-07 18:23:42 -080012669 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012670 }
12671 } else {
12672 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012673 }
12674 }
12675
12676 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
12677 new Parcelable.Creator<BatteryStatsImpl>() {
12678 public BatteryStatsImpl createFromParcel(Parcel in) {
12679 return new BatteryStatsImpl(in);
12680 }
12681
12682 public BatteryStatsImpl[] newArray(int size) {
12683 return new BatteryStatsImpl[size];
12684 }
12685 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012686
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070012687 public void prepareForDumpLocked() {
12688 // Need to retrieve current kernel wake lock stats before printing.
Dianne Hackborna7c837f2014-01-15 16:20:44 -080012689 pullPendingStateUpdatesLocked();
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070012690
12691 // Pull the clock time. This may update the time and make a new history entry
12692 // if we had originally pulled a time before the RTC was set.
12693 getStartClockTime();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070012694 }
12695
Dianne Hackbornc51cf032014-03-02 19:08:15 -080012696 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012697 if (DEBUG) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012698 pw.println("mOnBatteryTimeBase:");
12699 mOnBatteryTimeBase.dump(pw, " ");
12700 pw.println("mOnBatteryScreenOffTimeBase:");
12701 mOnBatteryScreenOffTimeBase.dump(pw, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070012702 Printer pr = new PrintWriterPrinter(pw);
12703 pr.println("*** Screen timer:");
12704 mScreenOnTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -070012705 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070012706 pr.println("*** Screen brightness #" + i + ":");
12707 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -070012708 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070012709 pr.println("*** Interactive timer:");
12710 mInteractiveTimer.logState(pr, " ");
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070012711 pr.println("*** Power save mode timer:");
12712 mPowerSaveModeEnabledTimer.logState(pr, " ");
Dianne Hackborn08c47a52015-10-15 12:38:14 -070012713 pr.println("*** Device idle mode light timer:");
12714 mDeviceIdleModeLightTimer.logState(pr, " ");
12715 pr.println("*** Device idle mode full timer:");
12716 mDeviceIdleModeFullTimer.logState(pr, " ");
12717 pr.println("*** Device light idling timer:");
12718 mDeviceLightIdlingTimer.logState(pr, " ");
Dianne Hackborn88e98df2015-03-23 13:29:14 -070012719 pr.println("*** Device idling timer:");
12720 mDeviceIdlingTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070012721 pr.println("*** Phone timer:");
12722 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -080012723 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3251b902014-06-20 14:40:53 -070012724 pr.println("*** Phone signal strength #" + i + ":");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070012725 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -070012726 }
Amith Yamasanif37447b2009-10-08 18:28:01 -070012727 pr.println("*** Signal scanning :");
12728 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -070012729 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070012730 pr.println("*** Data connection type #" + i + ":");
12731 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -070012732 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012733 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState);
Dianne Hackborne13c4c02014-02-11 17:18:35 -080012734 pr.println("*** Mobile network active timer:");
12735 mMobileRadioActiveTimer.logState(pr, " ");
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012736 pr.println("*** Mobile network active adjusted timer:");
12737 mMobileRadioActiveAdjustedTime.logState(pr, " ");
Dianne Hackborn0c820db2015-04-14 17:47:34 -070012738 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070012739 pr.println("*** Wifi timer:");
12740 mWifiOnTimer.logState(pr, " ");
12741 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070012742 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -080012743 for (int i=0; i<NUM_WIFI_STATES; i++) {
12744 pr.println("*** Wifi state #" + i + ":");
12745 mWifiStateTimer[i].logState(pr, " ");
12746 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070012747 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
12748 pr.println("*** Wifi suppl state #" + i + ":");
12749 mWifiSupplStateTimer[i].logState(pr, " ");
12750 }
12751 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
12752 pr.println("*** Wifi signal strength #" + i + ":");
12753 mWifiSignalStrengthsTimer[i].logState(pr, " ");
12754 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -070012755 pr.println("*** Flashlight timer:");
12756 mFlashlightOnTimer.logState(pr, " ");
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012757 pr.println("*** Camera timer:");
12758 mCameraOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012759 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -080012760 super.dumpLocked(context, pw, flags, reqUid, histStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012761 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012762}