blob: 7e52d2af9595b7bef628edea8cf46c7525893ce9 [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;
Bookatzc1a050a2017-10-10 15:49:28 -070066import android.util.StatsLog;
Dianne Hackbornae384452011-06-28 12:33:48 -070067import android.util.TimeUtils;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080068import android.util.Xml;
Jeff Browne95c3cd2014-05-02 16:59:26 -070069import android.view.Display;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080070
Adam Lesinski14ae39a2017-05-26 11:50:40 -070071import com.android.internal.annotations.GuardedBy;
Adam Lesinski98f0d462016-04-19 16:46:20 -070072import com.android.internal.annotations.VisibleForTesting;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070073import com.android.internal.net.NetworkStatsFactory;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080074import com.android.internal.util.ArrayUtils;
Dianne Hackborn8c841092013-06-24 13:46:13 -070075import com.android.internal.util.FastPrintWriter;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080076import com.android.internal.util.FastXmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070077import com.android.internal.util.JournaledFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080078import com.android.internal.util.XmlUtils;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070079
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070080import libcore.util.EmptyArray;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080081import org.xmlpull.v1.XmlPullParser;
82import org.xmlpull.v1.XmlPullParserException;
83import org.xmlpull.v1.XmlSerializer;
Jeff Sharkey1059c3c2011-10-04 16:54:49 -070084
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080085import java.io.ByteArrayOutputStream;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080086import java.io.File;
87import java.io.FileInputStream;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080088import java.io.FileNotFoundException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import java.io.FileOutputStream;
90import java.io.IOException;
Dianne Hackborn1d442e02009-04-20 18:14:05 -070091import java.io.PrintWriter;
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +010092import java.nio.charset.StandardCharsets;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import java.util.ArrayList;
Sudheer Shanka9b735c52017-05-09 18:26:18 -070094import java.util.Arrays;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080095import java.util.Calendar;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080096import java.util.HashMap;
Evan Millarc64edde2009-04-18 12:26:32 -070097import java.util.Iterator;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080098import java.util.Map;
Adam Lesinskib3a1bad2017-05-26 11:50:40 -070099import java.util.concurrent.Future;
Christopher Tate4cee7252010-03-19 14:50:40 -0700100import java.util.concurrent.atomic.AtomicInteger;
Dianne Hackbornce2ef762010-09-20 11:39:14 -0700101import java.util.concurrent.locks.ReentrantLock;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800102
103/**
104 * All information we are collecting about things that can happen that impact
105 * battery life. All times are represented in microseconds except where indicated
106 * otherwise.
107 */
Joe Onoratoabded112016-02-08 16:49:39 -0800108public class BatteryStatsImpl extends BatteryStats {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800109 private static final String TAG = "BatteryStatsImpl";
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800110 private static final boolean DEBUG = false;
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700111 public static final boolean DEBUG_ENERGY = false;
Adam Lesinski50e47602015-12-04 17:04:54 -0800112 private static final boolean DEBUG_ENERGY_CPU = DEBUG_ENERGY;
James Carr3a226052016-07-01 14:49:52 -0700113 private static final boolean DEBUG_MEMORY = false;
Dianne Hackborn32907cf2010-06-10 17:50:20 -0700114 private static final boolean DEBUG_HISTORY = false;
Dianne Hackborne8c88e62011-08-17 19:09:09 -0700115 private static final boolean USE_OLD_HISTORY = false; // for debugging.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700116
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700117 // TODO: remove "tcp" from network methods, since we measure total stats.
118
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800119 // In-memory Parcel magic number, used to detect attempts to unmarshall bad data
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700120 private static final int MAGIC = 0xBA757475; // 'BATSTATS'
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800121
122 // Current on-disk Parcel version
Bookatzba78b2b2017-10-10 11:06:33 -0700123 private static final int VERSION = 168 + (USE_OLD_HISTORY ? 1000 : 0);
Amith Yamasanie43530a2009-08-21 13:11:37 -0700124
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700125 // Maximum number of items we will record in the history.
Narayan Kamathb59b7c32017-06-12 14:11:03 +0100126 private static final int MAX_HISTORY_ITEMS;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700127
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700128 // No, really, THIS is the maximum number of items we will record in the history.
Narayan Kamathb59b7c32017-06-12 14:11:03 +0100129 private static final int MAX_MAX_HISTORY_ITEMS;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -0700130
Dianne Hackborn9e0f5d92010-02-22 15:05:42 -0800131 // The maximum number of names wakelocks we will keep track of
132 // per uid; once the limit is reached, we batch the remaining wakelocks
133 // in to one common name.
Narayan Kamathb59b7c32017-06-12 14:11:03 +0100134 private static final int MAX_WAKELOCKS_PER_UID;
135
136 static final int MAX_HISTORY_BUFFER; // 256KB
137 static final int MAX_MAX_HISTORY_BUFFER; // 320KB
138
139 static {
140 if (ActivityManager.isLowRamDeviceStatic()) {
141 MAX_HISTORY_ITEMS = 800;
142 MAX_MAX_HISTORY_ITEMS = 1200;
143 MAX_WAKELOCKS_PER_UID = 40;
144 MAX_HISTORY_BUFFER = 96*1024; // 96KB
145 MAX_MAX_HISTORY_BUFFER = 128*1024; // 128KB
146 } else {
147 MAX_HISTORY_ITEMS = 2000;
148 MAX_MAX_HISTORY_ITEMS = 3000;
149 MAX_WAKELOCKS_PER_UID = 100;
150 MAX_HISTORY_BUFFER = 256*1024; // 256KB
151 MAX_MAX_HISTORY_BUFFER = 320*1024; // 256KB
152 }
153 }
Dianne Hackbornc24ab862011-10-18 15:55:03 -0700154
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800155 // Number of transmit power states the Wifi controller can be in.
156 private static final int NUM_WIFI_TX_LEVELS = 1;
157
158 // Number of transmit power states the Bluetooth controller can be in.
159 private static final int NUM_BT_TX_LEVELS = 1;
160
Sudheer Shanka38383232017-07-25 09:55:03 -0700161 /**
162 * Holding a wakelock costs more than just using the cpu.
163 * Currently, we assign only half the cpu time to an app that is running but
164 * not holding a wakelock. The apps holding wakelocks get the rest of the blame.
165 * If no app is holding a wakelock, then the distribution is normal.
166 */
167 @VisibleForTesting
168 public static final int WAKE_LOCK_WEIGHT = 50;
169
Joe Onoratoabded112016-02-08 16:49:39 -0800170 protected Clocks mClocks;
171
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700172 private final JournaledFile mFile;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700173 public final AtomicFile mCheckinFile;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800174 public final AtomicFile mDailyFile;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800175
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700176 static final int MSG_UPDATE_WAKELOCKS = 1;
177 static final int MSG_REPORT_POWER_CHANGE = 2;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700178 static final int MSG_REPORT_CHARGING = 3;
Dianne Hackborn287952c2010-09-22 22:34:31 -0700179 static final long DELAY_UPDATE_WAKELOCKS = 5*1000;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700180
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700181 private final KernelWakelockReader mKernelWakelockReader = new KernelWakelockReader();
182 private final KernelWakelockStats mTmpWakelockStats = new KernelWakelockStats();
183
Sudheer Shanka38383232017-07-25 09:55:03 -0700184 @VisibleForTesting
185 protected KernelUidCpuTimeReader mKernelUidCpuTimeReader = new KernelUidCpuTimeReader();
186 @VisibleForTesting
187 protected KernelCpuSpeedReader[] mKernelCpuSpeedReaders;
188 @VisibleForTesting
189 protected KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader =
Sudheer Shanka9b735c52017-05-09 18:26:18 -0700190 new KernelUidCpuFreqTimeReader();
Adam Lesinski06af1fa2015-05-05 17:35:35 -0700191
James Carr3a226052016-07-01 14:49:52 -0700192 private final KernelMemoryBandwidthStats mKernelMemoryBandwidthStats
193 = new KernelMemoryBandwidthStats();
194 private final LongSparseArray<SamplingTimer> mKernelMemoryStats = new LongSparseArray<>();
195 public LongSparseArray<SamplingTimer> getKernelMemoryStats() {
196 return mKernelMemoryStats;
197 }
198
Bookatz0b8a0502017-09-13 11:51:52 -0700199 /** Container for Resource Power Manager stats. Updated by updateRpmStatsLocked. */
Bookatz50df7112017-08-04 14:53:26 -0700200 private final RpmStats mTmpRpmStats = new RpmStats();
Bookatz0b8a0502017-09-13 11:51:52 -0700201 /** The soonest the RPM stats can be updated after it was last updated. */
202 private static final long RPM_STATS_UPDATE_FREQ_MS = 1000;
203 /** Last time that RPM stats were updated by updateRpmStatsLocked. */
204 private long mLastRpmStatsUpdateTimeMs = -RPM_STATS_UPDATE_FREQ_MS;
Bookatz50df7112017-08-04 14:53:26 -0700205
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700206 public interface BatteryCallback {
207 public void batteryNeedsCpuUpdate();
208 public void batteryPowerChanged(boolean onBattery);
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700209 public void batterySendBroadcast(Intent intent);
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700210 }
211
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700212 public interface PlatformIdleStateCallback {
Bookatz50df7112017-08-04 14:53:26 -0700213 public void fillLowPowerStats(RpmStats rpmStats);
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700214 public String getPlatformLowPowerStats();
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +0000215 public String getSubsystemLowPowerStats();
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700216 }
217
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700218 public static abstract class UserInfoProvider {
219 private int[] userIds;
220 protected abstract @Nullable int[] getUserIds();
Sudheer Shanka38383232017-07-25 09:55:03 -0700221 @VisibleForTesting
222 public final void refreshUserIds() {
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700223 userIds = getUserIds();
224 }
Sudheer Shanka38383232017-07-25 09:55:03 -0700225 @VisibleForTesting
226 public boolean exists(int userId) {
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700227 return userIds != null ? ArrayUtils.contains(userIds, userId) : true;
228 }
229 }
230
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700231 private final PlatformIdleStateCallback mPlatformIdleStateCallback;
232
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700233 final class MyHandler extends Handler {
Jeff Brown6f357d32014-01-15 20:40:55 -0800234 public MyHandler(Looper looper) {
235 super(looper, null, true);
236 }
237
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700238 @Override
239 public void handleMessage(Message msg) {
240 BatteryCallback cb = mCallback;
241 switch (msg.what) {
242 case MSG_UPDATE_WAKELOCKS:
Adam Lesinski72478f02015-06-17 15:39:43 -0700243 synchronized (BatteryStatsImpl.this) {
Sudheer Shankab8ad5942017-08-08 12:16:09 -0700244 updateCpuTimeLocked();
Adam Lesinski72478f02015-06-17 15:39:43 -0700245 }
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700246 if (cb != null) {
247 cb.batteryNeedsCpuUpdate();
248 }
249 break;
250 case MSG_REPORT_POWER_CHANGE:
251 if (cb != null) {
252 cb.batteryPowerChanged(msg.arg1 != 0);
253 }
254 break;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700255 case MSG_REPORT_CHARGING:
256 if (cb != null) {
257 final String action;
258 synchronized (BatteryStatsImpl.this) {
259 action = mCharging ? BatteryManager.ACTION_CHARGING
260 : BatteryManager.ACTION_DISCHARGING;
261 }
262 Intent intent = new Intent(action);
263 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
264 cb.batterySendBroadcast(intent);
265 }
266 break;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700267 }
268 }
269 }
270
Joe Onoratoabded112016-02-08 16:49:39 -0800271 public interface Clocks {
272 public long elapsedRealtime();
273 public long uptimeMillis();
274 }
275
276 public static class SystemClocks implements Clocks {
277 public long elapsedRealtime() {
278 return SystemClock.elapsedRealtime();
279 }
280
281 public long uptimeMillis() {
282 return SystemClock.uptimeMillis();
283 }
284 }
285
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700286 public interface ExternalStatsSync {
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700287 int UPDATE_CPU = 0x01;
288 int UPDATE_WIFI = 0x02;
289 int UPDATE_RADIO = 0x04;
290 int UPDATE_BT = 0x08;
Bookatz50df7112017-08-04 14:53:26 -0700291 int UPDATE_RPM = 0x10; // 16
292 int UPDATE_ALL = UPDATE_CPU | UPDATE_WIFI | UPDATE_RADIO | UPDATE_BT | UPDATE_RPM;
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800293
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700294 Future<?> scheduleSync(String reason, int flags);
295 Future<?> scheduleCpuSyncDueToRemovedUid(int uid);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700296 }
297
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700298 public final MyHandler mHandler;
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700299 private ExternalStatsSync mExternalSync = null;
Sudheer Shanka38383232017-07-25 09:55:03 -0700300 @VisibleForTesting
301 protected UserInfoProvider mUserInfoProvider = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700302
303 private BatteryCallback mCallback;
304
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800305 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -0800306 * Mapping isolated uids to the actual owning app uid.
307 */
308 final SparseIntArray mIsolatedUids = new SparseIntArray();
309
310 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800311 * The statistics we have collected organized by uids.
312 */
Adam Lesinski50e47602015-12-04 17:04:54 -0800313 final SparseArray<BatteryStatsImpl.Uid> mUidStats = new SparseArray<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314
315 // A set of pools of currently active timers. When a timer is queried, we will divide the
316 // elapsed time by the number of active timers to arrive at that timer's share of the time.
317 // In order to do this, we must refresh each timer whenever the number of active timers
318 // changes.
Sudheer Shanka38383232017-07-25 09:55:03 -0700319 @VisibleForTesting
320 protected ArrayList<StopwatchTimer> mPartialTimers = new ArrayList<>();
Adam Lesinskie08af192015-03-25 16:42:59 -0700321 final ArrayList<StopwatchTimer> mFullTimers = new ArrayList<>();
322 final ArrayList<StopwatchTimer> mWindowTimers = new ArrayList<>();
Jeff Brown6a8bd7b2015-06-19 15:07:51 -0700323 final ArrayList<StopwatchTimer> mDrawTimers = new ArrayList<>();
Adam Lesinskie08af192015-03-25 16:42:59 -0700324 final SparseArray<ArrayList<StopwatchTimer>> mSensorTimers = new SparseArray<>();
325 final ArrayList<StopwatchTimer> mWifiRunningTimers = new ArrayList<>();
326 final ArrayList<StopwatchTimer> mFullWifiLockTimers = new ArrayList<>();
327 final ArrayList<StopwatchTimer> mWifiMulticastTimers = new ArrayList<>();
328 final ArrayList<StopwatchTimer> mWifiScanTimers = new ArrayList<>();
329 final SparseArray<ArrayList<StopwatchTimer>> mWifiBatchedScanTimers = new SparseArray<>();
330 final ArrayList<StopwatchTimer> mAudioTurnedOnTimers = new ArrayList<>();
331 final ArrayList<StopwatchTimer> mVideoTurnedOnTimers = new ArrayList<>();
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700332 final ArrayList<StopwatchTimer> mFlashlightTurnedOnTimers = new ArrayList<>();
333 final ArrayList<StopwatchTimer> mCameraTurnedOnTimers = new ArrayList<>();
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800334 final ArrayList<StopwatchTimer> mBluetoothScanOnTimers = new ArrayList<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700336 // Last partial timers we use for distributing CPU usage.
Sudheer Shanka38383232017-07-25 09:55:03 -0700337 @VisibleForTesting
338 protected ArrayList<StopwatchTimer> mLastPartialTimers = new ArrayList<>();
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700339
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 // These are the objects that will want to do something when the device
341 // is unplugged from power.
Joe Onoratoabded112016-02-08 16:49:39 -0800342 protected final TimeBase mOnBatteryTimeBase = new TimeBase();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800343
344 // These are the objects that will want to do something when the device
Mike Mac2f518a2017-09-19 16:06:03 -0700345 // is unplugged from power *and* the screen is off or doze.
346 protected final TimeBase mOnBatteryScreenOffTimeBase = new TimeBase();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800347
348 // Set to true when we want to distribute CPU across wakelocks for the next
349 // CPU update, even if we aren't currently running wake locks.
350 boolean mDistributeWakelockCpu;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700351
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700352 boolean mShuttingDown;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700353
Dianne Hackborn37de0982014-05-09 09:32:18 -0700354 final HistoryEventTracker mActiveEvents = new HistoryEventTracker();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -0800355
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700356 long mHistoryBaseTime;
357 boolean mHaveBatteryLevel = false;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700358 boolean mRecordingHistory = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700359 int mNumHistoryItems;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700360
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700361 final Parcel mHistoryBuffer = Parcel.obtain();
362 final HistoryItem mHistoryLastWritten = new HistoryItem();
363 final HistoryItem mHistoryLastLastWritten = new HistoryItem();
Dianne Hackborn1fadab52011-04-14 17:57:33 -0700364 final HistoryItem mHistoryReadTmp = new HistoryItem();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700365 final HistoryItem mHistoryAddTmp = new HistoryItem();
Adam Lesinskie08af192015-03-25 16:42:59 -0700366 final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<>();
Dianne Hackborn099bc622014-01-22 13:39:16 -0800367 String[] mReadHistoryStrings;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -0800368 int[] mReadHistoryUids;
369 int mReadHistoryChars;
370 int mNextHistoryTagIdx = 0;
371 int mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700372 int mHistoryBufferLastPos = -1;
373 boolean mHistoryOverflow = false;
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700374 int mActiveHistoryStates = 0xffffffff;
375 int mActiveHistoryStates2 = 0xffffffff;
Dianne Hackborn40c87252014-03-19 16:55:40 -0700376 long mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700377 long mTrackRunningHistoryElapsedRealtime = 0;
378 long mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700379
380 final HistoryItem mHistoryCur = new HistoryItem();
381
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700382 HistoryItem mHistory;
383 HistoryItem mHistoryEnd;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700384 HistoryItem mHistoryLastEnd;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700385 HistoryItem mHistoryCache;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700386
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800387 // Used by computeHistoryStepDetails
388 HistoryStepDetails mLastHistoryStepDetails = null;
389 byte mLastHistoryStepLevel = 0;
390 final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails();
391 final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails();
392 final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails();
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700393
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800394 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700395 * Total time (in milliseconds) spent executing in user code.
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800396 */
397 long mLastStepCpuUserTime;
398 long mCurStepCpuUserTime;
399 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700400 * Total time (in milliseconds) spent executing in kernel code.
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800401 */
402 long mLastStepCpuSystemTime;
403 long mCurStepCpuSystemTime;
404 /**
Adam Lesinski7b83b0c2015-06-05 12:59:36 -0700405 * Times from /proc/stat (but measured in milliseconds).
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -0800406 */
407 long mLastStepStatUserTime;
408 long mLastStepStatSystemTime;
409 long mLastStepStatIOWaitTime;
410 long mLastStepStatIrqTime;
411 long mLastStepStatSoftIrqTime;
412 long mLastStepStatIdleTime;
413 long mCurStepStatUserTime;
414 long mCurStepStatSystemTime;
415 long mCurStepStatIOWaitTime;
416 long mCurStepStatIrqTime;
417 long mCurStepStatSoftIrqTime;
418 long mCurStepStatIdleTime;
419
Dianne Hackborn0ffc9882011-04-13 18:15:56 -0700420 private HistoryItem mHistoryIterator;
421 private boolean mReadOverflow;
422 private boolean mIteratingHistory;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700423
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800424 int mStartCount;
425
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800426 long mStartClockTime;
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700427 String mStartPlatformVersion;
428 String mEndPlatformVersion;
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -0800429
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800430 long mUptime;
431 long mUptimeStart;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800432 long mRealtime;
433 long mRealtimeStart;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700434
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800435 int mWakeLockNesting;
436 boolean mWakeLockImportant;
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700437 public boolean mRecordAllHistory;
Dianne Hackborn9a755432014-05-15 17:05:22 -0700438 boolean mNoAutoReset;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800439
Mike Mac2f518a2017-09-19 16:06:03 -0700440 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
441 protected int mScreenState = Display.STATE_UNKNOWN;
442 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
443 protected StopwatchTimer mScreenOnTimer;
444 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
445 protected StopwatchTimer mScreenDozeTimer;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700446
Dianne Hackborn617f8772009-03-31 15:04:46 -0700447 int mScreenBrightnessBin = -1;
Evan Millarc64edde2009-04-18 12:26:32 -0700448 final StopwatchTimer[] mScreenBrightnessTimer = new StopwatchTimer[NUM_SCREEN_BRIGHTNESS_BINS];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700449
Amith Yamasani674c9bb2017-02-01 09:45:17 -0800450 boolean mPretendScreenOff;
451
Jeff Browne95c3cd2014-05-02 16:59:26 -0700452 boolean mInteractive;
453 StopwatchTimer mInteractiveTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700454
Dianne Hackborn8ad2af72015-03-17 17:00:24 -0700455 boolean mPowerSaveModeEnabled;
456 StopwatchTimer mPowerSaveModeEnabledTimer;
457
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700458 boolean mDeviceIdling;
459 StopwatchTimer mDeviceIdlingTimer;
460
Dianne Hackborn08c47a52015-10-15 12:38:14 -0700461 boolean mDeviceLightIdling;
462 StopwatchTimer mDeviceLightIdlingTimer;
463
464 int mDeviceIdleMode;
465 long mLastIdleTimeStart;
466 long mLongestLightIdleTime;
467 long mLongestFullIdleTime;
468 StopwatchTimer mDeviceIdleModeLightTimer;
469 StopwatchTimer mDeviceIdleModeFullTimer;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700470
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800471 boolean mPhoneOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700472 StopwatchTimer mPhoneOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700473
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700474 int mAudioOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700475 StopwatchTimer mAudioOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700476
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700477 int mVideoOnNesting;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700478 StopwatchTimer mVideoOnTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700479
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700480 int mFlashlightOnNesting;
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700481 StopwatchTimer mFlashlightOnTimer;
482
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700483 int mCameraOnNesting;
484 StopwatchTimer mCameraOnTimer;
485
Dianne Hackborn627bba72009-03-24 22:32:56 -0700486 int mPhoneSignalStrengthBin = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800487 int mPhoneSignalStrengthBinRaw = -1;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700488 final StopwatchTimer[] mPhoneSignalStrengthsTimer =
Wink Saville52840902011-02-18 12:40:47 -0800489 new StopwatchTimer[SignalStrength.NUM_SIGNAL_STRENGTH_BINS];
Amith Yamasanif37447b2009-10-08 18:28:01 -0700490
491 StopwatchTimer mPhoneSignalScanningTimer;
492
Dianne Hackborn627bba72009-03-24 22:32:56 -0700493 int mPhoneDataConnectionType = -1;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700494 final StopwatchTimer[] mPhoneDataConnectionsTimer =
Evan Millarc64edde2009-04-18 12:26:32 -0700495 new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700496
Dianne Hackborn57ed6a62013-12-09 18:15:56 -0800497 final LongSamplingCounter[] mNetworkByteActivityCounters =
498 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
499 final LongSamplingCounter[] mNetworkPacketActivityCounters =
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700500 new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
501
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800502 /**
503 * The WiFi controller activity (time in tx, rx, idle, and power consumed) for the device.
504 */
505 ControllerActivityCounterImpl mWifiActivity;
Adam Lesinski33dac552015-03-09 15:24:48 -0700506
Adam Lesinski21f76aa2016-01-25 12:27:06 -0800507 /**
508 * The Bluetooth controller activity (time in tx, rx, idle, and power consumed) for the device.
509 */
510 ControllerActivityCounterImpl mBluetoothActivity;
511
512 /**
513 * The Modem controller activity (time in tx, rx, idle, and power consumed) for the device.
514 */
515 ControllerActivityCounterImpl mModemActivity;
516
517 /**
518 * Whether the device supports WiFi controller energy reporting. This is set to true on
519 * the first WiFi energy report. See {@link #mWifiActivity}.
520 */
521 boolean mHasWifiReporting = false;
522
523 /**
524 * Whether the device supports Bluetooth controller energy reporting. This is set to true on
525 * the first Bluetooth energy report. See {@link #mBluetoothActivity}.
526 */
527 boolean mHasBluetoothReporting = false;
528
529 /**
530 * Whether the device supports Modem controller energy reporting. This is set to true on
531 * the first Modem energy report. See {@link #mModemActivity}.
532 */
533 boolean mHasModemReporting = false;
Adam Lesinski33dac552015-03-09 15:24:48 -0700534
The Android Open Source Project10592532009-03-18 17:39:46 -0700535 boolean mWifiOn;
Evan Millarc64edde2009-04-18 12:26:32 -0700536 StopwatchTimer mWifiOnTimer;
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700537
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700538 boolean mGlobalWifiRunning;
539 StopwatchTimer mGlobalWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700540
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800541 int mWifiState = -1;
542 final StopwatchTimer[] mWifiStateTimer = new StopwatchTimer[NUM_WIFI_STATES];
543
Dianne Hackborn3251b902014-06-20 14:40:53 -0700544 int mWifiSupplState = -1;
545 final StopwatchTimer[] mWifiSupplStateTimer = new StopwatchTimer[NUM_WIFI_SUPPL_STATES];
546
547 int mWifiSignalStrengthBin = -1;
548 final StopwatchTimer[] mWifiSignalStrengthsTimer =
549 new StopwatchTimer[NUM_WIFI_SIGNAL_STRENGTH_BINS];
550
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800551 int mBluetoothScanNesting;
Bookatz867c0d72017-03-07 18:23:42 -0800552 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
553 protected StopwatchTimer mBluetoothScanTimer;
Adam Lesinski9f55cc72016-01-27 20:42:14 -0800554
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700555 int mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackbornf7097a52014-05-13 09:56:14 -0700556 long mMobileRadioActiveStartTime;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800557 StopwatchTimer mMobileRadioActiveTimer;
Dianne Hackborn77b987f2014-02-26 16:20:52 -0800558 StopwatchTimer mMobileRadioActivePerAppTimer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700559 LongSamplingCounter mMobileRadioActiveAdjustedTime;
Dianne Hackbornd45665b2014-02-26 12:35:32 -0800560 LongSamplingCounter mMobileRadioActiveUnknownTime;
561 LongSamplingCounter mMobileRadioActiveUnknownCount;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800562
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700563 int mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
564
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800565 /**
566 * These provide time bases that discount the time the device is plugged
567 * in to power.
568 */
569 boolean mOnBattery;
Sudheer Shanka38383232017-07-25 09:55:03 -0700570 @VisibleForTesting
571 protected boolean mOnBatteryInternal;
Amith Yamasani3718aaa2009-06-09 06:32:35 -0700572
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700573 /**
574 * External reporting of whether the device is actually charging.
575 */
576 boolean mCharging = true;
577 int mLastChargingStateLevel;
578
The Android Open Source Project10592532009-03-18 17:39:46 -0700579 /*
580 * These keep track of battery levels (1-100) at the last plug event and the last unplug event.
581 */
Evan Millar633a1742009-04-02 16:36:33 -0700582 int mDischargeStartLevel;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700583 int mDischargeUnplugLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700584 int mDischargePlugLevel;
Evan Millar633a1742009-04-02 16:36:33 -0700585 int mDischargeCurrentLevel;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -0700586 int mCurrentBatteryLevel;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -0700587 int mLowDischargeAmountSinceCharge;
588 int mHighDischargeAmountSinceCharge;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800589 int mDischargeScreenOnUnplugLevel;
590 int mDischargeScreenOffUnplugLevel;
Mike Mac2f518a2017-09-19 16:06:03 -0700591 int mDischargeScreenDozeUnplugLevel;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -0800592 int mDischargeAmountScreenOn;
593 int mDischargeAmountScreenOnSinceCharge;
594 int mDischargeAmountScreenOff;
595 int mDischargeAmountScreenOffSinceCharge;
Mike Mac2f518a2017-09-19 16:06:03 -0700596 int mDischargeAmountScreenDoze;
597 int mDischargeAmountScreenDozeSinceCharge;
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700598
Adam Lesinski3ee3f632016-06-08 13:55:55 -0700599 private LongSamplingCounter mDischargeScreenOffCounter;
Mike Mac2f518a2017-09-19 16:06:03 -0700600 private LongSamplingCounter mDischargeScreenDozeCounter;
Adam Lesinski3ee3f632016-06-08 13:55:55 -0700601 private LongSamplingCounter mDischargeCounter;
602
Dianne Hackborncd0e3352014-08-07 17:08:09 -0700603 static final int MAX_LEVEL_STEPS = 200;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700604
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700605 int mInitStepMode = 0;
606 int mCurStepMode = 0;
607 int mModStepMode = 0;
608
Dianne Hackborn260c5022014-04-29 11:23:16 -0700609 int mLastDischargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700610 int mMinDischargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800611 final LevelStepTracker mDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
612 final LevelStepTracker mDailyDischargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
Dianne Hackborn88e98df2015-03-23 13:29:14 -0700613 ArrayList<PackageChange> mDailyPackageChanges;
Dianne Hackborn260c5022014-04-29 11:23:16 -0700614
615 int mLastChargeStepLevel;
Dianne Hackborn29325132014-05-21 15:01:03 -0700616 int mMaxChargeStepLevel;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800617 final LevelStepTracker mChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS);
618 final LevelStepTracker mDailyChargeStepTracker = new LevelStepTracker(MAX_LEVEL_STEPS*2);
619
620 static final int MAX_DAILY_ITEMS = 10;
621
622 long mDailyStartTime = 0;
623 long mNextMinDailyDeadline = 0;
624 long mNextMaxDailyDeadline = 0;
625
626 final ArrayList<DailyItem> mDailyItems = new ArrayList<>();
Dianne Hackborn260c5022014-04-29 11:23:16 -0700627
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 long mLastWriteTime = 0; // Milliseconds
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700629
Amith Yamasanif37447b2009-10-08 18:28:01 -0700630 private int mPhoneServiceState = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -0800631 private int mPhoneServiceStateRaw = -1;
632 private int mPhoneSimStateRaw = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -0700633
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800634 private int mNumConnectivityChange;
635 private int mLoadedNumConnectivityChange;
636 private int mUnpluggedNumConnectivityChange;
637
Adam Lesinskif9b20a92016-06-17 17:30:01 -0700638 private int mEstimatedBatteryCapacity = -1;
639
Jocelyn Dangc627d102017-04-14 13:15:14 -0700640 private int mMinLearnedBatteryCapacity = -1;
641 private int mMaxLearnedBatteryCapacity = -1;
Adam Lesinski041d9172016-12-12 12:03:56 -0800642
Sudheer Shanka9b735c52017-05-09 18:26:18 -0700643 private long[] mCpuFreqs;
644
Sudheer Shanka38383232017-07-25 09:55:03 -0700645 @VisibleForTesting
646 protected PowerProfile mPowerProfile;
Adam Lesinskie08af192015-03-25 16:42:59 -0700647
Evan Millarc64edde2009-04-18 12:26:32 -0700648 /*
Bookatz50df7112017-08-04 14:53:26 -0700649 * Holds a SamplingTimer associated with each Resource Power Manager state and voter,
650 * recording their times when on-battery (regardless of screen state).
651 */
652 private final HashMap<String, SamplingTimer> mRpmStats = new HashMap<>();
653 /** Times for each Resource Power Manager state and voter when screen-off and on-battery. */
654 private final HashMap<String, SamplingTimer> mScreenOffRpmStats = new HashMap<>();
655
656 @Override
657 public Map<String, ? extends Timer> getRpmStats() {
658 return mRpmStats;
659 }
660
Bookatz82b341172017-09-07 19:06:08 -0700661 // TODO: Note: screenOffRpmStats has been disabled via SCREEN_OFF_RPM_STATS_ENABLED.
Bookatz50df7112017-08-04 14:53:26 -0700662 @Override
663 public Map<String, ? extends Timer> getScreenOffRpmStats() {
664 return mScreenOffRpmStats;
665 }
666
667 /*
Evan Millarc64edde2009-04-18 12:26:32 -0700668 * Holds a SamplingTimer associated with each kernel wakelock name being tracked.
669 */
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700670 private final HashMap<String, SamplingTimer> mKernelWakelockStats = new HashMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700671
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700672 public Map<String, ? extends Timer> getKernelWakelockStats() {
Evan Millarc64edde2009-04-18 12:26:32 -0700673 return mKernelWakelockStats;
674 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700675
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700676 String mLastWakeupReason = null;
677 long mLastWakeupUptimeMs = 0;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700678 private final HashMap<String, SamplingTimer> mWakeupReasonStats = new HashMap<>();
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700679
Dianne Hackbornc3940bc2014-09-05 15:50:25 -0700680 public Map<String, ? extends Timer> getWakeupReasonStats() {
Dianne Hackborna1bd7922014-03-21 11:07:11 -0700681 return mWakeupReasonStats;
682 }
683
Adam Lesinski3ee3f632016-06-08 13:55:55 -0700684 @Override
Kweku Adams87b19ec2017-10-09 12:40:03 -0700685 public long getUahDischarge(int which) {
Mike Mac2f518a2017-09-19 16:06:03 -0700686 return mDischargeCounter.getCountLocked(which);
Adam Lesinski3ee3f632016-06-08 13:55:55 -0700687 }
688
689 @Override
Kweku Adams87b19ec2017-10-09 12:40:03 -0700690 public long getUahDischargeScreenOff(int which) {
Mike Mac2f518a2017-09-19 16:06:03 -0700691 return mDischargeScreenOffCounter.getCountLocked(which);
692 }
693
694 @Override
Kweku Adams87b19ec2017-10-09 12:40:03 -0700695 public long getUahDischargeScreenDoze(int which) {
Mike Mac2f518a2017-09-19 16:06:03 -0700696 return mDischargeScreenDozeCounter.getCountLocked(which);
Adam Lesinski3ee3f632016-06-08 13:55:55 -0700697 }
698
Adam Lesinskif9b20a92016-06-17 17:30:01 -0700699 @Override
700 public int getEstimatedBatteryCapacity() {
701 return mEstimatedBatteryCapacity;
702 }
703
Jocelyn Dangc627d102017-04-14 13:15:14 -0700704 @Override
705 public int getMinLearnedBatteryCapacity() {
706 return mMinLearnedBatteryCapacity;
707 }
708
709 @Override
710 public int getMaxLearnedBatteryCapacity() {
711 return mMaxLearnedBatteryCapacity;
712 }
713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800714 public BatteryStatsImpl() {
Joe Onoratoabded112016-02-08 16:49:39 -0800715 this(new SystemClocks());
716 }
717
718 public BatteryStatsImpl(Clocks clocks) {
719 init(clocks);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -0700720 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700721 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -0800722 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -0700723 mHandler = null;
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700724 mPlatformIdleStateCallback = null;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700725 mUserInfoProvider = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700726 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800727 }
728
Joe Onoratoabded112016-02-08 16:49:39 -0800729 private void init(Clocks clocks) {
730 mClocks = clocks;
Joe Onoratoabded112016-02-08 16:49:39 -0800731 }
732
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700733 public interface TimeBaseObs {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800734 void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime);
735 void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime);
736 }
737
Joe Onoratoabded112016-02-08 16:49:39 -0800738 // methods are protected not private to be VisibleForTesting
739 public static class TimeBase {
740 protected final ArrayList<TimeBaseObs> mObservers = new ArrayList<>();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800741
Joe Onoratoabded112016-02-08 16:49:39 -0800742 protected long mUptime;
743 protected long mRealtime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800744
Joe Onoratoabded112016-02-08 16:49:39 -0800745 protected boolean mRunning;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800746
Joe Onoratoabded112016-02-08 16:49:39 -0800747 protected long mPastUptime;
748 protected long mUptimeStart;
749 protected long mPastRealtime;
750 protected long mRealtimeStart;
751 protected long mUnpluggedUptime;
752 protected long mUnpluggedRealtime;
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800753
754 public void dump(PrintWriter pw, String prefix) {
755 StringBuilder sb = new StringBuilder(128);
756 pw.print(prefix); pw.print("mRunning="); pw.println(mRunning);
757 sb.setLength(0);
758 sb.append(prefix);
759 sb.append("mUptime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700760 formatTimeMs(sb, mUptime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800761 pw.println(sb.toString());
762 sb.setLength(0);
763 sb.append(prefix);
764 sb.append("mRealtime=");
Dianne Hackborn4590e522014-03-24 13:36:46 -0700765 formatTimeMs(sb, mRealtime / 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800766 pw.println(sb.toString());
767 sb.setLength(0);
768 sb.append(prefix);
769 sb.append("mPastUptime=");
770 formatTimeMs(sb, mPastUptime / 1000); sb.append("mUptimeStart=");
771 formatTimeMs(sb, mUptimeStart / 1000);
772 sb.append("mUnpluggedUptime="); formatTimeMs(sb, mUnpluggedUptime / 1000);
773 pw.println(sb.toString());
774 sb.setLength(0);
775 sb.append(prefix);
776 sb.append("mPastRealtime=");
777 formatTimeMs(sb, mPastRealtime / 1000); sb.append("mRealtimeStart=");
778 formatTimeMs(sb, mRealtimeStart / 1000);
779 sb.append("mUnpluggedRealtime="); formatTimeMs(sb, mUnpluggedRealtime / 1000);
780 pw.println(sb.toString());
781 }
782
783 public void add(TimeBaseObs observer) {
784 mObservers.add(observer);
785 }
786
787 public void remove(TimeBaseObs observer) {
788 if (!mObservers.remove(observer)) {
789 Slog.wtf(TAG, "Removed unknown observer: " + observer);
790 }
791 }
792
Joe Onoratoabded112016-02-08 16:49:39 -0800793 public boolean hasObserver(TimeBaseObs observer) {
794 return mObservers.contains(observer);
795 }
796
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800797 public void init(long uptime, long realtime) {
798 mRealtime = 0;
799 mUptime = 0;
800 mPastUptime = 0;
801 mPastRealtime = 0;
802 mUptimeStart = uptime;
803 mRealtimeStart = realtime;
804 mUnpluggedUptime = getUptime(mUptimeStart);
805 mUnpluggedRealtime = getRealtime(mRealtimeStart);
806 }
807
808 public void reset(long uptime, long realtime) {
809 if (!mRunning) {
810 mPastUptime = 0;
811 mPastRealtime = 0;
812 } else {
813 mUptimeStart = uptime;
814 mRealtimeStart = realtime;
Joe Onoratoabded112016-02-08 16:49:39 -0800815 // TODO: Since mUptimeStart was just reset and we are running, getUptime will
816 // just return mPastUptime. Also, are we sure we don't want to reset that?
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800817 mUnpluggedUptime = getUptime(uptime);
Joe Onoratoabded112016-02-08 16:49:39 -0800818 // TODO: likewise.
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800819 mUnpluggedRealtime = getRealtime(realtime);
820 }
821 }
822
823 public long computeUptime(long curTime, int which) {
824 switch (which) {
825 case STATS_SINCE_CHARGED:
826 return mUptime + getUptime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800827 case STATS_CURRENT:
828 return getUptime(curTime);
829 case STATS_SINCE_UNPLUGGED:
830 return getUptime(curTime) - mUnpluggedUptime;
831 }
832 return 0;
833 }
834
835 public long computeRealtime(long curTime, int which) {
836 switch (which) {
837 case STATS_SINCE_CHARGED:
838 return mRealtime + getRealtime(curTime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800839 case STATS_CURRENT:
840 return getRealtime(curTime);
841 case STATS_SINCE_UNPLUGGED:
842 return getRealtime(curTime) - mUnpluggedRealtime;
843 }
844 return 0;
845 }
846
847 public long getUptime(long curTime) {
848 long time = mPastUptime;
849 if (mRunning) {
850 time += curTime - mUptimeStart;
851 }
852 return time;
853 }
854
855 public long getRealtime(long curTime) {
856 long time = mPastRealtime;
857 if (mRunning) {
858 time += curTime - mRealtimeStart;
859 }
860 return time;
861 }
862
863 public long getUptimeStart() {
864 return mUptimeStart;
865 }
866
867 public long getRealtimeStart() {
868 return mRealtimeStart;
869 }
870
871 public boolean isRunning() {
872 return mRunning;
873 }
874
875 public boolean setRunning(boolean running, long uptime, long realtime) {
876 if (mRunning != running) {
877 mRunning = running;
878 if (running) {
879 mUptimeStart = uptime;
880 mRealtimeStart = realtime;
881 long batteryUptime = mUnpluggedUptime = getUptime(uptime);
882 long batteryRealtime = mUnpluggedRealtime = getRealtime(realtime);
883
884 for (int i = mObservers.size() - 1; i >= 0; i--) {
885 mObservers.get(i).onTimeStarted(realtime, batteryUptime, batteryRealtime);
886 }
887 } else {
888 mPastUptime += uptime - mUptimeStart;
889 mPastRealtime += realtime - mRealtimeStart;
890
891 long batteryUptime = getUptime(uptime);
892 long batteryRealtime = getRealtime(realtime);
893
894 for (int i = mObservers.size() - 1; i >= 0; i--) {
895 mObservers.get(i).onTimeStopped(realtime, batteryUptime, batteryRealtime);
896 }
897 }
898 return true;
899 }
900 return false;
901 }
902
903 public void readSummaryFromParcel(Parcel in) {
904 mUptime = in.readLong();
905 mRealtime = in.readLong();
906 }
907
908 public void writeSummaryToParcel(Parcel out, long uptime, long realtime) {
909 out.writeLong(computeUptime(uptime, STATS_SINCE_CHARGED));
910 out.writeLong(computeRealtime(realtime, STATS_SINCE_CHARGED));
911 }
912
913 public void readFromParcel(Parcel in) {
914 mRunning = false;
915 mUptime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800916 mPastUptime = in.readLong();
917 mUptimeStart = in.readLong();
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700918 mRealtime = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800919 mPastRealtime = in.readLong();
920 mRealtimeStart = in.readLong();
921 mUnpluggedUptime = in.readLong();
922 mUnpluggedRealtime = in.readLong();
923 }
924
925 public void writeToParcel(Parcel out, long uptime, long realtime) {
926 final long runningUptime = getUptime(uptime);
927 final long runningRealtime = getRealtime(realtime);
928 out.writeLong(mUptime);
929 out.writeLong(runningUptime);
930 out.writeLong(mUptimeStart);
Dianne Hackbornef640cd2014-03-25 14:41:05 -0700931 out.writeLong(mRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800932 out.writeLong(runningRealtime);
933 out.writeLong(mRealtimeStart);
934 out.writeLong(mUnpluggedUptime);
935 out.writeLong(mUnpluggedRealtime);
936 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800937 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 /**
Dianne Hackborn617f8772009-03-31 15:04:46 -0700940 * State for keeping track of counting information.
941 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800942 public static class Counter extends BatteryStats.Counter implements TimeBaseObs {
Christopher Tate4cee7252010-03-19 14:50:40 -0700943 final AtomicInteger mCount = new AtomicInteger();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800944 final TimeBase mTimeBase;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700945 int mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700946 int mUnpluggedCount;
947 int mPluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700948
Bookatz8c6f3c52017-05-24 12:00:17 -0700949 public Counter(TimeBase timeBase, Parcel in) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800950 mTimeBase = timeBase;
Christopher Tate4cee7252010-03-19 14:50:40 -0700951 mPluggedCount = in.readInt();
952 mCount.set(mPluggedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700953 mLoadedCount = in.readInt();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700954 mUnpluggedCount = in.readInt();
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800955 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700956 }
957
Bookatz8c6f3c52017-05-24 12:00:17 -0700958 public Counter(TimeBase timeBase) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800959 mTimeBase = timeBase;
960 timeBase.add(this);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700961 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700962
Dianne Hackborn617f8772009-03-31 15:04:46 -0700963 public void writeToParcel(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700964 out.writeInt(mCount.get());
Dianne Hackborn617f8772009-03-31 15:04:46 -0700965 out.writeInt(mLoadedCount);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700966 out.writeInt(mUnpluggedCount);
967 }
968
Bookatz8c6f3c52017-05-24 12:00:17 -0700969 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800970 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700971 mUnpluggedCount = mPluggedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -0700972 }
973
Bookatz8c6f3c52017-05-24 12:00:17 -0700974 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -0800975 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Christopher Tate4cee7252010-03-19 14:50:40 -0700976 mPluggedCount = mCount.get();
Dianne Hackborn617f8772009-03-31 15:04:46 -0700977 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -0700978
Dianne Hackborn617f8772009-03-31 15:04:46 -0700979 /**
980 * Writes a possibly null Counter to a Parcel.
981 *
982 * @param out the Parcel to be written to.
983 * @param counter a Counter, or null.
984 */
985 public static void writeCounterToParcel(Parcel out, Counter counter) {
986 if (counter == null) {
987 out.writeInt(0); // indicates null
988 return;
989 }
990 out.writeInt(1); // indicates non-null
991
992 counter.writeToParcel(out);
993 }
994
995 @Override
Evan Millarc64edde2009-04-18 12:26:32 -0700996 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -0700997 int val = mCount.get();
998 if (which == STATS_SINCE_UNPLUGGED) {
999 val -= mUnpluggedCount;
1000 } else if (which != STATS_SINCE_CHARGED) {
1001 val -= mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -07001002 }
1003
1004 return val;
1005 }
1006
1007 public void logState(Printer pw, String prefix) {
Christopher Tate4cee7252010-03-19 14:50:40 -07001008 pw.println(prefix + "mCount=" + mCount.get()
Bookatz8c6f3c52017-05-24 12:00:17 -07001009 + " mLoadedCount=" + mLoadedCount
Dianne Hackborn617f8772009-03-31 15:04:46 -07001010 + " mUnpluggedCount=" + mUnpluggedCount
1011 + " mPluggedCount=" + mPluggedCount);
1012 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001013
Bookatz8c6f3c52017-05-24 12:00:17 -07001014 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
1015 public void stepAtomic() {
1016 if (mTimeBase.isRunning()) {
1017 mCount.incrementAndGet();
1018 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07001019 }
1020
Bookatz4ebc0642017-05-11 12:21:19 -07001021 void addAtomic(int delta) {
Bookatz8c6f3c52017-05-24 12:00:17 -07001022 if (mTimeBase.isRunning()) {
1023 mCount.addAndGet(delta);
1024 }
Bookatz4ebc0642017-05-11 12:21:19 -07001025 }
1026
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001027 /**
1028 * Clear state of this counter.
1029 */
1030 void reset(boolean detachIfReset) {
1031 mCount.set(0);
Bookatz8c6f3c52017-05-24 12:00:17 -07001032 mLoadedCount = mPluggedCount = mUnpluggedCount = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001033 if (detachIfReset) {
1034 detach();
1035 }
1036 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001037
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001038 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001039 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001040 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001041
Bookatz8c6f3c52017-05-24 12:00:17 -07001042 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
1043 public void writeSummaryFromParcelLocked(Parcel out) {
Christopher Tate4cee7252010-03-19 14:50:40 -07001044 int count = mCount.get();
1045 out.writeInt(count);
Dianne Hackborn617f8772009-03-31 15:04:46 -07001046 }
1047
Bookatz8c6f3c52017-05-24 12:00:17 -07001048 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
1049 public void readSummaryFromParcelLocked(Parcel in) {
Christopher Tate4cee7252010-03-19 14:50:40 -07001050 mLoadedCount = in.readInt();
1051 mCount.set(mLoadedCount);
Christopher Tate4cee7252010-03-19 14:50:40 -07001052 mUnpluggedCount = mPluggedCount = mLoadedCount;
Dianne Hackborn617f8772009-03-31 15:04:46 -07001053 }
1054 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07001055
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001056 @VisibleForTesting
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001057 public static class LongSamplingCounterArray extends LongCounterArray implements TimeBaseObs {
1058 final TimeBase mTimeBase;
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001059 public long[] mCounts;
1060 public long[] mLoadedCounts;
1061 public long[] mUnpluggedCounts;
1062 public long[] mPluggedCounts;
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001063
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001064 private LongSamplingCounterArray(TimeBase timeBase, Parcel in) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001065 mTimeBase = timeBase;
1066 mPluggedCounts = in.createLongArray();
1067 mCounts = copyArray(mPluggedCounts, mCounts);
1068 mLoadedCounts = in.createLongArray();
1069 mUnpluggedCounts = in.createLongArray();
1070 timeBase.add(this);
1071 }
1072
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001073 public LongSamplingCounterArray(TimeBase timeBase) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001074 mTimeBase = timeBase;
1075 timeBase.add(this);
1076 }
1077
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001078 private void writeToParcel(Parcel out) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001079 out.writeLongArray(mCounts);
1080 out.writeLongArray(mLoadedCounts);
1081 out.writeLongArray(mUnpluggedCounts);
1082 }
1083
1084 @Override
1085 public void onTimeStarted(long elapsedRealTime, long baseUptime, long baseRealtime) {
1086 mUnpluggedCounts = copyArray(mPluggedCounts, mUnpluggedCounts);
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001087 }
1088
1089 @Override
1090 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1091 mPluggedCounts = copyArray(mCounts, mPluggedCounts);
1092 }
1093
1094 @Override
1095 public long[] getCountsLocked(int which) {
1096 long[] val = copyArray(mTimeBase.isRunning() ? mCounts : mPluggedCounts, null);
1097 if (which == STATS_SINCE_UNPLUGGED) {
1098 subtract(val, mUnpluggedCounts);
1099 } else if (which != STATS_SINCE_CHARGED) {
1100 subtract(val, mLoadedCounts);
1101 }
1102 return val;
1103 }
1104
1105 @Override
1106 public void logState(Printer pw, String prefix) {
1107 pw.println(prefix + "mCounts=" + Arrays.toString(mCounts)
1108 + " mLoadedCounts=" + Arrays.toString(mLoadedCounts)
1109 + " mUnpluggedCounts=" + Arrays.toString(mUnpluggedCounts)
1110 + " mPluggedCounts=" + Arrays.toString(mPluggedCounts));
1111 }
1112
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001113 public void addCountLocked(long[] counts) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001114 if (counts == null) {
1115 return;
1116 }
Bookatz8c6f3c52017-05-24 12:00:17 -07001117 if (mTimeBase.isRunning()) {
1118 if (mCounts == null) {
1119 mCounts = new long[counts.length];
1120 }
1121 for (int i = 0; i < counts.length; ++i) {
1122 mCounts[i] += counts[i];
1123 }
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001124 }
1125 }
1126
Sudheer Shankab8ad5942017-08-08 12:16:09 -07001127 public int getSize() {
1128 return mCounts == null ? 0 : mCounts.length;
1129 }
1130
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001131 /**
1132 * Clear state of this counter.
1133 */
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001134 public void reset(boolean detachIfReset) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001135 fillArray(mCounts, 0);
1136 fillArray(mLoadedCounts, 0);
1137 fillArray(mPluggedCounts, 0);
1138 fillArray(mUnpluggedCounts, 0);
1139 if (detachIfReset) {
1140 detach();
1141 }
1142 }
1143
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001144 public void detach() {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001145 mTimeBase.remove(this);
1146 }
1147
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001148 private void writeSummaryToParcelLocked(Parcel out) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001149 out.writeLongArray(mCounts);
1150 }
1151
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001152 private void readSummaryFromParcelLocked(Parcel in) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001153 mCounts = in.createLongArray();
1154 mLoadedCounts = copyArray(mCounts, mLoadedCounts);
1155 mUnpluggedCounts = copyArray(mCounts, mUnpluggedCounts);
1156 mPluggedCounts = copyArray(mCounts, mPluggedCounts);
1157 }
1158
Sudheer Shanka59f5c002017-05-15 10:57:15 -07001159 public static void writeToParcel(Parcel out, LongSamplingCounterArray counterArray) {
1160 if (counterArray != null) {
1161 out.writeInt(1);
1162 counterArray.writeToParcel(out);
1163 } else {
1164 out.writeInt(0);
1165 }
1166 }
1167
1168 public static LongSamplingCounterArray readFromParcel(Parcel in, TimeBase timeBase) {
1169 if (in.readInt() != 0) {
1170 return new LongSamplingCounterArray(timeBase, in);
1171 } else {
1172 return null;
1173 }
1174 }
1175
1176 public static void writeSummaryToParcelLocked(Parcel out,
1177 LongSamplingCounterArray counterArray) {
1178 if (counterArray != null) {
1179 out.writeInt(1);
1180 counterArray.writeSummaryToParcelLocked(out);
1181 } else {
1182 out.writeInt(0);
1183 }
1184 }
1185
1186 public static LongSamplingCounterArray readSummaryFromParcelLocked(Parcel in,
1187 TimeBase timeBase) {
1188 if (in.readInt() != 0) {
1189 final LongSamplingCounterArray counterArray
1190 = new LongSamplingCounterArray(timeBase);
1191 counterArray.readSummaryFromParcelLocked(in);
1192 return counterArray;
1193 } else {
1194 return null;
1195 }
1196 }
1197
Bookatz8c6f3c52017-05-24 12:00:17 -07001198 private static void fillArray(long[] a, long val) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001199 if (a != null) {
1200 Arrays.fill(a, val);
1201 }
1202 }
1203
Bookatz8c6f3c52017-05-24 12:00:17 -07001204 private static void subtract(@NonNull long[] val, long[] toSubtract) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001205 if (toSubtract == null) {
1206 return;
1207 }
1208 for (int i = 0; i < val.length; i++) {
1209 val[i] -= toSubtract[i];
1210 }
1211 }
1212
Bookatz8c6f3c52017-05-24 12:00:17 -07001213 private static long[] copyArray(long[] src, long[] dest) {
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001214 if (src == null) {
1215 return null;
1216 } else {
1217 if (dest == null) {
1218 dest = new long[src.length];
1219 }
1220 System.arraycopy(src, 0, dest, 0, src.length);
1221 return dest;
1222 }
1223 }
1224 }
1225
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001226 public static class LongSamplingCounter extends LongCounter implements TimeBaseObs {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001227 final TimeBase mTimeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001228 long mCount;
1229 long mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001230 long mUnpluggedCount;
1231 long mPluggedCount;
1232
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001233 LongSamplingCounter(TimeBase timeBase, Parcel in) {
1234 mTimeBase = timeBase;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001235 mPluggedCount = in.readLong();
1236 mCount = mPluggedCount;
1237 mLoadedCount = in.readLong();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001238 mUnpluggedCount = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001239 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001240 }
1241
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001242 LongSamplingCounter(TimeBase timeBase) {
1243 mTimeBase = timeBase;
1244 timeBase.add(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001245 }
1246
1247 public void writeToParcel(Parcel out) {
1248 out.writeLong(mCount);
1249 out.writeLong(mLoadedCount);
1250 out.writeLong(mUnpluggedCount);
1251 }
1252
1253 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001254 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001255 mUnpluggedCount = mPluggedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001256 }
1257
1258 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001259 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001260 mPluggedCount = mCount;
1261 }
1262
1263 public long getCountLocked(int which) {
Adam Lesinski3ee3f632016-06-08 13:55:55 -07001264 long val = mTimeBase.isRunning() ? mCount : mPluggedCount;
Dianne Hackborn4590e522014-03-24 13:36:46 -07001265 if (which == STATS_SINCE_UNPLUGGED) {
1266 val -= mUnpluggedCount;
1267 } else if (which != STATS_SINCE_CHARGED) {
1268 val -= mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001269 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001270 return val;
1271 }
1272
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001273 @Override
1274 public void logState(Printer pw, String prefix) {
1275 pw.println(prefix + "mCount=" + mCount
Adam Lesinski3ee3f632016-06-08 13:55:55 -07001276 + " mLoadedCount=" + mLoadedCount
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001277 + " mUnpluggedCount=" + mUnpluggedCount
1278 + " mPluggedCount=" + mPluggedCount);
1279 }
1280
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001281 void addCountLocked(long count) {
Bookatz8c6f3c52017-05-24 12:00:17 -07001282 if (mTimeBase.isRunning()) {
1283 mCount += count;
1284 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001285 }
1286
1287 /**
1288 * Clear state of this counter.
1289 */
1290 void reset(boolean detachIfReset) {
1291 mCount = 0;
Adam Lesinski3ee3f632016-06-08 13:55:55 -07001292 mLoadedCount = mPluggedCount = mUnpluggedCount = 0;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001293 if (detachIfReset) {
1294 detach();
1295 }
1296 }
1297
1298 void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001299 mTimeBase.remove(this);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001300 }
1301
1302 void writeSummaryFromParcelLocked(Parcel out) {
1303 out.writeLong(mCount);
1304 }
1305
1306 void readSummaryFromParcelLocked(Parcel in) {
1307 mLoadedCount = in.readLong();
1308 mCount = mLoadedCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001309 mUnpluggedCount = mPluggedCount = mLoadedCount;
1310 }
1311 }
1312
Dianne Hackborn617f8772009-03-31 15:04:46 -07001313 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 * State for keeping track of timing information.
1315 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001316 public static abstract class Timer extends BatteryStats.Timer implements TimeBaseObs {
Joe Onoratoabded112016-02-08 16:49:39 -08001317 protected final Clocks mClocks;
1318 protected final int mType;
1319 protected final TimeBase mTimeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001320
Joe Onoratoabded112016-02-08 16:49:39 -08001321 protected int mCount;
1322 protected int mLoadedCount;
1323 protected int mLastCount;
1324 protected int mUnpluggedCount;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001325
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 // Times are in microseconds for better accuracy when dividing by the
1327 // lock count, and are in "battery realtime" units.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001328
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 /**
1330 * The total time we have accumulated since the start of the original
1331 * boot, to the last time something interesting happened in the
1332 * current run.
1333 */
Joe Onoratoabded112016-02-08 16:49:39 -08001334 protected long mTotalTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001335
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 /**
1337 * The total time we loaded for the previous runs. Subtract this from
1338 * mTotalTime to find the time for the current run of the system.
1339 */
Joe Onoratoabded112016-02-08 16:49:39 -08001340 protected long mLoadedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001341
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342 /**
1343 * The run time of the last run of the system, as loaded from the
1344 * saved data.
1345 */
Joe Onoratoabded112016-02-08 16:49:39 -08001346 protected long mLastTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001347
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 /**
1349 * The value of mTotalTime when unplug() was last called. Subtract
1350 * this from mTotalTime to find the time since the last unplug from
1351 * power.
1352 */
Joe Onoratoabded112016-02-08 16:49:39 -08001353 protected long mUnpluggedTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001354
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001355 /**
Adam Lesinskie08af192015-03-25 16:42:59 -07001356 * The total time this timer has been running until the latest mark has been set.
1357 * Subtract this from mTotalTime to get the time spent running since the mark was set.
1358 */
Joe Onoratoabded112016-02-08 16:49:39 -08001359 protected long mTimeBeforeMark;
Adam Lesinskie08af192015-03-25 16:42:59 -07001360
1361 /**
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001362 * Constructs from a parcel.
1363 * @param type
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001364 * @param timeBase
Amith Yamasani244fa5c2009-05-22 14:36:07 -07001365 * @param in
1366 */
Joe Onoratoabded112016-02-08 16:49:39 -08001367 public Timer(Clocks clocks, int type, TimeBase timeBase, Parcel in) {
1368 mClocks = clocks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001370 mTimeBase = timeBase;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001372 mCount = in.readInt();
1373 mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001374 mLastCount = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001375 mUnpluggedCount = in.readInt();
1376 mTotalTime = in.readLong();
1377 mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001378 mLastTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 mUnpluggedTime = in.readLong();
Adam Lesinskie08af192015-03-25 16:42:59 -07001380 mTimeBeforeMark = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001381 timeBase.add(this);
Dianne Hackborn29325132014-05-21 15:01:03 -07001382 if (DEBUG) Log.i(TAG, "**** READ TIMER #" + mType + ": mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383 }
1384
Joe Onoratoabded112016-02-08 16:49:39 -08001385 public Timer(Clocks clocks, int type, TimeBase timeBase) {
1386 mClocks = clocks;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001387 mType = type;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001388 mTimeBase = timeBase;
1389 timeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390 }
Evan Millarc64edde2009-04-18 12:26:32 -07001391
1392 protected abstract long computeRunTimeLocked(long curBatteryRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001393
Evan Millarc64edde2009-04-18 12:26:32 -07001394 protected abstract int computeCurrentCountLocked();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001395
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001396 /**
1397 * Clear state of this timer. Returns true if the timer is inactive
1398 * so can be completely dropped.
1399 */
Joe Onoratoabded112016-02-08 16:49:39 -08001400 public boolean reset(boolean detachIfReset) {
Adam Lesinskie08af192015-03-25 16:42:59 -07001401 mTotalTime = mLoadedTime = mLastTime = mTimeBeforeMark = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001402 mCount = mLoadedCount = mLastCount = 0;
1403 if (detachIfReset) {
1404 detach();
1405 }
1406 return true;
1407 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001408
Joe Onoratoabded112016-02-08 16:49:39 -08001409 public void detach() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001410 mTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001411 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001412
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001413 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
Dianne Hackborn29325132014-05-21 15:01:03 -07001414 if (DEBUG) Log.i(TAG, "**** WRITING TIMER #" + mType + ": mTotalTime="
1415 + computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
Adam Lesinski98f0d462016-04-19 16:46:20 -07001416 out.writeInt(computeCurrentCountLocked());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 out.writeInt(mLoadedCount);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 out.writeInt(mUnpluggedCount);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001419 out.writeLong(computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs)));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 out.writeLong(mLoadedTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001421 out.writeLong(mUnpluggedTime);
Adam Lesinskie08af192015-03-25 16:42:59 -07001422 out.writeLong(mTimeBeforeMark);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 }
1424
Adam Lesinskie08af192015-03-25 16:42:59 -07001425 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001426 public void onTimeStarted(long elapsedRealtime, long timeBaseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001428 Log.v(TAG, "unplug #" + mType + ": realtime=" + baseRealtime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001429 + " old mUnpluggedTime=" + mUnpluggedTime
1430 + " old mUnpluggedCount=" + mUnpluggedCount);
1431 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001432 mUnpluggedTime = computeRunTimeLocked(baseRealtime);
Adam Lesinski98f0d462016-04-19 16:46:20 -07001433 mUnpluggedCount = computeCurrentCountLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001434 if (DEBUG && mType < 0) {
1435 Log.v(TAG, "unplug #" + mType
1436 + ": new mUnpluggedTime=" + mUnpluggedTime
1437 + " new mUnpluggedCount=" + mUnpluggedCount);
1438 }
1439 }
1440
Adam Lesinskie08af192015-03-25 16:42:59 -07001441 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001442 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07001443 if (DEBUG && mType < 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001444 Log.v(TAG, "plug #" + mType + ": realtime=" + baseRealtime
Evan Millarc64edde2009-04-18 12:26:32 -07001445 + " old mTotalTime=" + mTotalTime);
1446 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001447 mTotalTime = computeRunTimeLocked(baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001448 mCount = computeCurrentCountLocked();
1449 if (DEBUG && mType < 0) {
1450 Log.v(TAG, "plug #" + mType
1451 + ": new mTotalTime=" + mTotalTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452 }
1453 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001454
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001455 /**
1456 * Writes a possibly null Timer to a Parcel.
1457 *
1458 * @param out the Parcel to be written to.
1459 * @param timer a Timer, or null.
1460 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001461 public static void writeTimerToParcel(Parcel out, Timer timer, long elapsedRealtimeUs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001462 if (timer == null) {
1463 out.writeInt(0); // indicates null
1464 return;
1465 }
1466 out.writeInt(1); // indicates non-null
1467
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001468 timer.writeToParcel(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001469 }
1470
1471 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001472 public long getTotalTimeLocked(long elapsedRealtimeUs, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001473 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1474 if (which == STATS_SINCE_UNPLUGGED) {
1475 val -= mUnpluggedTime;
1476 } else if (which != STATS_SINCE_CHARGED) {
1477 val -= mLoadedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001478 }
1479
1480 return val;
1481 }
1482
1483 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001484 public int getCountLocked(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07001485 int val = computeCurrentCountLocked();
1486 if (which == STATS_SINCE_UNPLUGGED) {
1487 val -= mUnpluggedCount;
1488 } else if (which != STATS_SINCE_CHARGED) {
1489 val -= mLoadedCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 }
1491
1492 return val;
1493 }
1494
Adam Lesinskie08af192015-03-25 16:42:59 -07001495 @Override
1496 public long getTimeSinceMarkLocked(long elapsedRealtimeUs) {
1497 long val = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1498 return val - mTimeBeforeMark;
1499 }
1500
1501 @Override
Dianne Hackborn627bba72009-03-24 22:32:56 -07001502 public void logState(Printer pw, String prefix) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07001503 pw.println(prefix + "mCount=" + mCount
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001504 + " mLoadedCount=" + mLoadedCount + " mLastCount=" + mLastCount
1505 + " mUnpluggedCount=" + mUnpluggedCount);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001506 pw.println(prefix + "mTotalTime=" + mTotalTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 + " mLoadedTime=" + mLoadedTime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07001508 pw.println(prefix + "mLastTime=" + mLastTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509 + " mUnpluggedTime=" + mUnpluggedTime);
Evan Millarc64edde2009-04-18 12:26:32 -07001510 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001511
1512
Joe Onoratoabded112016-02-08 16:49:39 -08001513 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001514 long runTime = computeRunTimeLocked(mTimeBase.getRealtime(elapsedRealtimeUs));
1515 out.writeLong(runTime);
Adam Lesinski98f0d462016-04-19 16:46:20 -07001516 out.writeInt(computeCurrentCountLocked());
Evan Millarc64edde2009-04-18 12:26:32 -07001517 }
1518
Joe Onoratoabded112016-02-08 16:49:39 -08001519 public void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07001520 // Multiply by 1000 for backwards compatibility
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001521 mTotalTime = mLoadedTime = in.readLong();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001522 mLastTime = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001523 mUnpluggedTime = mTotalTime;
1524 mCount = mLoadedCount = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07001525 mLastCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001526 mUnpluggedCount = mCount;
Adam Lesinskie08af192015-03-25 16:42:59 -07001527
1528 // When reading the summary, we set the mark to be the latest information.
1529 mTimeBeforeMark = mTotalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001530 }
1531 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001532
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001533 /**
1534 * A counter meant to accept monotonically increasing values to its {@link #update(long, int)}
1535 * method. The state of the timer according to its {@link TimeBase} will determine how much
1536 * of the value is recorded.
1537 *
1538 * If the value being recorded resets, {@link #endSample()} can be called in order to
1539 * account for the change. If the value passed in to {@link #update(long, int)} decreased
1540 * between calls, the {@link #endSample()} is automatically called and the new value is
1541 * expected to increase monotonically from that point on.
1542 */
Joe Onoratoabded112016-02-08 16:49:39 -08001543 public static class SamplingTimer extends Timer {
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001544
Evan Millarc64edde2009-04-18 12:26:32 -07001545 /**
1546 * The most recent reported count from /proc/wakelocks.
1547 */
1548 int mCurrentReportedCount;
1549
1550 /**
1551 * The reported count from /proc/wakelocks when unplug() was last
1552 * called.
1553 */
1554 int mUnpluggedReportedCount;
1555
1556 /**
1557 * The most recent reported total_time from /proc/wakelocks.
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001558 */
Evan Millarc64edde2009-04-18 12:26:32 -07001559 long mCurrentReportedTotalTime;
1560
1561
1562 /**
1563 * The reported total_time from /proc/wakelocks when unplug() was last
1564 * called.
1565 */
1566 long mUnpluggedReportedTotalTime;
1567
1568 /**
1569 * Whether we are currently in a discharge cycle.
1570 */
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001571 boolean mTimeBaseRunning;
Evan Millarc64edde2009-04-18 12:26:32 -07001572
1573 /**
1574 * Whether we are currently recording reported values.
1575 */
1576 boolean mTrackingReportedValues;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001577
Evan Millarc64edde2009-04-18 12:26:32 -07001578 /*
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001579 * A sequence counter, incremented once for each update of the stats.
Evan Millarc64edde2009-04-18 12:26:32 -07001580 */
1581 int mUpdateVersion;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001582
Adam Lesinski98f0d462016-04-19 16:46:20 -07001583 @VisibleForTesting
1584 public SamplingTimer(Clocks clocks, TimeBase timeBase, Parcel in) {
Joe Onoratoabded112016-02-08 16:49:39 -08001585 super(clocks, 0, timeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -07001586 mCurrentReportedCount = in.readInt();
1587 mUnpluggedReportedCount = in.readInt();
1588 mCurrentReportedTotalTime = in.readLong();
1589 mUnpluggedReportedTotalTime = in.readLong();
1590 mTrackingReportedValues = in.readInt() == 1;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001591 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001592 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001593
Adam Lesinski98f0d462016-04-19 16:46:20 -07001594 @VisibleForTesting
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001595 public SamplingTimer(Clocks clocks, TimeBase timeBase) {
Joe Onoratoabded112016-02-08 16:49:39 -08001596 super(clocks, 0, timeBase);
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001597 mTrackingReportedValues = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001598 mTimeBaseRunning = timeBase.isRunning();
Evan Millarc64edde2009-04-18 12:26:32 -07001599 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001600
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001601 /**
1602 * Ends the current sample, allowing subsequent values to {@link #update(long, int)} to
1603 * be less than the values used for a previous invocation.
1604 */
1605 public void endSample() {
1606 mTotalTime = computeRunTimeLocked(0 /* unused by us */);
1607 mCount = computeCurrentCountLocked();
1608 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime = 0;
1609 mUnpluggedReportedCount = mCurrentReportedCount = 0;
Evan Millarc64edde2009-04-18 12:26:32 -07001610 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001611
Evan Millarc64edde2009-04-18 12:26:32 -07001612 public void setUpdateVersion(int version) {
1613 mUpdateVersion = version;
1614 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001615
Evan Millarc64edde2009-04-18 12:26:32 -07001616 public int getUpdateVersion() {
1617 return mUpdateVersion;
1618 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001619
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001620 /**
1621 * Updates the current recorded values. These are meant to be monotonically increasing
1622 * and cumulative. If you are dealing with deltas, use {@link #add(long, int)}.
1623 *
1624 * If the values being recorded have been reset, the monotonically increasing requirement
1625 * will be broken. In this case, {@link #endSample()} is automatically called and
1626 * the total value of totalTime and count are recorded, starting a new monotonically
1627 * increasing sample.
1628 *
1629 * @param totalTime total time of sample in microseconds.
1630 * @param count total number of times the event being sampled occurred.
1631 */
1632 public void update(long totalTime, int count) {
1633 if (mTimeBaseRunning && !mTrackingReportedValues) {
Evan Millarc64edde2009-04-18 12:26:32 -07001634 // Updating the reported value for the first time.
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001635 mUnpluggedReportedTotalTime = totalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001636 mUnpluggedReportedCount = count;
Evan Millarc64edde2009-04-18 12:26:32 -07001637 }
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001638
1639 mTrackingReportedValues = true;
1640
1641 if (totalTime < mCurrentReportedTotalTime || count < mCurrentReportedCount) {
1642 endSample();
1643 }
1644
1645 mCurrentReportedTotalTime = totalTime;
Evan Millarc64edde2009-04-18 12:26:32 -07001646 mCurrentReportedCount = count;
1647 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001648
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001649 /**
1650 * Adds deltaTime and deltaCount to the current sample.
1651 *
1652 * @param deltaTime additional time recorded since the last sampled event, in microseconds.
1653 * @param deltaCount additional number of times the event being sampled occurred.
1654 */
1655 public void add(long deltaTime, int deltaCount) {
1656 update(mCurrentReportedTotalTime + deltaTime, mCurrentReportedCount + deltaCount);
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07001657 }
1658
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001659 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001660 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
1661 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Evan Millarc64edde2009-04-18 12:26:32 -07001662 if (mTrackingReportedValues) {
1663 mUnpluggedReportedTotalTime = mCurrentReportedTotalTime;
1664 mUnpluggedReportedCount = mCurrentReportedCount;
1665 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001666 mTimeBaseRunning = true;
Evan Millarc64edde2009-04-18 12:26:32 -07001667 }
1668
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001669 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001670 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
1671 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
1672 mTimeBaseRunning = false;
Evan Millarc64edde2009-04-18 12:26:32 -07001673 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001674
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001675 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001676 public void logState(Printer pw, String prefix) {
1677 super.logState(pw, prefix);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001678 pw.println(prefix + "mCurrentReportedCount=" + mCurrentReportedCount
Evan Millarc64edde2009-04-18 12:26:32 -07001679 + " mUnpluggedReportedCount=" + mUnpluggedReportedCount
1680 + " mCurrentReportedTotalTime=" + mCurrentReportedTotalTime
1681 + " mUnpluggedReportedTotalTime=" + mUnpluggedReportedTotalTime);
1682 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001683
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001684 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001685 protected long computeRunTimeLocked(long curBatteryRealtime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001686 return mTotalTime + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001687 ? mCurrentReportedTotalTime - mUnpluggedReportedTotalTime : 0);
1688 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001689
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001690 @Override
Evan Millarc64edde2009-04-18 12:26:32 -07001691 protected int computeCurrentCountLocked() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001692 return mCount + (mTimeBaseRunning && mTrackingReportedValues
Evan Millarc64edde2009-04-18 12:26:32 -07001693 ? mCurrentReportedCount - mUnpluggedReportedCount : 0);
1694 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001695
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001696 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001697 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1698 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07001699 out.writeInt(mCurrentReportedCount);
1700 out.writeInt(mUnpluggedReportedCount);
1701 out.writeLong(mCurrentReportedTotalTime);
1702 out.writeLong(mUnpluggedReportedTotalTime);
1703 out.writeInt(mTrackingReportedValues ? 1 : 0);
1704 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001705
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001706 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08001707 public boolean reset(boolean detachIfReset) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001708 super.reset(detachIfReset);
Adam Lesinski757c6ea2016-04-21 09:55:41 -07001709 mTrackingReportedValues = false;
1710 mUnpluggedReportedTotalTime = 0;
1711 mUnpluggedReportedCount = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07001712 return true;
1713 }
Evan Millarc64edde2009-04-18 12:26:32 -07001714 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07001715
Evan Millarc64edde2009-04-18 12:26:32 -07001716 /**
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001717 * A timer that increments in batches. It does not run for durations, but just jumps
1718 * for a pre-determined amount.
1719 */
Joe Onoratoabded112016-02-08 16:49:39 -08001720 public static class BatchTimer extends Timer {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001721 final Uid mUid;
1722
1723 /**
1724 * The last time at which we updated the timer. This is in elapsed realtime microseconds.
1725 */
1726 long mLastAddedTime;
1727
1728 /**
1729 * The last duration that we added to the timer. This is in microseconds.
1730 */
1731 long mLastAddedDuration;
1732
1733 /**
1734 * Whether we are currently in a discharge cycle.
1735 */
1736 boolean mInDischarge;
1737
Joe Onoratoabded112016-02-08 16:49:39 -08001738 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase, Parcel in) {
1739 super(clocks, type, timeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001740 mUid = uid;
1741 mLastAddedTime = in.readLong();
1742 mLastAddedDuration = in.readLong();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001743 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001744 }
1745
Joe Onoratoabded112016-02-08 16:49:39 -08001746 BatchTimer(Clocks clocks, Uid uid, int type, TimeBase timeBase) {
1747 super(clocks, type, timeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001748 mUid = uid;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001749 mInDischarge = timeBase.isRunning();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001750 }
1751
1752 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001753 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1754 super.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001755 out.writeLong(mLastAddedTime);
1756 out.writeLong(mLastAddedDuration);
1757 }
1758
1759 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001760 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Joe Onoratoabded112016-02-08 16:49:39 -08001761 recomputeLastDuration(mClocks.elapsedRealtime() * 1000, false);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001762 mInDischarge = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001763 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001764 }
1765
1766 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001767 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001768 recomputeLastDuration(elapsedRealtime, false);
1769 mInDischarge = true;
1770 // If we are still within the last added duration, then re-added whatever remains.
1771 if (mLastAddedTime == elapsedRealtime) {
1772 mTotalTime += mLastAddedDuration;
1773 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001774 super.onTimeStarted(elapsedRealtime, baseUptime, baseRealtime);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001775 }
1776
1777 @Override
1778 public void logState(Printer pw, String prefix) {
1779 super.logState(pw, prefix);
1780 pw.println(prefix + "mLastAddedTime=" + mLastAddedTime
1781 + " mLastAddedDuration=" + mLastAddedDuration);
1782 }
1783
1784 private long computeOverage(long curTime) {
1785 if (mLastAddedTime > 0) {
1786 return mLastTime + mLastAddedDuration - curTime;
1787 }
1788 return 0;
1789 }
1790
1791 private void recomputeLastDuration(long curTime, boolean abort) {
1792 final long overage = computeOverage(curTime);
1793 if (overage > 0) {
1794 // Aborting before the duration ran out -- roll back the remaining
1795 // duration. Only do this if currently discharging; otherwise we didn't
1796 // actually add the time.
1797 if (mInDischarge) {
1798 mTotalTime -= overage;
1799 }
1800 if (abort) {
1801 mLastAddedTime = 0;
1802 } else {
1803 mLastAddedTime = curTime;
1804 mLastAddedDuration -= overage;
1805 }
1806 }
1807 }
1808
1809 public void addDuration(BatteryStatsImpl stats, long durationMillis) {
Joe Onoratoabded112016-02-08 16:49:39 -08001810 final long now = mClocks.elapsedRealtime() * 1000;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001811 recomputeLastDuration(now, true);
1812 mLastAddedTime = now;
1813 mLastAddedDuration = durationMillis * 1000;
1814 if (mInDischarge) {
1815 mTotalTime += mLastAddedDuration;
1816 mCount++;
1817 }
1818 }
1819
1820 public void abortLastDuration(BatteryStatsImpl stats) {
Joe Onoratoabded112016-02-08 16:49:39 -08001821 final long now = mClocks.elapsedRealtime() * 1000;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001822 recomputeLastDuration(now, true);
1823 }
1824
1825 @Override
1826 protected int computeCurrentCountLocked() {
1827 return mCount;
1828 }
1829
1830 @Override
1831 protected long computeRunTimeLocked(long curBatteryRealtime) {
Joe Onoratoabded112016-02-08 16:49:39 -08001832 final long overage = computeOverage(mClocks.elapsedRealtime() * 1000);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001833 if (overage > 0) {
1834 return mTotalTime = overage;
1835 }
1836 return mTotalTime;
1837 }
1838
1839 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08001840 public boolean reset(boolean detachIfReset) {
1841 final long now = mClocks.elapsedRealtime() * 1000;
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001842 recomputeLastDuration(now, true);
1843 boolean stillActive = mLastAddedTime == now;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08001844 super.reset(!stillActive && detachIfReset);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08001845 return !stillActive;
1846 }
1847 }
1848
Joe Onorato92fd23f2016-07-25 11:18:42 -07001849
1850 /**
1851 * A StopwatchTimer that also tracks the total and max individual
1852 * time spent active according to the given timebase. Whereas
1853 * StopwatchTimer apportions the time amongst all in the pool,
1854 * the total and max durations are not apportioned.
1855 */
1856 public static class DurationTimer extends StopwatchTimer {
1857 /**
1858 * The time (in ms) that the timer was last acquired or the time base
1859 * last (re-)started. Increasing the nesting depth does not reset this time.
1860 *
1861 * -1 if the timer is currently not running or the time base is not running.
1862 *
1863 * If written to a parcel, the start time is reset, as is mNesting in the base class
1864 * StopwatchTimer.
1865 */
1866 long mStartTimeMs = -1;
1867
1868 /**
Bookatz867c0d72017-03-07 18:23:42 -08001869 * The longest time period (in ms) that the timer has been active. Not pooled.
Joe Onorato92fd23f2016-07-25 11:18:42 -07001870 */
1871 long mMaxDurationMs;
1872
1873 /**
Bookatz867c0d72017-03-07 18:23:42 -08001874 * The time (in ms) that that the timer has been active since most recent
1875 * stopRunningLocked() or reset(). Not pooled.
Joe Onorato92fd23f2016-07-25 11:18:42 -07001876 */
1877 long mCurrentDurationMs;
1878
Bookatz867c0d72017-03-07 18:23:42 -08001879 /**
1880 * The total time (in ms) that that the timer has been active since most recent reset()
1881 * prior to the current startRunningLocked. This is the sum of all past currentDurations
1882 * (but not including the present currentDuration) since reset. Not pooled.
1883 */
1884 long mTotalDurationMs;
1885
Joe Onorato92fd23f2016-07-25 11:18:42 -07001886 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
1887 TimeBase timeBase, Parcel in) {
1888 super(clocks, uid, type, timerPool, timeBase, in);
1889 mMaxDurationMs = in.readLong();
Bookatz867c0d72017-03-07 18:23:42 -08001890 mTotalDurationMs = in.readLong();
jackqdyulei610a0a02017-08-09 14:02:01 -07001891 mCurrentDurationMs = in.readLong();
Joe Onorato92fd23f2016-07-25 11:18:42 -07001892 }
1893
1894 public DurationTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
1895 TimeBase timeBase) {
1896 super(clocks, uid, type, timerPool, timeBase);
1897 }
1898
1899 @Override
1900 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
1901 super.writeToParcel(out, elapsedRealtimeUs);
Kweku Adams47db5a82016-12-09 19:04:50 -08001902 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000));
jackqdyulei610a0a02017-08-09 14:02:01 -07001903 out.writeLong(mTotalDurationMs);
1904 out.writeLong(getCurrentDurationMsLocked(elapsedRealtimeUs / 1000));
Joe Onorato92fd23f2016-07-25 11:18:42 -07001905 }
1906
1907 /**
1908 * Write the summary to the parcel.
1909 *
1910 * Since the time base is probably meaningless after we come back, reading
1911 * from this will have the effect of stopping the timer. So here all we write
Bookatz867c0d72017-03-07 18:23:42 -08001912 * is the max and total durations.
Joe Onorato92fd23f2016-07-25 11:18:42 -07001913 */
1914 @Override
1915 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
1916 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
Kweku Adams47db5a82016-12-09 19:04:50 -08001917 out.writeLong(getMaxDurationMsLocked(elapsedRealtimeUs / 1000));
Bookatz867c0d72017-03-07 18:23:42 -08001918 out.writeLong(getTotalDurationMsLocked(elapsedRealtimeUs / 1000));
Joe Onorato92fd23f2016-07-25 11:18:42 -07001919 }
1920
1921 /**
1922 * Read the summary parcel.
1923 *
1924 * Has the side effect of stopping the timer.
1925 */
1926 @Override
1927 public void readSummaryFromParcelLocked(Parcel in) {
1928 super.readSummaryFromParcelLocked(in);
1929 mMaxDurationMs = in.readLong();
Bookatz867c0d72017-03-07 18:23:42 -08001930 mTotalDurationMs = in.readLong();
Joe Onorato92fd23f2016-07-25 11:18:42 -07001931 mStartTimeMs = -1;
1932 mCurrentDurationMs = 0;
1933 }
1934
1935 /**
1936 * The TimeBase time started (again).
1937 *
1938 * If the timer is also running, store the start time.
1939 */
1940 public void onTimeStarted(long elapsedRealtimeUs, long baseUptime, long baseRealtime) {
1941 super.onTimeStarted(elapsedRealtimeUs, baseUptime, baseRealtime);
1942 if (mNesting > 0) {
Kweku Adams47db5a82016-12-09 19:04:50 -08001943 mStartTimeMs = baseRealtime / 1000;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001944 }
1945 }
1946
1947 /**
1948 * The TimeBase stopped running.
1949 *
1950 * If the timer is running, add the duration into mCurrentDurationMs.
1951 */
1952 @Override
Kweku Adams47db5a82016-12-09 19:04:50 -08001953 public void onTimeStopped(long elapsedRealtimeUs, long baseUptime, long baseRealtimeUs) {
1954 super.onTimeStopped(elapsedRealtimeUs, baseUptime, baseRealtimeUs);
Joe Onorato92fd23f2016-07-25 11:18:42 -07001955 if (mNesting > 0) {
Kweku Adams47db5a82016-12-09 19:04:50 -08001956 // baseRealtimeUs has already been converted to the timebase's realtime.
1957 mCurrentDurationMs += (baseRealtimeUs / 1000) - mStartTimeMs;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001958 }
1959 mStartTimeMs = -1;
1960 }
1961
1962 @Override
1963 public void logState(Printer pw, String prefix) {
1964 super.logState(pw, prefix);
1965 }
1966
1967 @Override
1968 public void startRunningLocked(long elapsedRealtimeMs) {
1969 super.startRunningLocked(elapsedRealtimeMs);
1970 if (mNesting == 1 && mTimeBase.isRunning()) {
1971 // Just started
Kweku Adams47db5a82016-12-09 19:04:50 -08001972 mStartTimeMs = mTimeBase.getRealtime(elapsedRealtimeMs * 1000) / 1000;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001973 }
1974 }
1975
1976 /**
1977 * Decrements the mNesting ref-count on this timer.
1978 *
1979 * If it actually stopped (mNesting went to 0), then possibly update
1980 * mMaxDuration if the current duration was the longest ever.
1981 */
1982 @Override
1983 public void stopRunningLocked(long elapsedRealtimeMs) {
Kweku Adams47db5a82016-12-09 19:04:50 -08001984 if (mNesting == 1) {
Joe Onorato92fd23f2016-07-25 11:18:42 -07001985 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs);
Bookatz867c0d72017-03-07 18:23:42 -08001986 mTotalDurationMs += durationMs;
Joe Onorato92fd23f2016-07-25 11:18:42 -07001987 if (durationMs > mMaxDurationMs) {
1988 mMaxDurationMs = durationMs;
1989 }
1990 mStartTimeMs = -1;
1991 mCurrentDurationMs = 0;
1992 }
Kweku Adams47db5a82016-12-09 19:04:50 -08001993 // super method decrements mNesting, which getCurrentDurationMsLocked relies on,
1994 // so call super.stopRunningLocked after calling getCurrentDurationMsLocked.
1995 super.stopRunningLocked(elapsedRealtimeMs);
Joe Onorato92fd23f2016-07-25 11:18:42 -07001996 }
1997
1998 @Override
1999 public boolean reset(boolean detachIfReset) {
2000 boolean result = super.reset(detachIfReset);
2001 mMaxDurationMs = 0;
Bookatz867c0d72017-03-07 18:23:42 -08002002 mTotalDurationMs = 0;
Joe Onorato92fd23f2016-07-25 11:18:42 -07002003 mCurrentDurationMs = 0;
2004 if (mNesting > 0) {
2005 mStartTimeMs = mTimeBase.getRealtime(mClocks.elapsedRealtime()*1000) / 1000;
2006 } else {
2007 mStartTimeMs = -1;
2008 }
2009 return result;
2010 }
2011
2012 /**
2013 * Returns the max duration that this timer has ever seen.
2014 *
2015 * Note that this time is NOT split between the timers in the timer group that
2016 * this timer is attached to. It is the TOTAL time.
2017 */
2018 @Override
2019 public long getMaxDurationMsLocked(long elapsedRealtimeMs) {
2020 if (mNesting > 0) {
2021 final long durationMs = getCurrentDurationMsLocked(elapsedRealtimeMs);
2022 if (durationMs > mMaxDurationMs) {
2023 return durationMs;
2024 }
2025 }
2026 return mMaxDurationMs;
2027 }
2028
2029 /**
2030 * Returns the time since the timer was started.
Bookatz867c0d72017-03-07 18:23:42 -08002031 * Returns 0 if the timer is not currently running.
Joe Onorato92fd23f2016-07-25 11:18:42 -07002032 *
2033 * Note that this time is NOT split between the timers in the timer group that
2034 * this timer is attached to. It is the TOTAL time.
jackqdyulei610a0a02017-08-09 14:02:01 -07002035 *
2036 * Note that if running timer is parceled and unparceled, this method will return
2037 * current duration value at the time of parceling even though timer may not be
2038 * currently running.
Joe Onorato92fd23f2016-07-25 11:18:42 -07002039 */
2040 @Override
2041 public long getCurrentDurationMsLocked(long elapsedRealtimeMs) {
2042 long durationMs = mCurrentDurationMs;
Kweku Adams47db5a82016-12-09 19:04:50 -08002043 if (mNesting > 0 && mTimeBase.isRunning()) {
2044 durationMs += (mTimeBase.getRealtime(elapsedRealtimeMs*1000)/1000)
2045 - mStartTimeMs;
Joe Onorato92fd23f2016-07-25 11:18:42 -07002046 }
2047 return durationMs;
2048 }
Bookatz867c0d72017-03-07 18:23:42 -08002049
2050 /**
2051 * Returns the total cumulative duration that this timer has been on since reset().
2052 * If mTimerPool == null, this should be the same
2053 * as getTotalTimeLocked(elapsedRealtimeMs*1000, STATS_SINCE_CHARGED)/1000.
2054 *
2055 * Note that this time is NOT split between the timers in the timer group that
2056 * this timer is attached to. It is the TOTAL time. For this reason, if mTimerPool != null,
2057 * the result will not be equivalent to getTotalTimeLocked.
2058 */
2059 @Override
2060 public long getTotalDurationMsLocked(long elapsedRealtimeMs) {
2061 return mTotalDurationMs + getCurrentDurationMsLocked(elapsedRealtimeMs);
2062 }
Joe Onorato92fd23f2016-07-25 11:18:42 -07002063 }
2064
Dianne Hackborna06de0f2012-12-11 16:34:47 -08002065 /**
Evan Millarc64edde2009-04-18 12:26:32 -07002066 * State for keeping track of timing information.
2067 */
Joe Onoratoabded112016-02-08 16:49:39 -08002068 public static class StopwatchTimer extends Timer {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002069 final Uid mUid;
Evan Millarc64edde2009-04-18 12:26:32 -07002070 final ArrayList<StopwatchTimer> mTimerPool;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002071
Evan Millarc64edde2009-04-18 12:26:32 -07002072 int mNesting;
2073
Evan Millarc64edde2009-04-18 12:26:32 -07002074 /**
2075 * The last time at which we updated the timer. If mNesting is > 0,
2076 * subtract this from the current battery time to find the amount of
2077 * time we have been running since we last computed an update.
2078 */
2079 long mUpdateTime;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002080
Evan Millarc64edde2009-04-18 12:26:32 -07002081 /**
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002082 * The total time at which the timer was acquired, to determine if it
Bookatzceebafe2017-04-06 11:59:13 -07002083 * was actually held for an interesting duration. If time base was not running when timer
2084 * was acquired, will be -1.
Evan Millarc64edde2009-04-18 12:26:32 -07002085 */
Bookatzceebafe2017-04-06 11:59:13 -07002086 long mAcquireTime = -1;
Evan Millarc64edde2009-04-18 12:26:32 -07002087
Amith Yamasanif37447b2009-10-08 18:28:01 -07002088 long mTimeout;
2089
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002090 /**
2091 * For partial wake locks, keep track of whether we are in the list
2092 * to consume CPU cycles.
2093 */
Sudheer Shanka38383232017-07-25 09:55:03 -07002094 @VisibleForTesting
2095 public boolean mInList;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002096
Joe Onoratoabded112016-02-08 16:49:39 -08002097 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002098 TimeBase timeBase, Parcel in) {
Joe Onoratoabded112016-02-08 16:49:39 -08002099 super(clocks, type, timeBase, in);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002100 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07002101 mTimerPool = timerPool;
2102 mUpdateTime = in.readLong();
2103 }
2104
Joe Onoratoabded112016-02-08 16:49:39 -08002105 public StopwatchTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002106 TimeBase timeBase) {
Joe Onoratoabded112016-02-08 16:49:39 -08002107 super(clocks, type, timeBase);
Dianne Hackborn0d903a82010-09-07 23:51:03 -07002108 mUid = uid;
Evan Millarc64edde2009-04-18 12:26:32 -07002109 mTimerPool = timerPool;
2110 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002111
Joe Onoratoabded112016-02-08 16:49:39 -08002112 public void setTimeout(long timeout) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07002113 mTimeout = timeout;
2114 }
2115
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002116 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
2117 super.writeToParcel(out, elapsedRealtimeUs);
Evan Millarc64edde2009-04-18 12:26:32 -07002118 out.writeLong(mUpdateTime);
2119 }
2120
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002121 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
Evan Millarc64edde2009-04-18 12:26:32 -07002122 if (mNesting > 0) {
2123 if (DEBUG && mType < 0) {
2124 Log.v(TAG, "old mUpdateTime=" + mUpdateTime);
2125 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002126 super.onTimeStopped(elapsedRealtime, baseUptime, baseRealtime);
2127 mUpdateTime = baseRealtime;
Evan Millarc64edde2009-04-18 12:26:32 -07002128 if (DEBUG && mType < 0) {
2129 Log.v(TAG, "new mUpdateTime=" + mUpdateTime);
2130 }
2131 }
2132 }
2133
2134 public void logState(Printer pw, String prefix) {
2135 super.logState(pw, prefix);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07002136 pw.println(prefix + "mNesting=" + mNesting + " mUpdateTime=" + mUpdateTime
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002137 + " mAcquireTime=" + mAcquireTime);
2138 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002139
Joe Onoratoabded112016-02-08 16:49:39 -08002140 public void startRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002141 if (mNesting++ == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002142 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08002143 mUpdateTime = batteryRealtime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002144 if (mTimerPool != null) {
2145 // Accumulate time to all currently active timers before adding
2146 // this new one to the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002147 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 // Add this timer to the active pool
2149 mTimerPool.add(this);
2150 }
Bookatzceebafe2017-04-06 11:59:13 -07002151 if (mTimeBase.isRunning()) {
2152 // Increment the count
2153 mCount++;
2154 mAcquireTime = mTotalTime;
2155 } else {
2156 mAcquireTime = -1;
2157 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002158 if (DEBUG && mType < 0) {
2159 Log.v(TAG, "start #" + mType + ": mUpdateTime=" + mUpdateTime
2160 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
2161 + " mAcquireTime=" + mAcquireTime);
2162 }
2163 }
2164 }
2165
Joe Onoratoabded112016-02-08 16:49:39 -08002166 public boolean isRunningLocked() {
Amith Yamasani32dbefd2009-06-19 09:21:17 -07002167 return mNesting > 0;
2168 }
2169
Joe Onoratoabded112016-02-08 16:49:39 -08002170 public void stopRunningLocked(long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 // Ignore attempt to stop a timer that isn't running
2172 if (mNesting == 0) {
2173 return;
2174 }
2175 if (--mNesting == 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002176 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002177 if (mTimerPool != null) {
2178 // Accumulate time to all active counters, scaled by the total
2179 // active in the pool, before taking this one out of the pool.
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002180 refreshTimersLocked(batteryRealtime, mTimerPool, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002181 // Remove this timer from the active pool
2182 mTimerPool.remove(this);
2183 } else {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002184 mNesting = 1;
2185 mTotalTime = computeRunTimeLocked(batteryRealtime);
2186 mNesting = 0;
2187 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002189 if (DEBUG && mType < 0) {
2190 Log.v(TAG, "stop #" + mType + ": mUpdateTime=" + mUpdateTime
2191 + " mTotalTime=" + mTotalTime + " mCount=" + mCount
2192 + " mAcquireTime=" + mAcquireTime);
2193 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002194
Bookatzceebafe2017-04-06 11:59:13 -07002195 if (mAcquireTime >= 0 && mTotalTime == mAcquireTime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002196 // If there was no change in the time, then discard this
2197 // count. A somewhat cheezy strategy, but hey.
2198 mCount--;
2199 }
2200 }
2201 }
2202
Joe Onoratoabded112016-02-08 16:49:39 -08002203 public void stopAllRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07002204 if (mNesting > 0) {
2205 mNesting = 1;
2206 stopRunningLocked(elapsedRealtimeMs);
2207 }
2208 }
2209
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002210 // Update the total time for all other running Timers with the same type as this Timer
2211 // due to a change in timer count
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002212 private static long refreshTimersLocked(long batteryRealtime,
2213 final ArrayList<StopwatchTimer> pool, StopwatchTimer self) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08002214 long selfTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002215 final int N = pool.size();
2216 for (int i=N-1; i>= 0; i--) {
Evan Millarc64edde2009-04-18 12:26:32 -07002217 final StopwatchTimer t = pool.get(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002218 long heldTime = batteryRealtime - t.mUpdateTime;
2219 if (heldTime > 0) {
Dianne Hackbornd45665b2014-02-26 12:35:32 -08002220 final long myTime = heldTime / N;
2221 if (t == self) {
2222 selfTime = myTime;
2223 }
2224 t.mTotalTime += myTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002225 }
2226 t.mUpdateTime = batteryRealtime;
2227 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08002228 return selfTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002229 }
2230
Evan Millarc64edde2009-04-18 12:26:32 -07002231 @Override
2232 protected long computeRunTimeLocked(long curBatteryRealtime) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07002233 if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
2234 curBatteryRealtime = mUpdateTime + mTimeout;
2235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002236 return mTotalTime + (mNesting > 0
2237 ? (curBatteryRealtime - mUpdateTime)
2238 / (mTimerPool != null ? mTimerPool.size() : 1)
2239 : 0);
2240 }
2241
Evan Millarc64edde2009-04-18 12:26:32 -07002242 @Override
2243 protected int computeCurrentCountLocked() {
2244 return mCount;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002245 }
2246
Adam Lesinskie08af192015-03-25 16:42:59 -07002247 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08002248 public boolean reset(boolean detachIfReset) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002249 boolean canDetach = mNesting <= 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08002250 super.reset(canDetach && detachIfReset);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002251 if (mNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08002252 mUpdateTime = mTimeBase.getRealtime(mClocks.elapsedRealtime() * 1000);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07002253 }
Bookatzceebafe2017-04-06 11:59:13 -07002254 mAcquireTime = -1; // to ensure mCount isn't decreased to -1 if timer is stopped later.
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002255 return canDetach;
2256 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002257
Adam Lesinskie08af192015-03-25 16:42:59 -07002258 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08002259 public void detach() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07002260 super.detach();
2261 if (mTimerPool != null) {
2262 mTimerPool.remove(this);
2263 }
2264 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002265
Adam Lesinskie08af192015-03-25 16:42:59 -07002266 @Override
Joe Onoratoabded112016-02-08 16:49:39 -08002267 public void readSummaryFromParcelLocked(Parcel in) {
Evan Millarc64edde2009-04-18 12:26:32 -07002268 super.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002269 mNesting = 0;
2270 }
Adam Lesinskie08af192015-03-25 16:42:59 -07002271
2272 /**
2273 * Set the mark so that we can query later for the total time the timer has
2274 * accumulated since this point. The timer can be running or not.
2275 *
2276 * @param elapsedRealtimeMs the current elapsed realtime in milliseconds.
2277 */
2278 public void setMark(long elapsedRealtimeMs) {
2279 final long batteryRealtime = mTimeBase.getRealtime(elapsedRealtimeMs * 1000);
2280 if (mNesting > 0) {
2281 // We are running.
2282 if (mTimerPool != null) {
2283 refreshTimersLocked(batteryRealtime, mTimerPool, this);
2284 } else {
2285 mTotalTime += batteryRealtime - mUpdateTime;
2286 mUpdateTime = batteryRealtime;
2287 }
2288 }
2289 mTimeBeforeMark = mTotalTime;
2290 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002291 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002292
Bookatz867c0d72017-03-07 18:23:42 -08002293 /**
2294 * State for keeping track of two DurationTimers with different TimeBases, presumably where one
2295 * TimeBase is effectively a subset of the other.
2296 */
Bookatzaa4594a2017-03-24 12:39:56 -07002297 public static class DualTimer extends DurationTimer {
2298 // This class both is a DurationTimer and also holds a second DurationTimer.
2299 // The main timer (this) typically tracks the total time. It may be pooled (but since it's a
2300 // durationTimer, it also has the unpooled getTotalDurationMsLocked() for
2301 // STATS_SINCE_CHARGED).
Bookatz867c0d72017-03-07 18:23:42 -08002302 // mSubTimer typically tracks only part of the total time, such as background time, as
2303 // determined by a subTimeBase. It is NOT pooled.
2304 private final DurationTimer mSubTimer;
2305
2306 /**
Bookatzaa4594a2017-03-24 12:39:56 -07002307 * Creates a DualTimer to hold a main timer (this) and a mSubTimer.
2308 * The main timer (this) is based on the given timeBase and timerPool.
Bookatz867c0d72017-03-07 18:23:42 -08002309 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if
Bookatzaa4594a2017-03-24 12:39:56 -07002310 * the main timer is.
Bookatz867c0d72017-03-07 18:23:42 -08002311 */
2312 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2313 TimeBase timeBase, TimeBase subTimeBase, Parcel in) {
Bookatzaa4594a2017-03-24 12:39:56 -07002314 super(clocks, uid, type, timerPool, timeBase, in);
Bookatz867c0d72017-03-07 18:23:42 -08002315 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase, in);
2316 }
2317
2318 /**
Bookatzaa4594a2017-03-24 12:39:56 -07002319 * Creates a DualTimer to hold a main timer (this) and a mSubTimer.
2320 * The main timer (this) is based on the given timeBase and timerPool.
Bookatz867c0d72017-03-07 18:23:42 -08002321 * The mSubTimer is based on the given subTimeBase. The mSubTimer is not pooled, even if
Bookatzaa4594a2017-03-24 12:39:56 -07002322 * the main timer is.
Bookatz867c0d72017-03-07 18:23:42 -08002323 */
2324 public DualTimer(Clocks clocks, Uid uid, int type, ArrayList<StopwatchTimer> timerPool,
2325 TimeBase timeBase, TimeBase subTimeBase) {
Bookatzaa4594a2017-03-24 12:39:56 -07002326 super(clocks, uid, type, timerPool, timeBase);
Bookatz867c0d72017-03-07 18:23:42 -08002327 mSubTimer = new DurationTimer(clocks, uid, type, null, subTimeBase);
2328 }
2329
Bookatz867c0d72017-03-07 18:23:42 -08002330 /** Get the secondary timer. */
Bookatzaa4594a2017-03-24 12:39:56 -07002331 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002332 public DurationTimer getSubTimer() {
2333 return mSubTimer;
2334 }
2335
Bookatzaa4594a2017-03-24 12:39:56 -07002336 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002337 public void startRunningLocked(long elapsedRealtimeMs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002338 super.startRunningLocked(elapsedRealtimeMs);
Bookatz867c0d72017-03-07 18:23:42 -08002339 mSubTimer.startRunningLocked(elapsedRealtimeMs);
2340 }
2341
Bookatzaa4594a2017-03-24 12:39:56 -07002342 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002343 public void stopRunningLocked(long elapsedRealtimeMs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002344 super.stopRunningLocked(elapsedRealtimeMs);
Bookatz867c0d72017-03-07 18:23:42 -08002345 mSubTimer.stopRunningLocked(elapsedRealtimeMs);
2346 }
2347
Bookatzaa4594a2017-03-24 12:39:56 -07002348 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002349 public void stopAllRunningLocked(long elapsedRealtimeMs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002350 super.stopAllRunningLocked(elapsedRealtimeMs);
Bookatz867c0d72017-03-07 18:23:42 -08002351 mSubTimer.stopAllRunningLocked(elapsedRealtimeMs);
2352 }
2353
Bookatzaa4594a2017-03-24 12:39:56 -07002354 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002355 public boolean reset(boolean detachIfReset) {
2356 boolean active = false;
Bookatz4a3eda92017-04-10 13:10:46 -07002357 // Do not detach the subTimer explicitly since that'll be done by DualTimer.detach().
2358 active |= !mSubTimer.reset(false);
Bookatzaa4594a2017-03-24 12:39:56 -07002359 active |= !super.reset(detachIfReset);
Bookatz867c0d72017-03-07 18:23:42 -08002360 return !active;
2361 }
2362
Bookatzaa4594a2017-03-24 12:39:56 -07002363 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002364 public void detach() {
Bookatz867c0d72017-03-07 18:23:42 -08002365 mSubTimer.detach();
Bookatz4a3eda92017-04-10 13:10:46 -07002366 super.detach();
Bookatz867c0d72017-03-07 18:23:42 -08002367 }
2368
Bookatzaa4594a2017-03-24 12:39:56 -07002369 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002370 public void writeToParcel(Parcel out, long elapsedRealtimeUs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002371 super.writeToParcel(out, elapsedRealtimeUs);
Bookatz867c0d72017-03-07 18:23:42 -08002372 mSubTimer.writeToParcel(out, elapsedRealtimeUs);
2373 }
2374
Bookatzaa4594a2017-03-24 12:39:56 -07002375 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002376 public void writeSummaryFromParcelLocked(Parcel out, long elapsedRealtimeUs) {
Bookatzaa4594a2017-03-24 12:39:56 -07002377 super.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
Bookatz867c0d72017-03-07 18:23:42 -08002378 mSubTimer.writeSummaryFromParcelLocked(out, elapsedRealtimeUs);
2379 }
2380
Bookatzaa4594a2017-03-24 12:39:56 -07002381 @Override
Bookatz867c0d72017-03-07 18:23:42 -08002382 public void readSummaryFromParcelLocked(Parcel in) {
Bookatzaa4594a2017-03-24 12:39:56 -07002383 super.readSummaryFromParcelLocked(in);
Bookatz867c0d72017-03-07 18:23:42 -08002384 mSubTimer.readSummaryFromParcelLocked(in);
2385 }
2386 }
2387
2388
Dianne Hackbornd953c532014-08-16 18:17:38 -07002389 public abstract class OverflowArrayMap<T> {
2390 private static final String OVERFLOW_NAME = "*overflow*";
2391
Dianne Hackborn657153b2016-07-29 14:54:14 -07002392 final int mUid;
Dianne Hackbornd953c532014-08-16 18:17:38 -07002393 final ArrayMap<String, T> mMap = new ArrayMap<>();
2394 T mCurOverflow;
2395 ArrayMap<String, MutableInt> mActiveOverflow;
Dianne Hackborn657153b2016-07-29 14:54:14 -07002396 long mLastOverflowTime;
2397 long mLastOverflowFinishTime;
2398 long mLastClearTime;
2399 long mLastCleanupTime;
Dianne Hackbornd953c532014-08-16 18:17:38 -07002400
Dianne Hackborn657153b2016-07-29 14:54:14 -07002401 public OverflowArrayMap(int uid) {
2402 mUid = uid;
Dianne Hackbornd953c532014-08-16 18:17:38 -07002403 }
2404
2405 public ArrayMap<String, T> getMap() {
2406 return mMap;
2407 }
2408
2409 public void clear() {
Dianne Hackborn657153b2016-07-29 14:54:14 -07002410 mLastClearTime = SystemClock.elapsedRealtime();
Dianne Hackbornd953c532014-08-16 18:17:38 -07002411 mMap.clear();
2412 mCurOverflow = null;
2413 mActiveOverflow = null;
2414 }
2415
2416 public void add(String name, T obj) {
Joe Onorato388fc332016-04-12 17:06:47 -07002417 if (name == null) {
2418 name = "";
2419 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07002420 mMap.put(name, obj);
2421 if (OVERFLOW_NAME.equals(name)) {
2422 mCurOverflow = obj;
2423 }
2424 }
2425
2426 public void cleanup() {
Dianne Hackborn657153b2016-07-29 14:54:14 -07002427 mLastCleanupTime = SystemClock.elapsedRealtime();
Dianne Hackbornd953c532014-08-16 18:17:38 -07002428 if (mActiveOverflow != null) {
2429 if (mActiveOverflow.size() == 0) {
2430 mActiveOverflow = null;
2431 }
2432 }
2433 if (mActiveOverflow == null) {
2434 // There is no currently active overflow, so we should no longer have
2435 // an overflow entry.
2436 if (mMap.containsKey(OVERFLOW_NAME)) {
2437 Slog.wtf(TAG, "Cleaning up with no active overflow, but have overflow entry "
2438 + mMap.get(OVERFLOW_NAME));
2439 mMap.remove(OVERFLOW_NAME);
2440 }
2441 mCurOverflow = null;
2442 } else {
2443 // There is currently active overflow, so we should still have an overflow entry.
2444 if (mCurOverflow == null || !mMap.containsKey(OVERFLOW_NAME)) {
2445 Slog.wtf(TAG, "Cleaning up with active overflow, but no overflow entry: cur="
2446 + mCurOverflow + " map=" + mMap.get(OVERFLOW_NAME));
2447 }
2448 }
2449 }
2450
2451 public T startObject(String name) {
Joe Onorato388fc332016-04-12 17:06:47 -07002452 if (name == null) {
2453 name = "";
2454 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07002455 T obj = mMap.get(name);
2456 if (obj != null) {
2457 return obj;
2458 }
2459
2460 // No object exists for the given name, but do we currently have it
2461 // running as part of the overflow?
2462 if (mActiveOverflow != null) {
2463 MutableInt over = mActiveOverflow.get(name);
2464 if (over != null) {
2465 // We are already actively counting this name in the overflow object.
2466 obj = mCurOverflow;
2467 if (obj == null) {
2468 // Shouldn't be here, but we'll try to recover.
2469 Slog.wtf(TAG, "Have active overflow " + name + " but null overflow");
2470 obj = mCurOverflow = instantiateObject();
2471 mMap.put(OVERFLOW_NAME, obj);
2472 }
2473 over.value++;
2474 return obj;
2475 }
2476 }
2477
2478 // No object exists for given name nor in the overflow; we need to make
2479 // a new one.
2480 final int N = mMap.size();
2481 if (N >= MAX_WAKELOCKS_PER_UID) {
2482 // Went over the limit on number of objects to track; this one goes
2483 // in to the overflow.
2484 obj = mCurOverflow;
2485 if (obj == null) {
2486 // Need to start overflow now...
2487 obj = mCurOverflow = instantiateObject();
2488 mMap.put(OVERFLOW_NAME, obj);
2489 }
2490 if (mActiveOverflow == null) {
2491 mActiveOverflow = new ArrayMap<>();
2492 }
2493 mActiveOverflow.put(name, new MutableInt(1));
Dianne Hackborn657153b2016-07-29 14:54:14 -07002494 mLastOverflowTime = SystemClock.elapsedRealtime();
Dianne Hackbornd953c532014-08-16 18:17:38 -07002495 return obj;
2496 }
2497
2498 // Normal case where we just need to make a new object.
2499 obj = instantiateObject();
2500 mMap.put(name, obj);
2501 return obj;
2502 }
2503
2504 public T stopObject(String name) {
Joe Onorato388fc332016-04-12 17:06:47 -07002505 if (name == null) {
2506 name = "";
2507 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07002508 T obj = mMap.get(name);
2509 if (obj != null) {
2510 return obj;
2511 }
2512
2513 // No object exists for the given name, but do we currently have it
2514 // running as part of the overflow?
2515 if (mActiveOverflow != null) {
2516 MutableInt over = mActiveOverflow.get(name);
2517 if (over != null) {
2518 // We are already actively counting this name in the overflow object.
2519 obj = mCurOverflow;
2520 if (obj != null) {
2521 over.value--;
2522 if (over.value <= 0) {
2523 mActiveOverflow.remove(name);
Dianne Hackborn657153b2016-07-29 14:54:14 -07002524 mLastOverflowFinishTime = SystemClock.elapsedRealtime();
Dianne Hackbornd953c532014-08-16 18:17:38 -07002525 }
2526 return obj;
2527 }
2528 }
2529 }
2530
2531 // Huh, they are stopping an active operation but we can't find one!
2532 // That's not good.
Dianne Hackborn657153b2016-07-29 14:54:14 -07002533 StringBuilder sb = new StringBuilder();
2534 sb.append("Unable to find object for ");
2535 sb.append(name);
2536 sb.append(" in uid ");
2537 sb.append(mUid);
2538 sb.append(" mapsize=");
2539 sb.append(mMap.size());
2540 sb.append(" activeoverflow=");
2541 sb.append(mActiveOverflow);
2542 sb.append(" curoverflow=");
2543 sb.append(mCurOverflow);
2544 long now = SystemClock.elapsedRealtime();
2545 if (mLastOverflowTime != 0) {
2546 sb.append(" lastOverflowTime=");
2547 TimeUtils.formatDuration(mLastOverflowTime-now, sb);
2548 }
2549 if (mLastOverflowFinishTime != 0) {
2550 sb.append(" lastOverflowFinishTime=");
2551 TimeUtils.formatDuration(mLastOverflowFinishTime-now, sb);
2552 }
2553 if (mLastClearTime != 0) {
2554 sb.append(" lastClearTime=");
2555 TimeUtils.formatDuration(mLastClearTime-now, sb);
2556 }
2557 if (mLastCleanupTime != 0) {
2558 sb.append(" lastCleanupTime=");
2559 TimeUtils.formatDuration(mLastCleanupTime-now, sb);
2560 }
2561 Slog.wtf(TAG, sb.toString());
Dianne Hackbornd953c532014-08-16 18:17:38 -07002562 return null;
2563 }
2564
2565 public abstract T instantiateObject();
2566 }
2567
Adam Lesinski21f76aa2016-01-25 12:27:06 -08002568 public static class ControllerActivityCounterImpl extends ControllerActivityCounter
2569 implements Parcelable {
2570 private final LongSamplingCounter mIdleTimeMillis;
2571 private final LongSamplingCounter mRxTimeMillis;
2572 private final LongSamplingCounter[] mTxTimeMillis;
2573 private final LongSamplingCounter mPowerDrainMaMs;
2574
2575 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates) {
2576 mIdleTimeMillis = new LongSamplingCounter(timeBase);
2577 mRxTimeMillis = new LongSamplingCounter(timeBase);
2578 mTxTimeMillis = new LongSamplingCounter[numTxStates];
2579 for (int i = 0; i < numTxStates; i++) {
2580 mTxTimeMillis[i] = new LongSamplingCounter(timeBase);
2581 }
2582 mPowerDrainMaMs = new LongSamplingCounter(timeBase);
2583 }
2584
2585 public ControllerActivityCounterImpl(TimeBase timeBase, int numTxStates, Parcel in) {
2586 mIdleTimeMillis = new LongSamplingCounter(timeBase, in);
2587 mRxTimeMillis = new LongSamplingCounter(timeBase, in);
2588 final int recordedTxStates = in.readInt();
2589 if (recordedTxStates != numTxStates) {
2590 throw new ParcelFormatException("inconsistent tx state lengths");
2591 }
2592
2593 mTxTimeMillis = new LongSamplingCounter[numTxStates];
2594 for (int i = 0; i < numTxStates; i++) {
2595 mTxTimeMillis[i] = new LongSamplingCounter(timeBase, in);
2596 }
2597 mPowerDrainMaMs = new LongSamplingCounter(timeBase, in);
2598 }
2599
2600 public void readSummaryFromParcel(Parcel in) {
2601 mIdleTimeMillis.readSummaryFromParcelLocked(in);
2602 mRxTimeMillis.readSummaryFromParcelLocked(in);
2603 final int recordedTxStates = in.readInt();
2604 if (recordedTxStates != mTxTimeMillis.length) {
2605 throw new ParcelFormatException("inconsistent tx state lengths");
2606 }
2607 for (LongSamplingCounter counter : mTxTimeMillis) {
2608 counter.readSummaryFromParcelLocked(in);
2609 }
2610 mPowerDrainMaMs.readSummaryFromParcelLocked(in);
2611 }
2612
2613 @Override
2614 public int describeContents() {
2615 return 0;
2616 }
2617
2618 public void writeSummaryToParcel(Parcel dest) {
2619 mIdleTimeMillis.writeSummaryFromParcelLocked(dest);
2620 mRxTimeMillis.writeSummaryFromParcelLocked(dest);
2621 dest.writeInt(mTxTimeMillis.length);
2622 for (LongSamplingCounter counter : mTxTimeMillis) {
2623 counter.writeSummaryFromParcelLocked(dest);
2624 }
2625 mPowerDrainMaMs.writeSummaryFromParcelLocked(dest);
2626 }
2627
2628 @Override
2629 public void writeToParcel(Parcel dest, int flags) {
2630 mIdleTimeMillis.writeToParcel(dest);
2631 mRxTimeMillis.writeToParcel(dest);
2632 dest.writeInt(mTxTimeMillis.length);
2633 for (LongSamplingCounter counter : mTxTimeMillis) {
2634 counter.writeToParcel(dest);
2635 }
2636 mPowerDrainMaMs.writeToParcel(dest);
2637 }
2638
2639 public void reset(boolean detachIfReset) {
2640 mIdleTimeMillis.reset(detachIfReset);
2641 mRxTimeMillis.reset(detachIfReset);
2642 for (LongSamplingCounter counter : mTxTimeMillis) {
2643 counter.reset(detachIfReset);
2644 }
2645 mPowerDrainMaMs.reset(detachIfReset);
2646 }
2647
2648 public void detach() {
2649 mIdleTimeMillis.detach();
2650 mRxTimeMillis.detach();
2651 for (LongSamplingCounter counter : mTxTimeMillis) {
2652 counter.detach();
2653 }
2654 mPowerDrainMaMs.detach();
2655 }
2656
2657 /**
2658 * @return a LongSamplingCounter, measuring time spent in the idle state in
2659 * milliseconds.
2660 */
2661 @Override
2662 public LongSamplingCounter getIdleTimeCounter() {
Roshan Pius81643302016-03-14 16:45:55 -07002663 return mIdleTimeMillis;
Adam Lesinski21f76aa2016-01-25 12:27:06 -08002664 }
2665
2666 /**
2667 * @return a LongSamplingCounter, measuring time spent in the receive state in
2668 * milliseconds.
2669 */
2670 @Override
2671 public LongSamplingCounter getRxTimeCounter() {
2672 return mRxTimeMillis;
2673 }
2674
2675 /**
2676 * @return a LongSamplingCounter[], measuring time spent in various transmit states in
2677 * milliseconds.
2678 */
2679 @Override
2680 public LongSamplingCounter[] getTxTimeCounters() {
2681 return mTxTimeMillis;
2682 }
2683
2684 /**
2685 * @return a LongSamplingCounter, measuring power use in milli-ampere milliseconds (mAmS).
2686 */
2687 @Override
2688 public LongSamplingCounter getPowerCounter() {
2689 return mPowerDrainMaMs;
2690 }
2691 }
2692
Bookatz50df7112017-08-04 14:53:26 -07002693 /** Get Resource Power Manager stats. Create a new one if it doesn't already exist. */
2694 public SamplingTimer getRpmTimerLocked(String name) {
2695 SamplingTimer rpmt = mRpmStats.get(name);
2696 if (rpmt == null) {
2697 rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase);
2698 mRpmStats.put(name, rpmt);
2699 }
2700 return rpmt;
2701 }
2702
2703 /** Get Screen-off Resource Power Manager stats. Create new one if it doesn't already exist. */
2704 public SamplingTimer getScreenOffRpmTimerLocked(String name) {
2705 SamplingTimer rpmt = mScreenOffRpmStats.get(name);
2706 if (rpmt == null) {
2707 rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase);
2708 mScreenOffRpmStats.put(name, rpmt);
2709 }
2710 return rpmt;
2711 }
2712
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002713 /*
2714 * Get the wakeup reason counter, and create a new one if one
2715 * doesn't already exist.
2716 */
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002717 public SamplingTimer getWakeupReasonTimerLocked(String name) {
2718 SamplingTimer timer = mWakeupReasonStats.get(name);
2719 if (timer == null) {
Adam Lesinski757c6ea2016-04-21 09:55:41 -07002720 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase);
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002721 mWakeupReasonStats.put(name, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002722 }
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07002723 return timer;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002724 }
2725
Evan Millarc64edde2009-04-18 12:26:32 -07002726 /*
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07002727 * Get the KernelWakelockTimer associated with name, and create a new one if one
Evan Millarc64edde2009-04-18 12:26:32 -07002728 * doesn't already exist.
2729 */
2730 public SamplingTimer getKernelWakelockTimerLocked(String name) {
2731 SamplingTimer kwlt = mKernelWakelockStats.get(name);
2732 if (kwlt == null) {
Adam Lesinski757c6ea2016-04-21 09:55:41 -07002733 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase);
Evan Millarc64edde2009-04-18 12:26:32 -07002734 mKernelWakelockStats.put(name, kwlt);
2735 }
2736 return kwlt;
2737 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07002738
James Carr3a226052016-07-01 14:49:52 -07002739 public SamplingTimer getKernelMemoryTimerLocked(long bucket) {
2740 SamplingTimer kmt = mKernelMemoryStats.get(bucket);
2741 if (kmt == null) {
2742 kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase);
2743 mKernelMemoryStats.put(bucket, kmt);
2744 }
2745 return kmt;
2746 }
2747
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002748 private int writeHistoryTag(HistoryTag tag) {
2749 Integer idxObj = mHistoryTagPool.get(tag);
2750 int idx;
2751 if (idxObj != null) {
2752 idx = idxObj;
2753 } else {
2754 idx = mNextHistoryTagIdx;
2755 HistoryTag key = new HistoryTag();
2756 key.setTo(tag);
2757 tag.poolIdx = idx;
2758 mHistoryTagPool.put(key, idx);
2759 mNextHistoryTagIdx++;
2760 mNumHistoryTagChars += key.string.length() + 1;
2761 }
2762 return idx;
2763 }
2764
2765 private void readHistoryTag(int index, HistoryTag tag) {
2766 tag.string = mReadHistoryStrings[index];
2767 tag.uid = mReadHistoryUids[index];
2768 tag.poolIdx = index;
2769 }
2770
Adam Lesinski926969b2016-04-28 17:31:12 -07002771 /*
2772 The history delta format uses flags to denote further data in subsequent ints in the parcel.
2773
2774 There is always the first token, which may contain the delta time, or an indicator of
2775 the length of the time (int or long) following this token.
2776
2777 First token: always present,
2778 31 23 15 7 0
2779 â–ˆ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â–ˆ
2780
2781 T: the delta time if it is <= 0x7fffd. Otherwise 0x7fffe indicates an int immediately
2782 follows containing the time, and 0x7ffff indicates a long immediately follows with the
2783 delta time.
2784 A: battery level changed and an int follows with battery data.
2785 B: state changed and an int follows with state change data.
2786 C: state2 has changed and an int follows with state2 change data.
2787 D: wakelock/wakereason has changed and an wakelock/wakereason struct follows.
2788 E: event data has changed and an event struct follows.
2789 F: battery charge in coulombs has changed and an int with the charge follows.
2790 G: state flag denoting that the mobile radio was active.
2791 H: state flag denoting that the wifi radio was active.
2792 I: state flag denoting that a wifi scan occurred.
2793 J: state flag denoting that a wifi full lock was held.
2794 K: state flag denoting that the gps was on.
2795 L: state flag denoting that a wakelock was held.
2796 M: state flag denoting that the cpu was running.
2797
2798 Time int/long: if T in the first token is 0x7ffff or 0x7fffe, then an int or long follows
2799 with the time delta.
2800
2801 Battery level int: if A in the first token is set,
2802 31 23 15 7 0
2803 â–ˆ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â–ˆ
2804
2805 D: indicates that extra history details follow.
2806 V: the battery voltage.
2807 T: the battery temperature.
2808 L: the battery level (out of 100).
2809
2810 State change int: if B in the first token is set,
2811 31 23 15 7 0
2812 â–ˆS|S|S|H|H|H|P|Pâ–ˆF|E|D|C|B| | |Aâ–ˆ | | | | | | | â–ˆ | | | | | | | â–ˆ
2813
2814 A: wifi multicast was on.
2815 B: battery was plugged in.
2816 C: screen was on.
2817 D: phone was scanning for signal.
2818 E: audio was on.
2819 F: a sensor was active.
2820
2821 State2 change int: if C in the first token is set,
2822 31 23 15 7 0
2823 â–ˆM|L|K|J|I|H|H|Gâ–ˆF|E|D|C| | | | â–ˆ | | | | | | | â–ˆ |B|B|B|A|A|A|Aâ–ˆ
2824
2825 A: 4 bits indicating the wifi supplicant state: {@link BatteryStats#WIFI_SUPPL_STATE_NAMES}.
2826 B: 3 bits indicating the wifi signal strength: 0, 1, 2, 3, 4.
2827 C: a bluetooth scan was active.
2828 D: the camera was active.
2829 E: bluetooth was on.
2830 F: a phone call was active.
2831 G: the device was charging.
2832 H: 2 bits indicating the device-idle (doze) state: off, light, full
2833 I: the flashlight was on.
2834 J: wifi was on.
2835 K: wifi was running.
2836 L: video was playing.
2837 M: power save mode was on.
2838
2839 Wakelock/wakereason struct: if D in the first token is set,
2840 TODO(adamlesinski): describe wakelock/wakereason struct.
2841
2842 Event struct: if E in the first token is set,
2843 TODO(adamlesinski): describe the event struct.
2844
2845 History step details struct: if D in the battery level int is set,
2846 TODO(adamlesinski): describe the history step details struct.
2847
2848 Battery charge int: if F in the first token is set, an int representing the battery charge
2849 in coulombs follows.
2850 */
2851
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002852 // Part of initial delta int that specifies the time delta.
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002853 static final int DELTA_TIME_MASK = 0x7ffff;
2854 static final int DELTA_TIME_LONG = 0x7ffff; // The delta is a following long
2855 static final int DELTA_TIME_INT = 0x7fffe; // The delta is a following int
2856 static final int DELTA_TIME_ABS = 0x7fffd; // Following is an entire abs update.
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002857 // Flag in delta int: a new battery level int follows.
Adam Lesinski926969b2016-04-28 17:31:12 -07002858 static final int DELTA_BATTERY_LEVEL_FLAG = 0x00080000;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002859 // Flag in delta int: a new full state and battery status int follows.
Adam Lesinski926969b2016-04-28 17:31:12 -07002860 static final int DELTA_STATE_FLAG = 0x00100000;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08002861 // Flag in delta int: a new full state2 int follows.
Adam Lesinski926969b2016-04-28 17:31:12 -07002862 static final int DELTA_STATE2_FLAG = 0x00200000;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002863 // Flag in delta int: contains a wakelock or wakeReason tag.
Adam Lesinski926969b2016-04-28 17:31:12 -07002864 static final int DELTA_WAKELOCK_FLAG = 0x00400000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002865 // Flag in delta int: contains an event description.
Adam Lesinski926969b2016-04-28 17:31:12 -07002866 static final int DELTA_EVENT_FLAG = 0x00800000;
Adam Lesinskia8018ac2016-05-03 10:18:10 -07002867 // Flag in delta int: contains the battery charge count in uAh.
2868 static final int DELTA_BATTERY_CHARGE_FLAG = 0x01000000;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002869 // These upper bits are the frequently changing state bits.
Adam Lesinski926969b2016-04-28 17:31:12 -07002870 static final int DELTA_STATE_MASK = 0xfe000000;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002871
2872 // These are the pieces of battery state that are packed in to the upper bits of
2873 // the state int that have been packed in to the first delta int. They must fit
Adam Lesinski926969b2016-04-28 17:31:12 -07002874 // in STATE_BATTERY_MASK.
2875 static final int STATE_BATTERY_MASK = 0xff000000;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08002876 static final int STATE_BATTERY_STATUS_MASK = 0x00000007;
2877 static final int STATE_BATTERY_STATUS_SHIFT = 29;
2878 static final int STATE_BATTERY_HEALTH_MASK = 0x00000007;
2879 static final int STATE_BATTERY_HEALTH_SHIFT = 26;
2880 static final int STATE_BATTERY_PLUG_MASK = 0x00000003;
2881 static final int STATE_BATTERY_PLUG_SHIFT = 24;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002882
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002883 // We use the low bit of the battery state int to indicate that we have full details
2884 // from a battery level change.
2885 static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001;
2886
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002887 public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002888 if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002889 dest.writeInt(DELTA_TIME_ABS);
2890 cur.writeToParcel(dest, 0);
2891 return;
2892 }
2893
2894 final long deltaTime = cur.time - last.time;
2895 final int lastBatteryLevelInt = buildBatteryLevelInt(last);
2896 final int lastStateInt = buildStateInt(last);
2897
2898 int deltaTimeToken;
2899 if (deltaTime < 0 || deltaTime > Integer.MAX_VALUE) {
2900 deltaTimeToken = DELTA_TIME_LONG;
2901 } else if (deltaTime >= DELTA_TIME_ABS) {
2902 deltaTimeToken = DELTA_TIME_INT;
2903 } else {
2904 deltaTimeToken = (int)deltaTime;
2905 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002906 int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002907 final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel
2908 ? BATTERY_DELTA_LEVEL_FLAG : 0;
2909 final boolean computeStepDetails = includeStepDetails != 0
2910 || mLastHistoryStepDetails == null;
2911 final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002912 final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt;
2913 if (batteryLevelIntChanged) {
2914 firstToken |= DELTA_BATTERY_LEVEL_FLAG;
2915 }
2916 final int stateInt = buildStateInt(cur);
2917 final boolean stateIntChanged = stateInt != lastStateInt;
2918 if (stateIntChanged) {
2919 firstToken |= DELTA_STATE_FLAG;
2920 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002921 final boolean state2IntChanged = cur.states2 != last.states2;
2922 if (state2IntChanged) {
2923 firstToken |= DELTA_STATE2_FLAG;
2924 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002925 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002926 firstToken |= DELTA_WAKELOCK_FLAG;
2927 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002928 if (cur.eventCode != HistoryItem.EVENT_NONE) {
2929 firstToken |= DELTA_EVENT_FLAG;
2930 }
Adam Lesinski926969b2016-04-28 17:31:12 -07002931
Adam Lesinskia8018ac2016-05-03 10:18:10 -07002932 final boolean batteryChargeChanged = cur.batteryChargeUAh != last.batteryChargeUAh;
2933 if (batteryChargeChanged) {
2934 firstToken |= DELTA_BATTERY_CHARGE_FLAG;
Adam Lesinski926969b2016-04-28 17:31:12 -07002935 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002936 dest.writeInt(firstToken);
2937 if (DEBUG) Slog.i(TAG, "WRITE DELTA: firstToken=0x" + Integer.toHexString(firstToken)
2938 + " deltaTime=" + deltaTime);
2939
2940 if (deltaTimeToken >= DELTA_TIME_INT) {
2941 if (deltaTimeToken == DELTA_TIME_INT) {
2942 if (DEBUG) Slog.i(TAG, "WRITE DELTA: int deltaTime=" + (int)deltaTime);
2943 dest.writeInt((int)deltaTime);
2944 } else {
2945 if (DEBUG) Slog.i(TAG, "WRITE DELTA: long deltaTime=" + deltaTime);
2946 dest.writeLong(deltaTime);
2947 }
2948 }
2949 if (batteryLevelIntChanged) {
2950 dest.writeInt(batteryLevelInt);
2951 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryToken=0x"
2952 + Integer.toHexString(batteryLevelInt)
2953 + " batteryLevel=" + cur.batteryLevel
2954 + " batteryTemp=" + cur.batteryTemperature
2955 + " batteryVolt=" + (int)cur.batteryVoltage);
2956 }
2957 if (stateIntChanged) {
2958 dest.writeInt(stateInt);
2959 if (DEBUG) Slog.i(TAG, "WRITE DELTA: stateToken=0x"
2960 + Integer.toHexString(stateInt)
2961 + " batteryStatus=" + cur.batteryStatus
2962 + " batteryHealth=" + cur.batteryHealth
2963 + " batteryPlugType=" + cur.batteryPlugType
2964 + " states=0x" + Integer.toHexString(cur.states));
2965 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07002966 if (state2IntChanged) {
2967 dest.writeInt(cur.states2);
2968 if (DEBUG) Slog.i(TAG, "WRITE DELTA: states2=0x"
2969 + Integer.toHexString(cur.states2));
2970 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08002971 if (cur.wakelockTag != null || cur.wakeReasonTag != null) {
2972 int wakeLockIndex;
2973 int wakeReasonIndex;
2974 if (cur.wakelockTag != null) {
2975 wakeLockIndex = writeHistoryTag(cur.wakelockTag);
2976 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
2977 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
2978 } else {
2979 wakeLockIndex = 0xffff;
2980 }
2981 if (cur.wakeReasonTag != null) {
2982 wakeReasonIndex = writeHistoryTag(cur.wakeReasonTag);
2983 if (DEBUG) Slog.i(TAG, "WRITE DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
2984 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
2985 } else {
2986 wakeReasonIndex = 0xffff;
2987 }
2988 dest.writeInt((wakeReasonIndex<<16) | wakeLockIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002989 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08002990 if (cur.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002991 int index = writeHistoryTag(cur.eventTag);
2992 int codeAndIndex = (cur.eventCode&0xffff) | (index<<16);
Dianne Hackborn099bc622014-01-22 13:39:16 -08002993 dest.writeInt(codeAndIndex);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08002994 if (DEBUG) Slog.i(TAG, "WRITE DELTA: event=" + cur.eventCode + " tag=#"
2995 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
2996 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08002997 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08002998 if (computeStepDetails) {
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07002999 if (mPlatformIdleStateCallback != null) {
3000 mCurHistoryStepDetails.statPlatformIdleState =
3001 mPlatformIdleStateCallback.getPlatformLowPowerStats();
3002 if (DEBUG) Slog.i(TAG, "WRITE PlatformIdleState:" +
3003 mCurHistoryStepDetails.statPlatformIdleState);
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +00003004
3005 mCurHistoryStepDetails.statSubsystemPowerState =
3006 mPlatformIdleStateCallback.getSubsystemLowPowerStats();
3007 if (DEBUG) Slog.i(TAG, "WRITE SubsystemPowerState:" +
3008 mCurHistoryStepDetails.statSubsystemPowerState);
3009
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07003010 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003011 computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails);
3012 if (includeStepDetails != 0) {
3013 mCurHistoryStepDetails.writeToParcel(dest);
3014 }
3015 cur.stepDetails = mCurHistoryStepDetails;
3016 mLastHistoryStepDetails = mCurHistoryStepDetails;
3017 } else {
3018 cur.stepDetails = null;
3019 }
3020 if (mLastHistoryStepLevel < cur.batteryLevel) {
3021 mLastHistoryStepDetails = null;
3022 }
3023 mLastHistoryStepLevel = cur.batteryLevel;
Adam Lesinski926969b2016-04-28 17:31:12 -07003024
Adam Lesinskia8018ac2016-05-03 10:18:10 -07003025 if (batteryChargeChanged) {
3026 if (DEBUG) Slog.i(TAG, "WRITE DELTA: batteryChargeUAh=" + cur.batteryChargeUAh);
3027 dest.writeInt(cur.batteryChargeUAh);
Adam Lesinski926969b2016-04-28 17:31:12 -07003028 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003029 }
3030
3031 private int buildBatteryLevelInt(HistoryItem h) {
3032 return ((((int)h.batteryLevel)<<25)&0xfe000000)
Adam Lesinski3944c812015-11-13 15:54:59 -08003033 | ((((int)h.batteryTemperature)<<15)&0x01ff8000)
3034 | ((((int)h.batteryVoltage)<<1)&0x00007ffe);
3035 }
3036
3037 private void readBatteryLevelInt(int batteryLevelInt, HistoryItem out) {
3038 out.batteryLevel = (byte)((batteryLevelInt & 0xfe000000) >>> 25);
3039 out.batteryTemperature = (short)((batteryLevelInt & 0x01ff8000) >>> 15);
3040 out.batteryVoltage = (char)((batteryLevelInt & 0x00007ffe) >>> 1);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003041 }
3042
3043 private int buildStateInt(HistoryItem h) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08003044 int plugType = 0;
3045 if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_AC) != 0) {
3046 plugType = 1;
3047 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_USB) != 0) {
3048 plugType = 2;
3049 } else if ((h.batteryPlugType&BatteryManager.BATTERY_PLUGGED_WIRELESS) != 0) {
3050 plugType = 3;
3051 }
3052 return ((h.batteryStatus&STATE_BATTERY_STATUS_MASK)<<STATE_BATTERY_STATUS_SHIFT)
3053 | ((h.batteryHealth&STATE_BATTERY_HEALTH_MASK)<<STATE_BATTERY_HEALTH_SHIFT)
3054 | ((plugType&STATE_BATTERY_PLUG_MASK)<<STATE_BATTERY_PLUG_SHIFT)
Adam Lesinski926969b2016-04-28 17:31:12 -07003055 | (h.states&(~STATE_BATTERY_MASK));
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003056 }
3057
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003058 private void computeHistoryStepDetails(final HistoryStepDetails out,
3059 final HistoryStepDetails last) {
3060 final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out;
3061
3062 // Perform a CPU update right after we do this collection, so we have started
3063 // collecting good data for the next step.
3064 requestImmediateCpuUpdate();
3065
3066 if (last == null) {
3067 // We are not generating a delta, so all we need to do is reset the stats
3068 // we will later be doing a delta from.
3069 final int NU = mUidStats.size();
3070 for (int i=0; i<NU; i++) {
3071 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3072 uid.mLastStepUserTime = uid.mCurStepUserTime;
3073 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
3074 }
3075 mLastStepCpuUserTime = mCurStepCpuUserTime;
3076 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
3077 mLastStepStatUserTime = mCurStepStatUserTime;
3078 mLastStepStatSystemTime = mCurStepStatSystemTime;
3079 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
3080 mLastStepStatIrqTime = mCurStepStatIrqTime;
3081 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
3082 mLastStepStatIdleTime = mCurStepStatIdleTime;
3083 tmp.clear();
3084 return;
3085 }
3086 if (DEBUG) {
3087 Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys="
3088 + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime
3089 + " irq=" + mLastStepStatIrqTime + " sirq="
3090 + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime);
3091 Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys="
3092 + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime
3093 + " irq=" + mCurStepStatIrqTime + " sirq="
3094 + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime);
3095 }
3096 out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime);
3097 out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime);
3098 out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime);
3099 out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime);
3100 out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime);
3101 out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime);
3102 out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime);
3103 out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime);
3104 out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1;
3105 out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0;
3106 out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0;
3107 final int NU = mUidStats.size();
3108 for (int i=0; i<NU; i++) {
3109 final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
3110 final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime);
3111 final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime);
3112 final int totalTime = totalUTime + totalSTime;
3113 uid.mLastStepUserTime = uid.mCurStepUserTime;
3114 uid.mLastStepSystemTime = uid.mCurStepSystemTime;
3115 if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) {
3116 continue;
3117 }
3118 if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) {
3119 out.appCpuUid3 = uid.mUid;
3120 out.appCpuUTime3 = totalUTime;
3121 out.appCpuSTime3 = totalSTime;
3122 } else {
3123 out.appCpuUid3 = out.appCpuUid2;
3124 out.appCpuUTime3 = out.appCpuUTime2;
3125 out.appCpuSTime3 = out.appCpuSTime2;
3126 if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) {
3127 out.appCpuUid2 = uid.mUid;
3128 out.appCpuUTime2 = totalUTime;
3129 out.appCpuSTime2 = totalSTime;
3130 } else {
3131 out.appCpuUid2 = out.appCpuUid1;
3132 out.appCpuUTime2 = out.appCpuUTime1;
3133 out.appCpuSTime2 = out.appCpuSTime1;
3134 out.appCpuUid1 = uid.mUid;
3135 out.appCpuUTime1 = totalUTime;
3136 out.appCpuSTime1 = totalSTime;
3137 }
3138 }
3139 }
3140 mLastStepCpuUserTime = mCurStepCpuUserTime;
3141 mLastStepCpuSystemTime = mCurStepCpuSystemTime;
3142 mLastStepStatUserTime = mCurStepStatUserTime;
3143 mLastStepStatSystemTime = mCurStepStatSystemTime;
3144 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime;
3145 mLastStepStatIrqTime = mCurStepStatIrqTime;
3146 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime;
3147 mLastStepStatIdleTime = mCurStepStatIdleTime;
3148 }
3149
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003150 public void readHistoryDelta(Parcel src, HistoryItem cur) {
3151 int firstToken = src.readInt();
3152 int deltaTimeToken = firstToken&DELTA_TIME_MASK;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003153 cur.cmd = HistoryItem.CMD_UPDATE;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003154 cur.numReadInts = 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003155 if (DEBUG) Slog.i(TAG, "READ DELTA: firstToken=0x" + Integer.toHexString(firstToken)
3156 + " deltaTimeToken=" + deltaTimeToken);
3157
3158 if (deltaTimeToken < DELTA_TIME_ABS) {
3159 cur.time += deltaTimeToken;
3160 } else if (deltaTimeToken == DELTA_TIME_ABS) {
3161 cur.time = src.readLong();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003162 cur.numReadInts += 2;
3163 if (DEBUG) Slog.i(TAG, "READ DELTA: ABS time=" + cur.time);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003164 cur.readFromParcel(src);
3165 return;
3166 } else if (deltaTimeToken == DELTA_TIME_INT) {
3167 int delta = src.readInt();
3168 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003169 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003170 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
3171 } else {
3172 long delta = src.readLong();
3173 if (DEBUG) Slog.i(TAG, "READ DELTA: time delta=" + delta + " new time=" + cur.time);
3174 cur.time += delta;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003175 cur.numReadInts += 2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003176 }
3177
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003178 final int batteryLevelInt;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003179 if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003180 batteryLevelInt = src.readInt();
Adam Lesinski3944c812015-11-13 15:54:59 -08003181 readBatteryLevelInt(batteryLevelInt, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003182 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003183 if (DEBUG) Slog.i(TAG, "READ DELTA: batteryToken=0x"
3184 + Integer.toHexString(batteryLevelInt)
3185 + " batteryLevel=" + cur.batteryLevel
3186 + " batteryTemp=" + cur.batteryTemperature
3187 + " batteryVolt=" + (int)cur.batteryVoltage);
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003188 } else {
3189 batteryLevelInt = 0;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003190 }
3191
3192 if ((firstToken&DELTA_STATE_FLAG) != 0) {
3193 int stateInt = src.readInt();
Adam Lesinski926969b2016-04-28 17:31:12 -07003194 cur.states = (firstToken&DELTA_STATE_MASK) | (stateInt&(~STATE_BATTERY_MASK));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08003195 cur.batteryStatus = (byte)((stateInt>>STATE_BATTERY_STATUS_SHIFT)
3196 & STATE_BATTERY_STATUS_MASK);
3197 cur.batteryHealth = (byte)((stateInt>>STATE_BATTERY_HEALTH_SHIFT)
3198 & STATE_BATTERY_HEALTH_MASK);
3199 cur.batteryPlugType = (byte)((stateInt>>STATE_BATTERY_PLUG_SHIFT)
3200 & STATE_BATTERY_PLUG_MASK);
3201 switch (cur.batteryPlugType) {
3202 case 1:
3203 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_AC;
3204 break;
3205 case 2:
3206 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_USB;
3207 break;
3208 case 3:
3209 cur.batteryPlugType = BatteryManager.BATTERY_PLUGGED_WIRELESS;
3210 break;
3211 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003212 cur.numReadInts += 1;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003213 if (DEBUG) Slog.i(TAG, "READ DELTA: stateToken=0x"
3214 + Integer.toHexString(stateInt)
3215 + " batteryStatus=" + cur.batteryStatus
3216 + " batteryHealth=" + cur.batteryHealth
3217 + " batteryPlugType=" + cur.batteryPlugType
3218 + " states=0x" + Integer.toHexString(cur.states));
3219 } else {
Adam Lesinski926969b2016-04-28 17:31:12 -07003220 cur.states = (firstToken&DELTA_STATE_MASK) | (cur.states&(~STATE_BATTERY_MASK));
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003221 }
3222
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003223 if ((firstToken&DELTA_STATE2_FLAG) != 0) {
3224 cur.states2 = src.readInt();
3225 if (DEBUG) Slog.i(TAG, "READ DELTA: states2=0x"
3226 + Integer.toHexString(cur.states2));
3227 }
3228
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003229 if ((firstToken&DELTA_WAKELOCK_FLAG) != 0) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003230 int indexes = src.readInt();
3231 int wakeLockIndex = indexes&0xffff;
3232 int wakeReasonIndex = (indexes>>16)&0xffff;
3233 if (wakeLockIndex != 0xffff) {
3234 cur.wakelockTag = cur.localWakelockTag;
3235 readHistoryTag(wakeLockIndex, cur.wakelockTag);
3236 if (DEBUG) Slog.i(TAG, "READ DELTA: wakelockTag=#" + cur.wakelockTag.poolIdx
3237 + " " + cur.wakelockTag.uid + ":" + cur.wakelockTag.string);
3238 } else {
3239 cur.wakelockTag = null;
3240 }
3241 if (wakeReasonIndex != 0xffff) {
3242 cur.wakeReasonTag = cur.localWakeReasonTag;
3243 readHistoryTag(wakeReasonIndex, cur.wakeReasonTag);
3244 if (DEBUG) Slog.i(TAG, "READ DELTA: wakeReasonTag=#" + cur.wakeReasonTag.poolIdx
3245 + " " + cur.wakeReasonTag.uid + ":" + cur.wakeReasonTag.string);
3246 } else {
3247 cur.wakeReasonTag = null;
3248 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003249 cur.numReadInts += 1;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003250 } else {
3251 cur.wakelockTag = null;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003252 cur.wakeReasonTag = null;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003253 }
3254
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003255 if ((firstToken&DELTA_EVENT_FLAG) != 0) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003256 cur.eventTag = cur.localEventTag;
3257 final int codeAndIndex = src.readInt();
Dianne Hackborn099bc622014-01-22 13:39:16 -08003258 cur.eventCode = (codeAndIndex&0xffff);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003259 final int index = ((codeAndIndex>>16)&0xffff);
3260 readHistoryTag(index, cur.eventTag);
3261 cur.numReadInts += 1;
3262 if (DEBUG) Slog.i(TAG, "READ DELTA: event=" + cur.eventCode + " tag=#"
3263 + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":"
3264 + cur.eventTag.string);
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003265 } else {
3266 cur.eventCode = HistoryItem.EVENT_NONE;
3267 }
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003268
3269 if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) {
3270 cur.stepDetails = mReadHistoryStepDetails;
3271 cur.stepDetails.readFromParcel(src);
3272 } else {
3273 cur.stepDetails = null;
3274 }
Adam Lesinski926969b2016-04-28 17:31:12 -07003275
Adam Lesinskia8018ac2016-05-03 10:18:10 -07003276 if ((firstToken&DELTA_BATTERY_CHARGE_FLAG) != 0) {
3277 cur.batteryChargeUAh = src.readInt();
Adam Lesinski926969b2016-04-28 17:31:12 -07003278 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003279 }
3280
Dianne Hackbornfc064132014-06-02 12:42:12 -07003281 @Override
3282 public void commitCurrentHistoryBatchLocked() {
3283 mHistoryLastWritten.cmd = HistoryItem.CMD_NULL;
3284 }
3285
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003286 void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003287 if (!mHaveBatteryLevel || !mRecordingHistory) {
3288 return;
3289 }
3290
Dianne Hackborn40c87252014-03-19 16:55:40 -07003291 final long timeDiff = (mHistoryBaseTime+elapsedRealtimeMs) - mHistoryLastWritten.time;
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003292 final int diffStates = mHistoryLastWritten.states^(cur.states&mActiveHistoryStates);
3293 final int diffStates2 = mHistoryLastWritten.states2^(cur.states2&mActiveHistoryStates2);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003294 final int lastDiffStates = mHistoryLastWritten.states^mHistoryLastLastWritten.states;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003295 final int lastDiffStates2 = mHistoryLastWritten.states2^mHistoryLastLastWritten.states2;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003296 if (DEBUG) Slog.i(TAG, "ADD: tdelta=" + timeDiff + " diff="
3297 + Integer.toHexString(diffStates) + " lastDiff="
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003298 + Integer.toHexString(lastDiffStates) + " diff2="
3299 + Integer.toHexString(diffStates2) + " lastDiff2="
3300 + Integer.toHexString(lastDiffStates2));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003301 if (mHistoryBufferLastPos >= 0 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003302 && timeDiff < 1000 && (diffStates&lastDiffStates) == 0
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003303 && (diffStates2&lastDiffStates2) == 0
3304 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null)
3305 && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null)
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003306 && mHistoryLastWritten.stepDetails == null
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003307 && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003308 || cur.eventCode == HistoryItem.EVENT_NONE)
3309 && mHistoryLastWritten.batteryLevel == cur.batteryLevel
3310 && mHistoryLastWritten.batteryStatus == cur.batteryStatus
3311 && mHistoryLastWritten.batteryHealth == cur.batteryHealth
3312 && mHistoryLastWritten.batteryPlugType == cur.batteryPlugType
3313 && mHistoryLastWritten.batteryTemperature == cur.batteryTemperature
3314 && mHistoryLastWritten.batteryVoltage == cur.batteryVoltage) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003315 // We can merge this new change in with the last one. Merging is
Dianne Hackborn40c87252014-03-19 16:55:40 -07003316 // allowed as long as only the states have changed, and within those states
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003317 // as long as no bit has changed both between now and the last entry, as
3318 // well as the last entry and the one before it (so we capture any toggles).
3319 if (DEBUG) Slog.i(TAG, "ADD: rewinding back to " + mHistoryBufferLastPos);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003320 mHistoryBuffer.setDataSize(mHistoryBufferLastPos);
3321 mHistoryBuffer.setDataPosition(mHistoryBufferLastPos);
3322 mHistoryBufferLastPos = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003323 elapsedRealtimeMs = mHistoryLastWritten.time - mHistoryBaseTime;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003324 // If the last written history had a wakelock tag, we need to retain it.
3325 // Note that the condition above made sure that we aren't in a case where
3326 // both it and the current history item have a wakelock tag.
3327 if (mHistoryLastWritten.wakelockTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003328 cur.wakelockTag = cur.localWakelockTag;
3329 cur.wakelockTag.setTo(mHistoryLastWritten.wakelockTag);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003330 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003331 // If the last written history had a wake reason tag, we need to retain it.
3332 // Note that the condition above made sure that we aren't in a case where
3333 // both it and the current history item have a wakelock tag.
3334 if (mHistoryLastWritten.wakeReasonTag != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003335 cur.wakeReasonTag = cur.localWakeReasonTag;
3336 cur.wakeReasonTag.setTo(mHistoryLastWritten.wakeReasonTag);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08003337 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003338 // If the last written history had an event, we need to retain it.
3339 // Note that the condition above made sure that we aren't in a case where
3340 // both it and the current history item have an event.
3341 if (mHistoryLastWritten.eventCode != HistoryItem.EVENT_NONE) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003342 cur.eventCode = mHistoryLastWritten.eventCode;
3343 cur.eventTag = cur.localEventTag;
3344 cur.eventTag.setTo(mHistoryLastWritten.eventTag);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003345 }
Dianne Hackborn1fadab52011-04-14 17:57:33 -07003346 mHistoryLastWritten.setTo(mHistoryLastLastWritten);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003347 }
3348
Adam Lesinski45489782016-12-15 23:45:17 -08003349 boolean recordResetDueToOverflow = false;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003350 final int dataSize = mHistoryBuffer.dataSize();
Adam Lesinski45489782016-12-15 23:45:17 -08003351 if (dataSize >= MAX_MAX_HISTORY_BUFFER*3) {
3352 // Clients can't deal with history buffers this large. This only
3353 // really happens when the device is on charger and interacted with
3354 // for long periods of time, like in retail mode. Since the device is
3355 // most likely charged, when unplugged, stats would have reset anyways.
3356 // Reset the stats and mark that we overflowed.
3357 // b/32540341
3358 resetAllStatsLocked();
3359
3360 // Mark that we want to set *OVERFLOW* event and the RESET:START
3361 // events.
3362 recordResetDueToOverflow = true;
3363
3364 } else if (dataSize >= MAX_HISTORY_BUFFER) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003365 if (!mHistoryOverflow) {
3366 mHistoryOverflow = true;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003367 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
3368 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003369 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003370 }
3371
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003372 // After overflow, we allow various bit-wise states to settle to 0.
3373 boolean writeAnyway = false;
3374 final int curStates = cur.states & HistoryItem.SETTLE_TO_ZERO_STATES
3375 & mActiveHistoryStates;
3376 if (mHistoryLastWritten.states != curStates) {
3377 // mActiveHistoryStates keeps track of which bits in .states are now being
3378 // forced to 0.
3379 int old = mActiveHistoryStates;
3380 mActiveHistoryStates &= curStates | ~HistoryItem.SETTLE_TO_ZERO_STATES;
3381 writeAnyway |= old != mActiveHistoryStates;
3382 }
3383 final int curStates2 = cur.states2 & HistoryItem.SETTLE_TO_ZERO_STATES2
3384 & mActiveHistoryStates2;
3385 if (mHistoryLastWritten.states2 != curStates2) {
3386 // mActiveHistoryStates2 keeps track of which bits in .states2 are now being
3387 // forced to 0.
3388 int old = mActiveHistoryStates2;
3389 mActiveHistoryStates2 &= curStates2 | ~HistoryItem.SETTLE_TO_ZERO_STATES2;
3390 writeAnyway |= old != mActiveHistoryStates2;
3391 }
3392
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003393 // Once we've reached the maximum number of items, we only
3394 // record changes to the battery level and the most interesting states.
3395 // Once we've reached the maximum maximum number of items, we only
3396 // record changes to the battery level.
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003397 if (!writeAnyway && mHistoryLastWritten.batteryLevel == cur.batteryLevel &&
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003398 (dataSize >= MAX_MAX_HISTORY_BUFFER
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003399 || ((mHistoryLastWritten.states^cur.states)
Dianne Hackborn3251b902014-06-20 14:40:53 -07003400 & HistoryItem.MOST_INTERESTING_STATES) == 0
3401 || ((mHistoryLastWritten.states2^cur.states2)
3402 & HistoryItem.MOST_INTERESTING_STATES2) == 0)) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003403 return;
3404 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003405
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003406 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003407 return;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003408 }
3409
Adam Lesinski45489782016-12-15 23:45:17 -08003410 if (dataSize == 0 || recordResetDueToOverflow) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003411 // The history is currently empty; we need it to start with a time stamp.
3412 cur.currentTime = System.currentTimeMillis();
Adam Lesinski45489782016-12-15 23:45:17 -08003413 if (recordResetDueToOverflow) {
3414 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_OVERFLOW, cur);
3415 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003416 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_RESET, cur);
3417 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003418 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003419 }
3420
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003421 private void addHistoryBufferLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd,
3422 HistoryItem cur) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003423 if (mIteratingHistory) {
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003424 throw new IllegalStateException("Can't do this while iterating history!");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003425 }
3426 mHistoryBufferLastPos = mHistoryBuffer.dataPosition();
3427 mHistoryLastLastWritten.setTo(mHistoryLastWritten);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003428 mHistoryLastWritten.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003429 mHistoryLastWritten.states &= mActiveHistoryStates;
3430 mHistoryLastWritten.states2 &= mActiveHistoryStates2;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08003431 writeHistoryDelta(mHistoryBuffer, mHistoryLastWritten, mHistoryLastLastWritten);
Dianne Hackborn40c87252014-03-19 16:55:40 -07003432 mLastHistoryElapsedRealtime = elapsedRealtimeMs;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003433 cur.wakelockTag = null;
3434 cur.wakeReasonTag = null;
3435 cur.eventCode = HistoryItem.EVENT_NONE;
3436 cur.eventTag = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003437 if (DEBUG_HISTORY) Slog.i(TAG, "Writing history buffer: was " + mHistoryBufferLastPos
3438 + " now " + mHistoryBuffer.dataPosition()
3439 + " size is now " + mHistoryBuffer.dataSize());
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003440 }
3441
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003442 int mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003443 int mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003444
Dianne Hackborn40c87252014-03-19 16:55:40 -07003445 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003446 if (mTrackRunningHistoryElapsedRealtime != 0) {
3447 final long diffElapsed = elapsedRealtimeMs - mTrackRunningHistoryElapsedRealtime;
3448 final long diffUptime = uptimeMs - mTrackRunningHistoryUptime;
3449 if (diffUptime < (diffElapsed-20)) {
3450 final long wakeElapsedTime = elapsedRealtimeMs - (diffElapsed - diffUptime);
3451 mHistoryAddTmp.setTo(mHistoryLastWritten);
3452 mHistoryAddTmp.wakelockTag = null;
3453 mHistoryAddTmp.wakeReasonTag = null;
3454 mHistoryAddTmp.eventCode = HistoryItem.EVENT_NONE;
3455 mHistoryAddTmp.states &= ~HistoryItem.STATE_CPU_RUNNING_FLAG;
3456 addHistoryRecordInnerLocked(wakeElapsedTime, uptimeMs, mHistoryAddTmp);
3457 }
3458 }
3459 mHistoryCur.states |= HistoryItem.STATE_CPU_RUNNING_FLAG;
3460 mTrackRunningHistoryElapsedRealtime = elapsedRealtimeMs;
3461 mTrackRunningHistoryUptime = uptimeMs;
3462 addHistoryRecordInnerLocked(elapsedRealtimeMs, uptimeMs, mHistoryCur);
3463 }
3464
3465 void addHistoryRecordInnerLocked(long elapsedRealtimeMs, long uptimeMs, HistoryItem cur) {
3466 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, cur);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003467
Dianne Hackborne8c88e62011-08-17 19:09:09 -07003468 if (!USE_OLD_HISTORY) {
3469 return;
3470 }
3471
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003472 if (!mHaveBatteryLevel || !mRecordingHistory) {
3473 return;
3474 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003475
3476 // If the current time is basically the same as the last time,
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003477 // and no states have since the last recorded entry changed and
3478 // are now resetting back to their original value, then just collapse
3479 // into one record.
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003480 if (mHistoryEnd != null && mHistoryEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07003481 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+1000)
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003482 && ((mHistoryEnd.states^cur.states)&mChangedStates&mActiveHistoryStates) == 0
3483 && ((mHistoryEnd.states2^cur.states2)&mChangedStates2&mActiveHistoryStates2) == 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003484 // If the current is the same as the one before, then we no
3485 // longer need the entry.
3486 if (mHistoryLastEnd != null && mHistoryLastEnd.cmd == HistoryItem.CMD_UPDATE
Dianne Hackborn40c87252014-03-19 16:55:40 -07003487 && (mHistoryBaseTime+elapsedRealtimeMs) < (mHistoryEnd.time+500)
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003488 && mHistoryLastEnd.sameNonEvent(cur)) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003489 mHistoryLastEnd.next = null;
3490 mHistoryEnd.next = mHistoryCache;
3491 mHistoryCache = mHistoryEnd;
3492 mHistoryEnd = mHistoryLastEnd;
3493 mHistoryLastEnd = null;
3494 } else {
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003495 mChangedStates |= mHistoryEnd.states^(cur.states&mActiveHistoryStates);
3496 mChangedStates2 |= mHistoryEnd.states^(cur.states2&mActiveHistoryStates2);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003497 mHistoryEnd.setTo(mHistoryEnd.time, HistoryItem.CMD_UPDATE, cur);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003498 }
3499 return;
3500 }
3501
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003502 mChangedStates = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003503 mChangedStates2 = 0;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003504
3505 if (mNumHistoryItems == MAX_HISTORY_ITEMS
3506 || mNumHistoryItems == MAX_MAX_HISTORY_ITEMS) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07003507 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_OVERFLOW);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003508 }
3509
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003510 if (mNumHistoryItems >= MAX_HISTORY_ITEMS) {
3511 // Once we've reached the maximum number of items, we only
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003512 // record changes to the battery level and the most interesting states.
3513 // Once we've reached the maximum maximum number of items, we only
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003514 // record changes to the battery level.
3515 if (mHistoryEnd != null && mHistoryEnd.batteryLevel
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003516 == cur.batteryLevel &&
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003517 (mNumHistoryItems >= MAX_MAX_HISTORY_ITEMS
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003518 || ((mHistoryEnd.states^(cur.states&mActiveHistoryStates))
Dianne Hackbornf47d8f22010-10-08 10:46:55 -07003519 & HistoryItem.MOST_INTERESTING_STATES) == 0)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003520 return;
3521 }
3522 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003523
Dianne Hackborn40c87252014-03-19 16:55:40 -07003524 addHistoryRecordLocked(elapsedRealtimeMs, HistoryItem.CMD_UPDATE);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003525 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003526
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003527 public void addHistoryEventLocked(long elapsedRealtimeMs, long uptimeMs, int code,
Dianne Hackborn40c87252014-03-19 16:55:40 -07003528 String name, int uid) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003529 mHistoryCur.eventCode = code;
3530 mHistoryCur.eventTag = mHistoryCur.localEventTag;
3531 mHistoryCur.eventTag.string = name;
3532 mHistoryCur.eventTag.uid = uid;
Dianne Hackborn4590e522014-03-24 13:36:46 -07003533 addHistoryRecordLocked(elapsedRealtimeMs, uptimeMs);
Dianne Hackborn099bc622014-01-22 13:39:16 -08003534 }
3535
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003536 void addHistoryRecordLocked(long elapsedRealtimeMs, long uptimeMs, byte cmd, HistoryItem cur) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003537 HistoryItem rec = mHistoryCache;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003538 if (rec != null) {
3539 mHistoryCache = rec.next;
3540 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003541 rec = new HistoryItem();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003542 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003543 rec.setTo(mHistoryBaseTime + elapsedRealtimeMs, cmd, cur);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003544
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003545 addHistoryRecordLocked(rec);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003546 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003547
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003548 void addHistoryRecordLocked(HistoryItem rec) {
3549 mNumHistoryItems++;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003550 rec.next = null;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003551 mHistoryLastEnd = mHistoryEnd;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003552 if (mHistoryEnd != null) {
3553 mHistoryEnd.next = rec;
3554 mHistoryEnd = rec;
3555 } else {
3556 mHistory = mHistoryEnd = rec;
3557 }
3558 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003559
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003560 void clearHistoryLocked() {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003561 if (DEBUG_HISTORY) Slog.i(TAG, "********** CLEARING HISTORY!");
Dianne Hackborne8c88e62011-08-17 19:09:09 -07003562 if (USE_OLD_HISTORY) {
3563 if (mHistory != null) {
3564 mHistoryEnd.next = mHistoryCache;
3565 mHistoryCache = mHistory;
3566 mHistory = mHistoryLastEnd = mHistoryEnd = null;
3567 }
3568 mNumHistoryItems = 0;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003569 }
Dianne Hackborne8c88e62011-08-17 19:09:09 -07003570
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07003571 mHistoryBaseTime = 0;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003572 mLastHistoryElapsedRealtime = 0;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003573 mTrackRunningHistoryElapsedRealtime = 0;
3574 mTrackRunningHistoryUptime = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003575
3576 mHistoryBuffer.setDataSize(0);
3577 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003578 mHistoryBuffer.setDataCapacity(MAX_HISTORY_BUFFER / 2);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003579 mHistoryLastLastWritten.clear();
3580 mHistoryLastWritten.clear();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003581 mHistoryTagPool.clear();
3582 mNextHistoryTagIdx = 0;
3583 mNumHistoryTagChars = 0;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07003584 mHistoryBufferLastPos = -1;
3585 mHistoryOverflow = false;
Dianne Hackborn0c820db2015-04-14 17:47:34 -07003586 mActiveHistoryStates = 0xffffffff;
3587 mActiveHistoryStates2 = 0xffffffff;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07003588 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07003589
Mike Mac2f518a2017-09-19 16:06:03 -07003590 public void updateTimeBasesLocked(boolean unplugged, int screenState, long uptime,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003591 long realtime) {
Mike Maa7724752017-10-10 15:29:25 -07003592 final boolean screenOff = !isScreenOn(screenState);
Sudheer Shanka9d4ed7c2017-07-08 22:10:45 -07003593 final boolean updateOnBatteryTimeBase = unplugged != mOnBatteryTimeBase.isRunning();
3594 final boolean updateOnBatteryScreenOffTimeBase =
3595 (unplugged && screenOff) != mOnBatteryScreenOffTimeBase.isRunning();
Bookatz867c0d72017-03-07 18:23:42 -08003596
Sudheer Shanka9d4ed7c2017-07-08 22:10:45 -07003597 if (updateOnBatteryScreenOffTimeBase || updateOnBatteryTimeBase) {
3598 if (updateOnBatteryScreenOffTimeBase) {
3599 updateKernelWakelocksLocked();
3600 updateBatteryPropertiesLocked();
Bookatz867c0d72017-03-07 18:23:42 -08003601 }
Bookatz82b341172017-09-07 19:06:08 -07003602 // This if{} is only necessary due to SCREEN_OFF_RPM_STATS_ENABLED, which exists because
3603 // updateRpmStatsLocked is too slow to run each screen change. When the speed is
3604 // improved, remove the surrounding if{}.
3605 if (SCREEN_OFF_RPM_STATS_ENABLED || updateOnBatteryTimeBase) {
3606 updateRpmStatsLocked(); // if either OnBattery or OnBatteryScreenOff timebase changes.
3607 }
Adam Lesinski72478f02015-06-17 15:39:43 -07003608 if (DEBUG_ENERGY_CPU) {
Mike Mac2f518a2017-09-19 16:06:03 -07003609 Slog.d(TAG, "Updating cpu time because screen is now "
3610 + Display.stateToString(screenState)
Sudheer Shanka9d4ed7c2017-07-08 22:10:45 -07003611 + " and battery is " + (unplugged ? "on" : "off"));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003612 }
Sudheer Shankab8ad5942017-08-08 12:16:09 -07003613 updateCpuTimeLocked();
Sudheer Shanka9d4ed7c2017-07-08 22:10:45 -07003614
3615 mOnBatteryTimeBase.setRunning(unplugged, uptime, realtime);
Mike Mac2f518a2017-09-19 16:06:03 -07003616 if (updateOnBatteryTimeBase) {
3617 for (int i = mUidStats.size() - 1; i >= 0; --i) {
3618 mUidStats.valueAt(i).updateOnBatteryBgTimeBase(uptime, realtime);
Sudheer Shanka9d4ed7c2017-07-08 22:10:45 -07003619 }
Mike Mac2f518a2017-09-19 16:06:03 -07003620 }
3621 if (updateOnBatteryScreenOffTimeBase) {
3622 mOnBatteryScreenOffTimeBase.setRunning(unplugged && screenOff, uptime, realtime);
3623 for (int i = mUidStats.size() - 1; i >= 0; --i) {
3624 mUidStats.valueAt(i).updateOnBatteryScreenOffBgTimeBase(uptime, realtime);
Sudheer Shanka9d4ed7c2017-07-08 22:10:45 -07003625 }
Bookatzc8c44962017-05-11 12:12:54 -07003626 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003627 }
3628 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07003629
Adam Lesinskie1f480d2017-02-15 18:51:23 -08003630 private void updateBatteryPropertiesLocked() {
3631 try {
3632 IBatteryPropertiesRegistrar registrar = IBatteryPropertiesRegistrar.Stub.asInterface(
3633 ServiceManager.getService("batteryproperties"));
3634 registrar.scheduleUpdate();
3635 } catch (RemoteException e) {
3636 // Ignore.
3637 }
3638 }
3639
Dianne Hackborn099bc622014-01-22 13:39:16 -08003640 public void addIsolatedUidLocked(int isolatedUid, int appUid) {
3641 mIsolatedUids.put(isolatedUid, appUid);
3642 }
3643
Adam Lesinski61db88f2015-07-01 15:05:07 -07003644 /**
3645 * Schedules a read of the latest cpu times before removing the isolated UID.
3646 * @see #removeIsolatedUidLocked(int)
3647 */
3648 public void scheduleRemoveIsolatedUidLocked(int isolatedUid, int appUid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003649 int curUid = mIsolatedUids.get(isolatedUid, -1);
3650 if (curUid == appUid) {
Adam Lesinski61db88f2015-07-01 15:05:07 -07003651 if (mExternalSync != null) {
3652 mExternalSync.scheduleCpuSyncDueToRemovedUid(isolatedUid);
3653 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08003654 }
3655 }
3656
Adam Lesinski61db88f2015-07-01 15:05:07 -07003657 /**
3658 * This should only be called after the cpu times have been read.
3659 * @see #scheduleRemoveIsolatedUidLocked(int, int)
3660 */
3661 public void removeIsolatedUidLocked(int isolatedUid) {
3662 mIsolatedUids.delete(isolatedUid);
3663 mKernelUidCpuTimeReader.removeUid(isolatedUid);
Sudheer Shanka6d8dcec2017-06-01 12:09:03 -07003664 mKernelUidCpuFreqTimeReader.removeUid(isolatedUid);
Adam Lesinski61db88f2015-07-01 15:05:07 -07003665 }
3666
Dianne Hackborn099bc622014-01-22 13:39:16 -08003667 public int mapUid(int uid) {
3668 int isolated = mIsolatedUids.get(uid, -1);
3669 return isolated > 0 ? isolated : uid;
3670 }
3671
3672 public void noteEventLocked(int code, String name, int uid) {
3673 uid = mapUid(uid);
Dianne Hackborn37de0982014-05-09 09:32:18 -07003674 if (!mActiveEvents.updateState(code, name, uid, 0)) {
3675 return;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08003676 }
Joe Onoratoabded112016-02-08 16:49:39 -08003677 final long elapsedRealtime = mClocks.elapsedRealtime();
3678 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn40c87252014-03-19 16:55:40 -07003679 addHistoryEventLocked(elapsedRealtime, uptime, code, name, uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -08003680 }
3681
Dianne Hackbornd48954f2015-07-22 17:20:33 -07003682 boolean ensureStartClockTime(final long currentTime) {
3683 final long ABOUT_ONE_YEAR = 365*24*60*60*1000L;
3684 if (currentTime > ABOUT_ONE_YEAR && mStartClockTime < (currentTime-ABOUT_ONE_YEAR)) {
3685 // If the start clock time has changed by more than a year, then presumably
3686 // the previous time was completely bogus. So we are going to figure out a
3687 // new time based on how much time has elapsed since we started counting.
Joe Onoratoabded112016-02-08 16:49:39 -08003688 mStartClockTime = currentTime - (mClocks.elapsedRealtime()-(mRealtimeStart/1000));
Dianne Hackbornd48954f2015-07-22 17:20:33 -07003689 return true;
3690 }
3691 return false;
3692 }
3693
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07003694 public void noteCurrentTimeChangedLocked() {
3695 final long currentTime = System.currentTimeMillis();
Joe Onoratoabded112016-02-08 16:49:39 -08003696 final long elapsedRealtime = mClocks.elapsedRealtime();
3697 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07003698 recordCurrentTimeChangeLocked(currentTime, elapsedRealtime, uptime);
Dianne Hackbornd48954f2015-07-22 17:20:33 -07003699 ensureStartClockTime(currentTime);
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07003700 }
3701
Dianne Hackborn61659e52014-07-09 16:13:01 -07003702 public void noteProcessStartLocked(String name, int uid) {
3703 uid = mapUid(uid);
3704 if (isOnBattery()) {
3705 Uid u = getUidStatsLocked(uid);
3706 u.getProcessStatsLocked(name).incStartsLocked();
3707 }
3708 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_START, name, uid, 0)) {
3709 return;
3710 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003711 if (!mRecordAllHistory) {
3712 return;
3713 }
Joe Onoratoabded112016-02-08 16:49:39 -08003714 final long elapsedRealtime = mClocks.elapsedRealtime();
3715 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn61659e52014-07-09 16:13:01 -07003716 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_START, name, uid);
3717 }
3718
Dianne Hackborn1e01d162014-12-04 17:46:42 -08003719 public void noteProcessCrashLocked(String name, int uid) {
3720 uid = mapUid(uid);
3721 if (isOnBattery()) {
3722 Uid u = getUidStatsLocked(uid);
3723 u.getProcessStatsLocked(name).incNumCrashesLocked();
3724 }
3725 }
3726
3727 public void noteProcessAnrLocked(String name, int uid) {
3728 uid = mapUid(uid);
3729 if (isOnBattery()) {
3730 Uid u = getUidStatsLocked(uid);
3731 u.getProcessStatsLocked(name).incNumAnrsLocked();
3732 }
3733 }
3734
Dianne Hackborna8d10942015-11-19 17:55:19 -08003735 public void noteUidProcessStateLocked(int uid, int state) {
Amith Yamasanifd3caf62017-07-26 11:48:35 -07003736 int parentUid = mapUid(uid);
3737 if (uid != parentUid) {
3738 // Isolated UIDs process state is already rolled up into parent, so no need to track
3739 // Otherwise the parent's process state will get downgraded incorrectly
3740 return;
3741 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08003742 getUidStatsLocked(uid).updateUidProcessStateLocked(state);
Dianne Hackborn61659e52014-07-09 16:13:01 -07003743 }
3744
3745 public void noteProcessFinishLocked(String name, int uid) {
3746 uid = mapUid(uid);
3747 if (!mActiveEvents.updateState(HistoryItem.EVENT_PROC_FINISH, name, uid, 0)) {
3748 return;
3749 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003750 if (!mRecordAllHistory) {
3751 return;
3752 }
Joe Onoratoabded112016-02-08 16:49:39 -08003753 final long elapsedRealtime = mClocks.elapsedRealtime();
3754 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003755 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PROC_FINISH, name, uid);
Dianne Hackborn61659e52014-07-09 16:13:01 -07003756 }
3757
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003758 public void noteSyncStartLocked(String name, int uid) {
3759 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003760 final long elapsedRealtime = mClocks.elapsedRealtime();
3761 final long uptime = mClocks.uptimeMillis();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003762 getUidStatsLocked(uid).noteStartSyncLocked(name, elapsedRealtime);
3763 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_START, name, uid, 0)) {
3764 return;
3765 }
3766 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_START, name, uid);
3767 }
3768
3769 public void noteSyncFinishLocked(String name, int uid) {
3770 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003771 final long elapsedRealtime = mClocks.elapsedRealtime();
3772 final long uptime = mClocks.uptimeMillis();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003773 getUidStatsLocked(uid).noteStopSyncLocked(name, elapsedRealtime);
3774 if (!mActiveEvents.updateState(HistoryItem.EVENT_SYNC_FINISH, name, uid, 0)) {
3775 return;
3776 }
3777 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SYNC_FINISH, name, uid);
3778 }
3779
3780 public void noteJobStartLocked(String name, int uid) {
3781 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003782 final long elapsedRealtime = mClocks.elapsedRealtime();
3783 final long uptime = mClocks.uptimeMillis();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003784 getUidStatsLocked(uid).noteStartJobLocked(name, elapsedRealtime);
3785 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_START, name, uid, 0)) {
3786 return;
3787 }
3788 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_START, name, uid);
3789 }
3790
Dianne Hackborn94326cb2017-06-28 16:17:20 -07003791 public void noteJobFinishLocked(String name, int uid, int stopReason) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003792 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003793 final long elapsedRealtime = mClocks.elapsedRealtime();
3794 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn94326cb2017-06-28 16:17:20 -07003795 getUidStatsLocked(uid).noteStopJobLocked(name, elapsedRealtime, stopReason);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07003796 if (!mActiveEvents.updateState(HistoryItem.EVENT_JOB_FINISH, name, uid, 0)) {
3797 return;
3798 }
3799 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_JOB_FINISH, name, uid);
3800 }
3801
Dianne Hackborn1e383822015-04-10 14:02:33 -07003802 public void noteAlarmStartLocked(String name, int uid) {
3803 if (!mRecordAllHistory) {
3804 return;
3805 }
3806 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003807 final long elapsedRealtime = mClocks.elapsedRealtime();
3808 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn1e383822015-04-10 14:02:33 -07003809 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_START, name, uid, 0)) {
3810 return;
3811 }
3812 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_START, name, uid);
3813 }
3814
3815 public void noteAlarmFinishLocked(String name, int uid) {
3816 if (!mRecordAllHistory) {
3817 return;
3818 }
3819 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08003820 final long elapsedRealtime = mClocks.elapsedRealtime();
3821 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn1e383822015-04-10 14:02:33 -07003822 if (!mActiveEvents.updateState(HistoryItem.EVENT_ALARM_FINISH, name, uid, 0)) {
3823 return;
3824 }
3825 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ALARM_FINISH, name, uid);
3826 }
3827
Dianne Hackborn97ae5382014-03-05 16:43:25 -08003828 private void requestWakelockCpuUpdate() {
3829 if (!mHandler.hasMessages(MSG_UPDATE_WAKELOCKS)) {
3830 Message m = mHandler.obtainMessage(MSG_UPDATE_WAKELOCKS);
3831 mHandler.sendMessageDelayed(m, DELAY_UPDATE_WAKELOCKS);
3832 }
3833 }
3834
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08003835 private void requestImmediateCpuUpdate() {
3836 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
3837 mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS);
3838 }
3839
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003840 public void setRecordAllHistoryLocked(boolean enabled) {
3841 mRecordAllHistory = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003842 if (!enabled) {
3843 // Clear out any existing state.
3844 mActiveEvents.removeEvents(HistoryItem.EVENT_WAKE_LOCK);
Dianne Hackborn1e383822015-04-10 14:02:33 -07003845 mActiveEvents.removeEvents(HistoryItem.EVENT_ALARM);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003846 // Record the currently running processes as stopping, now that we are no
3847 // longer tracking them.
3848 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
3849 HistoryItem.EVENT_PROC);
3850 if (active != null) {
Joe Onoratoabded112016-02-08 16:49:39 -08003851 long mSecRealtime = mClocks.elapsedRealtime();
3852 final long mSecUptime = mClocks.uptimeMillis();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003853 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
3854 SparseIntArray uids = ent.getValue();
3855 for (int j=0; j<uids.size(); j++) {
3856 addHistoryEventLocked(mSecRealtime, mSecUptime,
3857 HistoryItem.EVENT_PROC_FINISH, ent.getKey(), uids.keyAt(j));
3858 }
3859 }
3860 }
3861 } else {
3862 // Record the currently running processes as starting, now that we are tracking them.
3863 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(
3864 HistoryItem.EVENT_PROC);
3865 if (active != null) {
Joe Onoratoabded112016-02-08 16:49:39 -08003866 long mSecRealtime = mClocks.elapsedRealtime();
3867 final long mSecUptime = mClocks.uptimeMillis();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003868 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
3869 SparseIntArray uids = ent.getValue();
3870 for (int j=0; j<uids.size(); j++) {
3871 addHistoryEventLocked(mSecRealtime, mSecUptime,
3872 HistoryItem.EVENT_PROC_START, ent.getKey(), uids.keyAt(j));
3873 }
3874 }
3875 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003876 }
3877 }
3878
Dianne Hackborn9a755432014-05-15 17:05:22 -07003879 public void setNoAutoReset(boolean enabled) {
3880 mNoAutoReset = enabled;
3881 }
3882
Amith Yamasani674c9bb2017-02-01 09:45:17 -08003883 public void setPretendScreenOff(boolean pretendScreenOff) {
Mike Mac2f518a2017-09-19 16:06:03 -07003884 if (mPretendScreenOff != pretendScreenOff) {
3885 mPretendScreenOff = pretendScreenOff;
3886 noteScreenStateLocked(pretendScreenOff ? Display.STATE_OFF : Display.STATE_ON);
3887 }
Amith Yamasani674c9bb2017-02-01 09:45:17 -08003888 }
3889
Dianne Hackborn9a755432014-05-15 17:05:22 -07003890 private String mInitialAcquireWakeName;
3891 private int mInitialAcquireWakeUid = -1;
3892
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08003893 public void noteStartWakeLocked(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn40c87252014-03-19 16:55:40 -07003894 boolean unimportantForLogging, long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003895 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003896 if (type == WAKE_TYPE_PARTIAL) {
3897 // Only care about partial wake locks, since full wake locks
3898 // will be canceled when the user puts the screen to sleep.
Dianne Hackborna1bd7922014-03-21 11:07:11 -07003899 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07003900 if (historyName == null) {
3901 historyName = name;
3902 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003903 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07003904 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_START, historyName,
3905 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07003906 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07003907 HistoryItem.EVENT_WAKE_LOCK_START, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07003908 }
3909 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003910 if (mWakeLockNesting == 0) {
3911 mHistoryCur.states |= HistoryItem.STATE_WAKE_LOCK_FLAG;
3912 if (DEBUG_HISTORY) Slog.v(TAG, "Start wake lock to: "
3913 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08003914 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003915 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07003916 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003917 mWakeLockImportant = !unimportantForLogging;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003918 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornfc064132014-06-02 12:42:12 -07003919 } else if (!mWakeLockImportant && !unimportantForLogging
3920 && mHistoryLastWritten.cmd == HistoryItem.CMD_UPDATE) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003921 if (mHistoryLastWritten.wakelockTag != null) {
3922 // We'll try to update the last tag.
3923 mHistoryLastWritten.wakelockTag = null;
3924 mHistoryCur.wakelockTag = mHistoryCur.localWakelockTag;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003925 mHistoryCur.wakelockTag.string = mInitialAcquireWakeName = historyName;
Dianne Hackborn37de0982014-05-09 09:32:18 -07003926 mHistoryCur.wakelockTag.uid = mInitialAcquireWakeUid = uid;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003927 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08003928 }
3929 mWakeLockImportant = true;
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003930 }
3931 mWakeLockNesting++;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003932 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003933 if (uid >= 0) {
Adam Lesinski72478f02015-06-17 15:39:43 -07003934 if (mOnBatteryScreenOffTimeBase.isRunning()) {
3935 // We only update the cpu time when a wake lock is acquired if the screen is off.
3936 // If the screen is on, we don't distribute the power amongst partial wakelocks.
3937 if (DEBUG_ENERGY_CPU) {
3938 Slog.d(TAG, "Updating cpu time because of +wake_lock");
3939 }
3940 requestWakelockCpuUpdate();
3941 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003942 getUidStatsLocked(uid).noteStartWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003943 }
3944 }
3945
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003946 public void noteStopWakeLocked(int uid, int pid, String name, String historyName, int type,
3947 long elapsedRealtime, long uptime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08003948 uid = mapUid(uid);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003949 if (type == WAKE_TYPE_PARTIAL) {
3950 mWakeLockNesting--;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07003951 if (mRecordAllHistory) {
Dianne Hackbornfc064132014-06-02 12:42:12 -07003952 if (historyName == null) {
3953 historyName = name;
3954 }
3955 if (mActiveEvents.updateState(HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName,
3956 uid, 0)) {
Dianne Hackborn536456f2014-05-23 16:51:05 -07003957 addHistoryEventLocked(elapsedRealtime, uptime,
Dianne Hackbornfc064132014-06-02 12:42:12 -07003958 HistoryItem.EVENT_WAKE_LOCK_FINISH, historyName, uid);
Dianne Hackborn536456f2014-05-23 16:51:05 -07003959 }
3960 }
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003961 if (mWakeLockNesting == 0) {
3962 mHistoryCur.states &= ~HistoryItem.STATE_WAKE_LOCK_FLAG;
3963 if (DEBUG_HISTORY) Slog.v(TAG, "Stop wake lock to: "
3964 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn37de0982014-05-09 09:32:18 -07003965 mInitialAcquireWakeName = null;
3966 mInitialAcquireWakeUid = -1;
Dianne Hackborn40c87252014-03-19 16:55:40 -07003967 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn1ebccf52010-08-15 13:04:34 -07003968 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003969 }
3970 if (uid >= 0) {
Adam Lesinski72478f02015-06-17 15:39:43 -07003971 if (mOnBatteryScreenOffTimeBase.isRunning()) {
3972 if (DEBUG_ENERGY_CPU) {
3973 Slog.d(TAG, "Updating cpu time because of -wake_lock");
3974 }
3975 requestWakelockCpuUpdate();
3976 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08003977 getUidStatsLocked(uid).noteStopWakeLocked(pid, name, type, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07003978 }
3979 }
3980
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -08003981 public void noteStartWakeFromSourceLocked(WorkSource ws, int pid, String name,
3982 String historyName, int type, boolean unimportantForLogging) {
Joe Onoratoabded112016-02-08 16:49:39 -08003983 final long elapsedRealtime = mClocks.elapsedRealtime();
3984 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003985 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07003986 for (int i=0; i<N; i++) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003987 noteStartWakeLocked(ws.get(i), pid, name, historyName, type, unimportantForLogging,
Dianne Hackborn40c87252014-03-19 16:55:40 -07003988 elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003989 }
3990 }
3991
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07003992 public void noteChangeWakelockFromSourceLocked(WorkSource ws, int pid, String name,
3993 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003994 String newHistoryName, int newType, boolean newUnimportantForLogging) {
Joe Onoratoabded112016-02-08 16:49:39 -08003995 final long elapsedRealtime = mClocks.elapsedRealtime();
3996 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08003997 // For correct semantics, we start the need worksources first, so that we won't
3998 // make inappropriate history items as if all wake locks went away and new ones
3999 // appeared. This is okay because tracking of wake locks allows nesting.
Dianne Hackborn40c87252014-03-19 16:55:40 -07004000 final int NN = newWs.size();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004001 for (int i=0; i<NN; i++) {
4002 noteStartWakeLocked(newWs.get(i), newPid, newName, newHistoryName, newType,
Dianne Hackborn40c87252014-03-19 16:55:40 -07004003 newUnimportantForLogging, elapsedRealtime, uptime);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004004 }
4005 final int NO = ws.size();
4006 for (int i=0; i<NO; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004007 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004008 }
4009 }
4010
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004011 public void noteStopWakeFromSourceLocked(WorkSource ws, int pid, String name,
4012 String historyName, int type) {
Joe Onoratoabded112016-02-08 16:49:39 -08004013 final long elapsedRealtime = mClocks.elapsedRealtime();
4014 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004015 final int N = ws.size();
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004016 for (int i=0; i<N; i++) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004017 noteStopWakeLocked(ws.get(i), pid, name, historyName, type, elapsedRealtime, uptime);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07004018 }
4019 }
4020
Dianne Hackbornd0db6f02016-07-18 14:14:20 -07004021 public void noteLongPartialWakelockStart(String name, String historyName, int uid) {
4022 uid = mapUid(uid);
4023 final long elapsedRealtime = mClocks.elapsedRealtime();
4024 final long uptime = mClocks.uptimeMillis();
4025 if (historyName == null) {
4026 historyName = name;
4027 }
4028 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_START, historyName, uid,
4029 0)) {
4030 return;
4031 }
4032 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_START,
4033 historyName, uid);
Bookatzc1a050a2017-10-10 15:49:28 -07004034 StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, uid, name, historyName, 1);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -07004035 }
4036
4037 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) {
4038 uid = mapUid(uid);
4039 final long elapsedRealtime = mClocks.elapsedRealtime();
4040 final long uptime = mClocks.uptimeMillis();
4041 if (historyName == null) {
4042 historyName = name;
4043 }
4044 if (!mActiveEvents.updateState(HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH, historyName, uid,
4045 0)) {
4046 return;
4047 }
4048 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_LONG_WAKE_LOCK_FINISH,
4049 historyName, uid);
Bookatzc1a050a2017-10-10 15:49:28 -07004050 StatsLog.write(StatsLog.LONG_PARTIAL_WAKELOCK_STATE_CHANGED, uid, name, historyName, 0);
Dianne Hackbornd0db6f02016-07-18 14:14:20 -07004051 }
4052
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004053 void aggregateLastWakeupUptimeLocked(long uptimeMs) {
4054 if (mLastWakeupReason != null) {
4055 long deltaUptime = uptimeMs - mLastWakeupUptimeMs;
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07004056 SamplingTimer timer = getWakeupReasonTimerLocked(mLastWakeupReason);
Adam Lesinski757c6ea2016-04-21 09:55:41 -07004057 timer.add(deltaUptime * 1000, 1); // time in in microseconds
Bookatz8c6571b2017-10-24 15:04:41 -07004058 StatsLog.write(StatsLog.KERNEL_WAKEUP_REPORTED, mLastWakeupReason, deltaUptime * 1000);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004059 mLastWakeupReason = null;
4060 }
4061 }
4062
4063 public void noteWakeupReasonLocked(String reason) {
Joe Onoratoabded112016-02-08 16:49:39 -08004064 final long elapsedRealtime = mClocks.elapsedRealtime();
4065 final long uptime = mClocks.uptimeMillis();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07004066 if (DEBUG_HISTORY) Slog.v(TAG, "Wakeup reason \"" + reason +"\": "
Dianne Hackbornc51cf032014-03-02 19:08:15 -08004067 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004068 aggregateLastWakeupUptimeLocked(uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08004069 mHistoryCur.wakeReasonTag = mHistoryCur.localWakeReasonTag;
4070 mHistoryCur.wakeReasonTag.string = reason;
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004071 mHistoryCur.wakeReasonTag.uid = 0;
4072 mLastWakeupReason = reason;
4073 mLastWakeupUptimeMs = uptime;
Dianne Hackborn40c87252014-03-19 16:55:40 -07004074 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08004075 }
4076
Adam Lesinski72478f02015-06-17 15:39:43 -07004077 public boolean startAddingCpuLocked() {
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004078 mHandler.removeMessages(MSG_UPDATE_WAKELOCKS);
Adam Lesinski72478f02015-06-17 15:39:43 -07004079 return mOnBatteryInternal;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004080 }
4081
Adam Lesinski72478f02015-06-17 15:39:43 -07004082 public void finishAddingCpuLocked(int totalUTime, int totalSTime, int statUserTime,
4083 int statSystemTime, int statIOWaitTime, int statIrqTime,
4084 int statSoftIrqTime, int statIdleTime) {
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08004085 if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime
4086 + " user=" + statUserTime + " sys=" + statSystemTime
4087 + " io=" + statIOWaitTime + " irq=" + statIrqTime
4088 + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime);
4089 mCurStepCpuUserTime += totalUTime;
4090 mCurStepCpuSystemTime += totalSTime;
4091 mCurStepStatUserTime += statUserTime;
4092 mCurStepStatSystemTime += statSystemTime;
4093 mCurStepStatIOWaitTime += statIOWaitTime;
4094 mCurStepStatIrqTime += statIrqTime;
4095 mCurStepStatSoftIrqTime += statSoftIrqTime;
4096 mCurStepStatIdleTime += statIdleTime;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07004097 }
4098
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004099 public void noteProcessDiedLocked(int uid, int pid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004100 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004101 Uid u = mUidStats.get(uid);
4102 if (u != null) {
4103 u.mPids.remove(pid);
4104 }
4105 }
4106
4107 public long getProcessWakeTime(int uid, int pid, long realtime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004108 uid = mapUid(uid);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004109 Uid u = mUidStats.get(uid);
4110 if (u != null) {
4111 Uid.Pid p = u.mPids.get(pid);
4112 if (p != null) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08004113 return p.mWakeSumMs + (p.mWakeNesting > 0 ? (realtime - p.mWakeStartMs) : 0);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004114 }
4115 }
4116 return 0;
4117 }
4118
Dianne Hackborn287952c2010-09-22 22:34:31 -07004119 public void reportExcessiveCpuLocked(int uid, String proc, long overTime, long usedTime) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004120 uid = mapUid(uid);
Dianne Hackborn287952c2010-09-22 22:34:31 -07004121 Uid u = mUidStats.get(uid);
4122 if (u != null) {
4123 u.reportExcessiveCpuLocked(proc, overTime, usedTime);
4124 }
4125 }
4126
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004127 int mSensorNesting;
4128
4129 public void noteStartSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004130 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004131 final long elapsedRealtime = mClocks.elapsedRealtime();
4132 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004133 if (mSensorNesting == 0) {
4134 mHistoryCur.states |= HistoryItem.STATE_SENSOR_ON_FLAG;
4135 if (DEBUG_HISTORY) Slog.v(TAG, "Start sensor to: "
4136 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004137 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004138 }
4139 mSensorNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004140 getUidStatsLocked(uid).noteStartSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004141 }
4142
4143 public void noteStopSensorLocked(int uid, int sensor) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004144 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004145 final long elapsedRealtime = mClocks.elapsedRealtime();
4146 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004147 mSensorNesting--;
4148 if (mSensorNesting == 0) {
4149 mHistoryCur.states &= ~HistoryItem.STATE_SENSOR_ON_FLAG;
4150 if (DEBUG_HISTORY) Slog.v(TAG, "Stop sensor to: "
4151 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004152 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004153 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004154 getUidStatsLocked(uid).noteStopSensor(sensor, elapsedRealtime);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004155 }
4156
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004157 int mGpsNesting;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004158
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004159 public void noteStartGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004160 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004161 final long elapsedRealtime = mClocks.elapsedRealtime();
4162 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004163 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004164 mHistoryCur.states |= HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004165 if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: "
4166 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004167 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004168 }
4169 mGpsNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004170 getUidStatsLocked(uid).noteStartGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004171 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004172
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004173 public void noteStopGpsLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004174 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004175 final long elapsedRealtime = mClocks.elapsedRealtime();
4176 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004177 mGpsNesting--;
4178 if (mGpsNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004179 mHistoryCur.states &= ~HistoryItem.STATE_GPS_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004180 if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: "
4181 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004182 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004183 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004184 getUidStatsLocked(uid).noteStopGps(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004185 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004186
Jeff Browne95c3cd2014-05-02 16:59:26 -07004187 public void noteScreenStateLocked(int state) {
Amith Yamasani674c9bb2017-02-01 09:45:17 -08004188 state = mPretendScreenOff ? Display.STATE_OFF : state;
Santos Cordone94f0502017-02-24 12:31:20 -08004189
4190 // Battery stats relies on there being 4 states. To accommodate this, new states beyond the
4191 // original 4 are mapped to one of the originals.
4192 if (state > MAX_TRACKED_SCREEN_STATE) {
4193 switch (state) {
4194 case Display.STATE_VR:
4195 state = Display.STATE_ON;
4196 break;
4197 default:
4198 Slog.wtf(TAG, "Unknown screen state (not mapped): " + state);
4199 break;
4200 }
4201 }
4202
Jeff Browne95c3cd2014-05-02 16:59:26 -07004203 if (mScreenState != state) {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08004204 recordDailyStatsIfNeededLocked(true);
Jeff Browne95c3cd2014-05-02 16:59:26 -07004205 final int oldState = mScreenState;
4206 mScreenState = state;
4207 if (DEBUG) Slog.v(TAG, "Screen state: oldState=" + Display.stateToString(oldState)
4208 + ", newState=" + Display.stateToString(state));
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07004209
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07004210 if (state != Display.STATE_UNKNOWN) {
4211 int stepState = state-1;
Santos Cordone94f0502017-02-24 12:31:20 -08004212 if ((stepState & STEP_LEVEL_MODE_SCREEN_STATE) == stepState) {
4213 mModStepMode |= (mCurStepMode & STEP_LEVEL_MODE_SCREEN_STATE) ^ stepState;
4214 mCurStepMode = (mCurStepMode & ~STEP_LEVEL_MODE_SCREEN_STATE) | stepState;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07004215 } else {
4216 Slog.wtf(TAG, "Unexpected screen state: " + state);
4217 }
4218 }
4219
Mike Mac2f518a2017-09-19 16:06:03 -07004220 final long elapsedRealtime = mClocks.elapsedRealtime();
4221 final long uptime = mClocks.uptimeMillis();
4222
4223 boolean updateHistory = false;
4224 if (isScreenDoze(state)) {
4225 mHistoryCur.states |= HistoryItem.STATE_SCREEN_DOZE_FLAG;
4226 mScreenDozeTimer.startRunningLocked(elapsedRealtime);
4227 updateHistory = true;
4228 } else if (isScreenDoze(oldState)) {
4229 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_DOZE_FLAG;
4230 mScreenDozeTimer.stopRunningLocked(elapsedRealtime);
4231 updateHistory = true;
4232 }
4233 if (isScreenOn(state)) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07004234 mHistoryCur.states |= HistoryItem.STATE_SCREEN_ON_FLAG;
4235 if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: "
4236 + Integer.toHexString(mHistoryCur.states));
Jeff Browne95c3cd2014-05-02 16:59:26 -07004237 mScreenOnTimer.startRunningLocked(elapsedRealtime);
4238 if (mScreenBrightnessBin >= 0) {
4239 mScreenBrightnessTimer[mScreenBrightnessBin].startRunningLocked(elapsedRealtime);
4240 }
Mike Mac2f518a2017-09-19 16:06:03 -07004241 updateHistory = true;
4242 } else if (isScreenOn(oldState)) {
Jeff Browne95c3cd2014-05-02 16:59:26 -07004243 mHistoryCur.states &= ~HistoryItem.STATE_SCREEN_ON_FLAG;
4244 if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: "
4245 + Integer.toHexString(mHistoryCur.states));
Jeff Browne95c3cd2014-05-02 16:59:26 -07004246 mScreenOnTimer.stopRunningLocked(elapsedRealtime);
4247 if (mScreenBrightnessBin >= 0) {
4248 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
4249 }
Mike Mac2f518a2017-09-19 16:06:03 -07004250 updateHistory = true;
4251 }
4252 if (updateHistory) {
4253 if (DEBUG_HISTORY) Slog.v(TAG, "Screen state to: "
4254 + Display.stateToString(state));
4255 addHistoryRecordLocked(elapsedRealtime, uptime);
4256 }
4257 if (isScreenOn(state)) {
4258 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state,
4259 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000);
4260 // Fake a wake lock, so we consider the device waked as long as the screen is on.
4261 noteStartWakeLocked(-1, -1, "screen", null, WAKE_TYPE_PARTIAL, false,
4262 elapsedRealtime, uptime);
4263 } else if (isScreenOn(oldState)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004264 noteStopWakeLocked(-1, -1, "screen", "screen", WAKE_TYPE_PARTIAL,
Jeff Browne95c3cd2014-05-02 16:59:26 -07004265 elapsedRealtime, uptime);
Mike Mac2f518a2017-09-19 16:06:03 -07004266 updateTimeBasesLocked(mOnBatteryTimeBase.isRunning(), state,
Joe Onoratoabded112016-02-08 16:49:39 -08004267 mClocks.uptimeMillis() * 1000, elapsedRealtime * 1000);
Mike Mac2f518a2017-09-19 16:06:03 -07004268 }
4269 // Update discharge amounts.
4270 if (mOnBatteryInternal) {
4271 updateDischargeScreenLevelsLocked(oldState, state);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08004272 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07004273 }
4274 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004275
Dianne Hackborn617f8772009-03-31 15:04:46 -07004276 public void noteScreenBrightnessLocked(int brightness) {
4277 // Bin the brightness.
4278 int bin = brightness / (256/NUM_SCREEN_BRIGHTNESS_BINS);
4279 if (bin < 0) bin = 0;
4280 else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1;
4281 if (mScreenBrightnessBin != bin) {
Joe Onoratoabded112016-02-08 16:49:39 -08004282 final long elapsedRealtime = mClocks.elapsedRealtime();
4283 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004284 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_BRIGHTNESS_MASK)
4285 | (bin << HistoryItem.STATE_BRIGHTNESS_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004286 if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: "
4287 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004288 addHistoryRecordLocked(elapsedRealtime, uptime);
Jeff Browne95c3cd2014-05-02 16:59:26 -07004289 if (mScreenState == Display.STATE_ON) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07004290 if (mScreenBrightnessBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004291 mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004292 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004293 mScreenBrightnessTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn617f8772009-03-31 15:04:46 -07004294 }
4295 mScreenBrightnessBin = bin;
4296 }
4297 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004298
Dianne Hackborn617f8772009-03-31 15:04:46 -07004299 public void noteUserActivityLocked(int uid, int event) {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08004300 if (mOnBatteryInternal) {
4301 uid = mapUid(uid);
4302 getUidStatsLocked(uid).noteUserActivityLocked(event);
4303 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004304 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004305
Dianne Hackborn280a64e2015-07-13 14:48:08 -07004306 public void noteWakeUpLocked(String reason, int reasonUid) {
Joe Onoratoabded112016-02-08 16:49:39 -08004307 final long elapsedRealtime = mClocks.elapsedRealtime();
4308 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn280a64e2015-07-13 14:48:08 -07004309 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_SCREEN_WAKE_UP,
4310 reason, reasonUid);
4311 }
4312
Jeff Browne95c3cd2014-05-02 16:59:26 -07004313 public void noteInteractiveLocked(boolean interactive) {
4314 if (mInteractive != interactive) {
Joe Onoratoabded112016-02-08 16:49:39 -08004315 final long elapsedRealtime = mClocks.elapsedRealtime();
Jeff Browne95c3cd2014-05-02 16:59:26 -07004316 mInteractive = interactive;
4317 if (DEBUG) Slog.v(TAG, "Interactive: " + interactive);
4318 if (interactive) {
4319 mInteractiveTimer.startRunningLocked(elapsedRealtime);
4320 } else {
4321 mInteractiveTimer.stopRunningLocked(elapsedRealtime);
4322 }
4323 }
4324 }
4325
Dianne Hackborn1e01d162014-12-04 17:46:42 -08004326 public void noteConnectivityChangedLocked(int type, String extra) {
Joe Onoratoabded112016-02-08 16:49:39 -08004327 final long elapsedRealtime = mClocks.elapsedRealtime();
4328 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08004329 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_CONNECTIVITY_CHANGED,
4330 extra, type);
4331 mNumConnectivityChange++;
4332 }
4333
Adam Lesinski5f056f62016-07-14 16:56:08 -07004334 private void noteMobileRadioApWakeupLocked(final long elapsedRealtimeMillis,
4335 final long uptimeMillis, int uid) {
4336 uid = mapUid(uid);
4337 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
4338 uid);
4339 getUidStatsLocked(uid).noteMobileRadioApWakeupLocked();
4340 }
4341
Adam Lesinski14ae39a2017-05-26 11:50:40 -07004342 /**
4343 * Updates the radio power state and returns true if an external stats collection should occur.
4344 */
4345 public boolean noteMobileRadioPowerStateLocked(int powerState, long timestampNs, int uid) {
Joe Onoratoabded112016-02-08 16:49:39 -08004346 final long elapsedRealtime = mClocks.elapsedRealtime();
4347 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004348 if (mMobileRadioPowerState != powerState) {
4349 long realElapsedRealtimeMs;
4350 final boolean active =
4351 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
4352 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
4353 if (active) {
Adam Lesinski5f056f62016-07-14 16:56:08 -07004354 if (uid > 0) {
4355 noteMobileRadioApWakeupLocked(elapsedRealtime, uptime, uid);
4356 }
4357
Adam Lesinski9acfd812016-04-19 18:29:50 -07004358 mMobileRadioActiveStartTime = realElapsedRealtimeMs = timestampNs / (1000 * 1000);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004359 mHistoryCur.states |= HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
4360 } else {
4361 realElapsedRealtimeMs = timestampNs / (1000*1000);
Dianne Hackbornf7097a52014-05-13 09:56:14 -07004362 long lastUpdateTimeMs = mMobileRadioActiveStartTime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004363 if (realElapsedRealtimeMs < lastUpdateTimeMs) {
4364 Slog.wtf(TAG, "Data connection inactive timestamp " + realElapsedRealtimeMs
4365 + " is before start time " + lastUpdateTimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004366 realElapsedRealtimeMs = elapsedRealtime;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004367 } else if (realElapsedRealtimeMs < elapsedRealtime) {
4368 mMobileRadioActiveAdjustedTime.addCountLocked(elapsedRealtime
4369 - realElapsedRealtimeMs);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004370 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004371 mHistoryCur.states &= ~HistoryItem.STATE_MOBILE_RADIO_ACTIVE_FLAG;
4372 }
4373 if (DEBUG_HISTORY) Slog.v(TAG, "Mobile network active " + active + " to: "
4374 + Integer.toHexString(mHistoryCur.states));
4375 addHistoryRecordLocked(elapsedRealtime, uptime);
4376 mMobileRadioPowerState = powerState;
4377 if (active) {
4378 mMobileRadioActiveTimer.startRunningLocked(elapsedRealtime);
4379 mMobileRadioActivePerAppTimer.startRunningLocked(elapsedRealtime);
4380 } else {
4381 mMobileRadioActiveTimer.stopRunningLocked(realElapsedRealtimeMs);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07004382 mMobileRadioActivePerAppTimer.stopRunningLocked(realElapsedRealtimeMs);
Adam Lesinski14ae39a2017-05-26 11:50:40 -07004383 // Tell the caller to collect radio network/power stats.
4384 return true;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004385 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004386 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -07004387 return false;
Dianne Hackborne13c4c02014-02-11 17:18:35 -08004388 }
4389
Adam Lesinski14ae39a2017-05-26 11:50:40 -07004390 public void notePowerSaveModeLocked(boolean enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004391 if (mPowerSaveModeEnabled != enabled) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07004392 int stepState = enabled ? STEP_LEVEL_MODE_POWER_SAVE : 0;
4393 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_POWER_SAVE) ^ stepState;
4394 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_POWER_SAVE) | stepState;
Joe Onoratoabded112016-02-08 16:49:39 -08004395 final long elapsedRealtime = mClocks.elapsedRealtime();
4396 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004397 mPowerSaveModeEnabled = enabled;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004398 if (enabled) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004399 mHistoryCur.states2 |= HistoryItem.STATE2_POWER_SAVE_FLAG;
4400 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode enabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004401 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004402 mPowerSaveModeEnabledTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004403 } else {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004404 mHistoryCur.states2 &= ~HistoryItem.STATE2_POWER_SAVE_FLAG;
4405 if (DEBUG_HISTORY) Slog.v(TAG, "Power save mode disabled to: "
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004406 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004407 mPowerSaveModeEnabledTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004408 }
4409 addHistoryRecordLocked(elapsedRealtime, uptime);
Bookatzc1a050a2017-10-10 15:49:28 -07004410 StatsLog.write(StatsLog.BATTERY_SAVER_MODE_STATE_CHANGED, enabled ? 1 : 0);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07004411 }
4412 }
4413
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004414 public void noteDeviceIdleModeLocked(int mode, String activeReason, int activeUid) {
Joe Onoratoabded112016-02-08 16:49:39 -08004415 final long elapsedRealtime = mClocks.elapsedRealtime();
4416 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07004417 boolean nowIdling = mode == DEVICE_IDLE_MODE_DEEP;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004418 if (mDeviceIdling && !nowIdling && activeReason == null) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004419 // We don't go out of general idling mode until explicitly taken out of
4420 // device idle through going active or significant motion.
4421 nowIdling = true;
4422 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004423 boolean nowLightIdling = mode == DEVICE_IDLE_MODE_LIGHT;
4424 if (mDeviceLightIdling && !nowLightIdling && !nowIdling && activeReason == null) {
4425 // We don't go out of general light idling mode until explicitly taken out of
4426 // device idle through going active or significant motion.
4427 nowLightIdling = true;
4428 }
4429 if (activeReason != null && (mDeviceIdling || mDeviceLightIdling)) {
4430 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_ACTIVE,
4431 activeReason, activeUid);
4432 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004433 if (mDeviceIdling != nowIdling) {
4434 mDeviceIdling = nowIdling;
4435 int stepState = nowIdling ? STEP_LEVEL_MODE_DEVICE_IDLE : 0;
4436 mModStepMode |= (mCurStepMode&STEP_LEVEL_MODE_DEVICE_IDLE) ^ stepState;
4437 mCurStepMode = (mCurStepMode&~STEP_LEVEL_MODE_DEVICE_IDLE) | stepState;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004438 if (nowIdling) {
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004439 mDeviceIdlingTimer.startRunningLocked(elapsedRealtime);
4440 } else {
4441 mDeviceIdlingTimer.stopRunningLocked(elapsedRealtime);
4442 }
4443 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004444 if (mDeviceLightIdling != nowLightIdling) {
4445 mDeviceLightIdling = nowLightIdling;
4446 if (nowLightIdling) {
4447 mDeviceLightIdlingTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004448 } else {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004449 mDeviceLightIdlingTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004450 }
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004451 }
4452 if (mDeviceIdleMode != mode) {
4453 mHistoryCur.states2 = (mHistoryCur.states2 & ~HistoryItem.STATE2_DEVICE_IDLE_MASK)
4454 | (mode << HistoryItem.STATE2_DEVICE_IDLE_SHIFT);
4455 if (DEBUG_HISTORY) Slog.v(TAG, "Device idle mode changed to: "
4456 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004457 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004458 long lastDuration = elapsedRealtime - mLastIdleTimeStart;
4459 mLastIdleTimeStart = elapsedRealtime;
4460 if (mDeviceIdleMode == DEVICE_IDLE_MODE_LIGHT) {
4461 if (lastDuration > mLongestLightIdleTime) {
4462 mLongestLightIdleTime = lastDuration;
4463 }
4464 mDeviceIdleModeLightTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07004465 } else if (mDeviceIdleMode == DEVICE_IDLE_MODE_DEEP) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004466 if (lastDuration > mLongestFullIdleTime) {
4467 mLongestFullIdleTime = lastDuration;
4468 }
4469 mDeviceIdleModeFullTimer.stopRunningLocked(elapsedRealtime);
4470 }
4471 if (mode == DEVICE_IDLE_MODE_LIGHT) {
4472 mDeviceIdleModeLightTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07004473 } else if (mode == DEVICE_IDLE_MODE_DEEP) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07004474 mDeviceIdleModeFullTimer.startRunningLocked(elapsedRealtime);
4475 }
4476 mDeviceIdleMode = mode;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004477 }
4478 }
4479
4480 public void notePackageInstalledLocked(String pkgName, int versionCode) {
Joe Onoratoabded112016-02-08 16:49:39 -08004481 final long elapsedRealtime = mClocks.elapsedRealtime();
4482 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004483 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_INSTALLED,
4484 pkgName, versionCode);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004485 PackageChange pc = new PackageChange();
4486 pc.mPackageName = pkgName;
4487 pc.mUpdate = true;
4488 pc.mVersionCode = versionCode;
4489 addPackageChange(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004490 }
4491
4492 public void notePackageUninstalledLocked(String pkgName) {
Joe Onoratoabded112016-02-08 16:49:39 -08004493 final long elapsedRealtime = mClocks.elapsedRealtime();
4494 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004495 addHistoryEventLocked(elapsedRealtime, uptime, HistoryItem.EVENT_PACKAGE_UNINSTALLED,
4496 pkgName, 0);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07004497 PackageChange pc = new PackageChange();
4498 pc.mPackageName = pkgName;
4499 pc.mUpdate = true;
4500 addPackageChange(pc);
4501 }
4502
4503 private void addPackageChange(PackageChange pc) {
4504 if (mDailyPackageChanges == null) {
4505 mDailyPackageChanges = new ArrayList<>();
4506 }
4507 mDailyPackageChanges.add(pc);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07004508 }
4509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004510 public void notePhoneOnLocked() {
4511 if (!mPhoneOn) {
Joe Onoratoabded112016-02-08 16:49:39 -08004512 final long elapsedRealtime = mClocks.elapsedRealtime();
4513 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07004514 mHistoryCur.states2 |= HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004515 if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: "
4516 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004517 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004518 mPhoneOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004519 mPhoneOnTimer.startRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004520 }
4521 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004522
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004523 public void notePhoneOffLocked() {
4524 if (mPhoneOn) {
Joe Onoratoabded112016-02-08 16:49:39 -08004525 final long elapsedRealtime = mClocks.elapsedRealtime();
4526 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07004527 mHistoryCur.states2 &= ~HistoryItem.STATE2_PHONE_IN_CALL_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004528 if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: "
4529 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004530 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004531 mPhoneOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004532 mPhoneOnTimer.stopRunningLocked(elapsedRealtime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08004533 }
4534 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004535
Dianne Hackborn3251b902014-06-20 14:40:53 -07004536 void stopAllPhoneSignalStrengthTimersLocked(int except) {
Joe Onoratoabded112016-02-08 16:49:39 -08004537 final long elapsedRealtime = mClocks.elapsedRealtime();
Wink Saville52840902011-02-18 12:40:47 -08004538 for (int i = 0; i < SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004539 if (i == except) {
4540 continue;
4541 }
4542 while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004543 mPhoneSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004544 }
4545 }
4546 }
4547
Dianne Hackborne4a59512010-12-07 11:08:07 -08004548 private int fixPhoneServiceState(int state, int signalBin) {
4549 if (mPhoneSimStateRaw == TelephonyManager.SIM_STATE_ABSENT) {
4550 // In this case we will always be STATE_OUT_OF_SERVICE, so need
4551 // to infer that we are scanning from other data.
4552 if (state == ServiceState.STATE_OUT_OF_SERVICE
Wink Saville52840902011-02-18 12:40:47 -08004553 && signalBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004554 state = ServiceState.STATE_IN_SERVICE;
4555 }
4556 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004557
Dianne Hackborne4a59512010-12-07 11:08:07 -08004558 return state;
4559 }
4560
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004561 private void updateAllPhoneStateLocked(int state, int simState, int strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004562 boolean scanning = false;
4563 boolean newHistory = false;
4564
4565 mPhoneServiceStateRaw = state;
4566 mPhoneSimStateRaw = simState;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004567 mPhoneSignalStrengthBinRaw = strengthBin;
4568
Joe Onoratoabded112016-02-08 16:49:39 -08004569 final long elapsedRealtime = mClocks.elapsedRealtime();
4570 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne4a59512010-12-07 11:08:07 -08004571
4572 if (simState == TelephonyManager.SIM_STATE_ABSENT) {
4573 // In this case we will always be STATE_OUT_OF_SERVICE, so need
4574 // to infer that we are scanning from other data.
4575 if (state == ServiceState.STATE_OUT_OF_SERVICE
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004576 && strengthBin > SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004577 state = ServiceState.STATE_IN_SERVICE;
4578 }
4579 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004580
4581 // If the phone is powered off, stop all timers.
4582 if (state == ServiceState.STATE_POWER_OFF) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004583 strengthBin = -1;
Amith Yamasanif37447b2009-10-08 18:28:01 -07004584
Dianne Hackborne4a59512010-12-07 11:08:07 -08004585 // If we are in service, make sure the correct signal string timer is running.
4586 } else if (state == ServiceState.STATE_IN_SERVICE) {
4587 // Bin will be changed below.
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004588
4589 // If we're out of service, we are in the lowest signal strength
4590 // bin and have the scanning bit set.
Amith Yamasanif37447b2009-10-08 18:28:01 -07004591 } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004592 scanning = true;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004593 strengthBin = SignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
Amith Yamasanif37447b2009-10-08 18:28:01 -07004594 if (!mPhoneSignalScanningTimer.isRunningLocked()) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004595 mHistoryCur.states |= HistoryItem.STATE_PHONE_SCANNING_FLAG;
Dianne Hackborne4a59512010-12-07 11:08:07 -08004596 newHistory = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004597 if (DEBUG_HISTORY) Slog.v(TAG, "Phone started scanning to: "
4598 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004599 mPhoneSignalScanningTimer.startRunningLocked(elapsedRealtime);
Amith Yamasanif37447b2009-10-08 18:28:01 -07004600 }
4601 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004602
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004603 if (!scanning) {
4604 // If we are no longer scanning, then stop the scanning timer.
4605 if (mPhoneSignalScanningTimer.isRunningLocked()) {
4606 mHistoryCur.states &= ~HistoryItem.STATE_PHONE_SCANNING_FLAG;
4607 if (DEBUG_HISTORY) Slog.v(TAG, "Phone stopped scanning to: "
4608 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08004609 newHistory = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004610 mPhoneSignalScanningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07004611 }
4612 }
4613
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004614 if (mPhoneServiceState != state) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004615 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_STATE_MASK)
4616 | (state << HistoryItem.STATE_PHONE_STATE_SHIFT);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004617 if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + state + " to: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004618 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborne4a59512010-12-07 11:08:07 -08004619 newHistory = true;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004620 mPhoneServiceState = state;
4621 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08004622
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004623 if (mPhoneSignalStrengthBin != strengthBin) {
Dianne Hackborne4a59512010-12-07 11:08:07 -08004624 if (mPhoneSignalStrengthBin >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004625 mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004626 elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004627 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004628 if (strengthBin >= 0) {
4629 if (!mPhoneSignalStrengthsTimer[strengthBin].isRunningLocked()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004630 mPhoneSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004631 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07004632 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_MASK)
4633 | (strengthBin << HistoryItem.STATE_PHONE_SIGNAL_STRENGTH_SHIFT);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004634 if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + strengthBin + " to: "
Dianne Hackborne4a59512010-12-07 11:08:07 -08004635 + Integer.toHexString(mHistoryCur.states));
4636 newHistory = true;
Bookatze5885242017-10-24 20:10:31 -07004637 StatsLog.write(StatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, strengthBin);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004638 } else {
Dianne Hackborn3251b902014-06-20 14:40:53 -07004639 stopAllPhoneSignalStrengthTimersLocked(-1);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004640 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004641 mPhoneSignalStrengthBin = strengthBin;
Dianne Hackborne4a59512010-12-07 11:08:07 -08004642 }
4643
4644 if (newHistory) {
Dianne Hackborn40c87252014-03-19 16:55:40 -07004645 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborne4a59512010-12-07 11:08:07 -08004646 }
4647 }
4648
4649 /**
4650 * Telephony stack updates the phone state.
4651 * @param state phone state from ServiceState.getState()
4652 */
4653 public void notePhoneStateLocked(int state, int simState) {
4654 updateAllPhoneStateLocked(state, simState, mPhoneSignalStrengthBinRaw);
Amith Yamasani32dbefd2009-06-19 09:21:17 -07004655 }
4656
Wink Savillee9b06d72009-05-18 21:47:50 -07004657 public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -07004658 // Bin the strength.
Wink Saville52840902011-02-18 12:40:47 -08004659 int bin = signalStrength.getLevel();
Dianne Hackborne4a59512010-12-07 11:08:07 -08004660 updateAllPhoneStateLocked(mPhoneServiceStateRaw, mPhoneSimStateRaw, bin);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004661 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004662
Dianne Hackborn627bba72009-03-24 22:32:56 -07004663 public void notePhoneDataConnectionStateLocked(int dataType, boolean hasData) {
4664 int bin = DATA_CONNECTION_NONE;
4665 if (hasData) {
4666 switch (dataType) {
4667 case TelephonyManager.NETWORK_TYPE_EDGE:
4668 bin = DATA_CONNECTION_EDGE;
4669 break;
4670 case TelephonyManager.NETWORK_TYPE_GPRS:
4671 bin = DATA_CONNECTION_GPRS;
4672 break;
4673 case TelephonyManager.NETWORK_TYPE_UMTS:
4674 bin = DATA_CONNECTION_UMTS;
4675 break;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004676 case TelephonyManager.NETWORK_TYPE_CDMA:
4677 bin = DATA_CONNECTION_CDMA;
4678 break;
4679 case TelephonyManager.NETWORK_TYPE_EVDO_0:
4680 bin = DATA_CONNECTION_EVDO_0;
4681 break;
4682 case TelephonyManager.NETWORK_TYPE_EVDO_A:
4683 bin = DATA_CONNECTION_EVDO_A;
4684 break;
4685 case TelephonyManager.NETWORK_TYPE_1xRTT:
4686 bin = DATA_CONNECTION_1xRTT;
4687 break;
4688 case TelephonyManager.NETWORK_TYPE_HSDPA:
4689 bin = DATA_CONNECTION_HSDPA;
4690 break;
4691 case TelephonyManager.NETWORK_TYPE_HSUPA:
4692 bin = DATA_CONNECTION_HSUPA;
4693 break;
4694 case TelephonyManager.NETWORK_TYPE_HSPA:
4695 bin = DATA_CONNECTION_HSPA;
4696 break;
4697 case TelephonyManager.NETWORK_TYPE_IDEN:
4698 bin = DATA_CONNECTION_IDEN;
4699 break;
4700 case TelephonyManager.NETWORK_TYPE_EVDO_B:
4701 bin = DATA_CONNECTION_EVDO_B;
4702 break;
Robert Greenwalt962a9902010-11-02 11:10:25 -07004703 case TelephonyManager.NETWORK_TYPE_LTE:
4704 bin = DATA_CONNECTION_LTE;
4705 break;
4706 case TelephonyManager.NETWORK_TYPE_EHRPD:
4707 bin = DATA_CONNECTION_EHRPD;
4708 break;
Patrick Tjinb71703c2013-11-06 09:27:03 -08004709 case TelephonyManager.NETWORK_TYPE_HSPAP:
4710 bin = DATA_CONNECTION_HSPAP;
4711 break;
Dianne Hackborn627bba72009-03-24 22:32:56 -07004712 default:
4713 bin = DATA_CONNECTION_OTHER;
4714 break;
4715 }
4716 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -07004717 if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004718 if (mPhoneDataConnectionType != bin) {
Joe Onoratoabded112016-02-08 16:49:39 -08004719 final long elapsedRealtime = mClocks.elapsedRealtime();
4720 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004721 mHistoryCur.states = (mHistoryCur.states&~HistoryItem.STATE_DATA_CONNECTION_MASK)
4722 | (bin << HistoryItem.STATE_DATA_CONNECTION_SHIFT);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004723 if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: "
4724 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004725 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004726 if (mPhoneDataConnectionType >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004727 mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004728 elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004729 }
4730 mPhoneDataConnectionType = bin;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004731 mPhoneDataConnectionsTimer[bin].startRunningLocked(elapsedRealtime);
Dianne Hackborn627bba72009-03-24 22:32:56 -07004732 }
4733 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004734
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004735 public void noteWifiOnLocked() {
The Android Open Source Project10592532009-03-18 17:39:46 -07004736 if (!mWifiOn) {
Joe Onoratoabded112016-02-08 16:49:39 -08004737 final long elapsedRealtime = mClocks.elapsedRealtime();
4738 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07004739 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004740 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: "
4741 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004742 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07004743 mWifiOn = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004744 mWifiOnTimer.startRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004745 scheduleSyncExternalStatsLocked("wifi-off", ExternalStatsSync.UPDATE_WIFI);
The Android Open Source Project10592532009-03-18 17:39:46 -07004746 }
4747 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004748
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07004749 public void noteWifiOffLocked() {
Joe Onoratoabded112016-02-08 16:49:39 -08004750 final long elapsedRealtime = mClocks.elapsedRealtime();
4751 final long uptime = mClocks.uptimeMillis();
The Android Open Source Project10592532009-03-18 17:39:46 -07004752 if (mWifiOn) {
Dianne Hackborn3251b902014-06-20 14:40:53 -07004753 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004754 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: "
4755 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004756 addHistoryRecordLocked(elapsedRealtime, uptime);
The Android Open Source Project10592532009-03-18 17:39:46 -07004757 mWifiOn = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004758 mWifiOnTimer.stopRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004759 scheduleSyncExternalStatsLocked("wifi-on", ExternalStatsSync.UPDATE_WIFI);
The Android Open Source Project10592532009-03-18 17:39:46 -07004760 }
4761 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004762
4763 public void noteAudioOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004764 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004765 final long elapsedRealtime = mClocks.elapsedRealtime();
4766 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004767 if (mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004768 mHistoryCur.states |= HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004769 if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: "
4770 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004771 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004772 mAudioOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004773 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004774 mAudioOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004775 getUidStatsLocked(uid).noteAudioTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004776 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004777
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004778 public void noteAudioOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004779 if (mAudioOnNesting == 0) {
4780 return;
4781 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08004782 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004783 final long elapsedRealtime = mClocks.elapsedRealtime();
4784 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004785 if (--mAudioOnNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07004786 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004787 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
4788 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004789 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004790 mAudioOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004791 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004792 getUidStatsLocked(uid).noteAudioTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004793 }
4794
4795 public void noteVideoOnLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004796 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004797 final long elapsedRealtime = mClocks.elapsedRealtime();
4798 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004799 if (mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004800 mHistoryCur.states2 |= HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004801 if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: "
4802 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004803 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004804 mVideoOnTimer.startRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004805 }
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004806 mVideoOnNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004807 getUidStatsLocked(uid).noteVideoTurnedOnLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004808 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07004809
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004810 public void noteVideoOffLocked(int uid) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004811 if (mVideoOnNesting == 0) {
4812 return;
4813 }
Dianne Hackborn099bc622014-01-22 13:39:16 -08004814 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004815 final long elapsedRealtime = mClocks.elapsedRealtime();
4816 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004817 if (--mVideoOnNesting == 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07004818 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07004819 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
4820 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07004821 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08004822 mVideoOnTimer.stopRunningLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004823 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08004824 getUidStatsLocked(uid).noteVideoTurnedOffLocked(elapsedRealtime);
Amith Yamasani244fa5c2009-05-22 14:36:07 -07004825 }
4826
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004827 public void noteResetAudioLocked() {
4828 if (mAudioOnNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08004829 final long elapsedRealtime = mClocks.elapsedRealtime();
4830 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004831 mAudioOnNesting = 0;
4832 mHistoryCur.states &= ~HistoryItem.STATE_AUDIO_ON_FLAG;
4833 if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: "
4834 + Integer.toHexString(mHistoryCur.states));
4835 addHistoryRecordLocked(elapsedRealtime, uptime);
4836 mAudioOnTimer.stopAllRunningLocked(elapsedRealtime);
4837 for (int i=0; i<mUidStats.size(); i++) {
4838 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
4839 uid.noteResetAudioLocked(elapsedRealtime);
4840 }
4841 }
4842 }
4843
4844 public void noteResetVideoLocked() {
4845 if (mVideoOnNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08004846 final long elapsedRealtime = mClocks.elapsedRealtime();
4847 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn10eaa852014-07-22 22:54:55 -07004848 mAudioOnNesting = 0;
4849 mHistoryCur.states2 &= ~HistoryItem.STATE2_VIDEO_ON_FLAG;
4850 if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: "
4851 + Integer.toHexString(mHistoryCur.states));
4852 addHistoryRecordLocked(elapsedRealtime, uptime);
4853 mVideoOnTimer.stopAllRunningLocked(elapsedRealtime);
4854 for (int i=0; i<mUidStats.size(); i++) {
4855 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
4856 uid.noteResetVideoLocked(elapsedRealtime);
4857 }
4858 }
4859 }
4860
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004861 public void noteActivityResumedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004862 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004863 getUidStatsLocked(uid).noteActivityResumedLocked(mClocks.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004864 }
4865
4866 public void noteActivityPausedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004867 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004868 getUidStatsLocked(uid).noteActivityPausedLocked(mClocks.elapsedRealtime());
Jeff Sharkey3e013e82013-04-25 14:48:19 -07004869 }
4870
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004871 public void noteVibratorOnLocked(int uid, long durationMillis) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004872 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004873 getUidStatsLocked(uid).noteVibratorOnLocked(durationMillis);
4874 }
4875
4876 public void noteVibratorOffLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08004877 uid = mapUid(uid);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08004878 getUidStatsLocked(uid).noteVibratorOffLocked();
4879 }
4880
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004881 public void noteFlashlightOnLocked(int uid) {
4882 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004883 final long elapsedRealtime = mClocks.elapsedRealtime();
4884 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004885 if (mFlashlightOnNesting++ == 0) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004886 mHistoryCur.states2 |= HistoryItem.STATE2_FLASHLIGHT_FLAG;
4887 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight on to: "
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004888 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004889 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004890 mFlashlightOnTimer.startRunningLocked(elapsedRealtime);
4891 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004892 getUidStatsLocked(uid).noteFlashlightTurnedOnLocked(elapsedRealtime);
4893 }
4894
4895 public void noteFlashlightOffLocked(int uid) {
4896 if (mFlashlightOnNesting == 0) {
4897 return;
4898 }
4899 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004900 final long elapsedRealtime = mClocks.elapsedRealtime();
4901 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004902 if (--mFlashlightOnNesting == 0) {
4903 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
4904 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
4905 + Integer.toHexString(mHistoryCur.states2));
4906 addHistoryRecordLocked(elapsedRealtime, uptime);
4907 mFlashlightOnTimer.stopRunningLocked(elapsedRealtime);
4908 }
4909 getUidStatsLocked(uid).noteFlashlightTurnedOffLocked(elapsedRealtime);
4910 }
4911
4912 public void noteCameraOnLocked(int uid) {
4913 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004914 final long elapsedRealtime = mClocks.elapsedRealtime();
4915 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004916 if (mCameraOnNesting++ == 0) {
4917 mHistoryCur.states2 |= HistoryItem.STATE2_CAMERA_FLAG;
4918 if (DEBUG_HISTORY) Slog.v(TAG, "Camera on to: "
4919 + Integer.toHexString(mHistoryCur.states2));
4920 addHistoryRecordLocked(elapsedRealtime, uptime);
4921 mCameraOnTimer.startRunningLocked(elapsedRealtime);
4922 }
4923 getUidStatsLocked(uid).noteCameraTurnedOnLocked(elapsedRealtime);
4924 }
4925
4926 public void noteCameraOffLocked(int uid) {
4927 if (mCameraOnNesting == 0) {
4928 return;
4929 }
4930 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08004931 final long elapsedRealtime = mClocks.elapsedRealtime();
4932 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004933 if (--mCameraOnNesting == 0) {
4934 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
4935 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
4936 + Integer.toHexString(mHistoryCur.states2));
4937 addHistoryRecordLocked(elapsedRealtime, uptime);
4938 mCameraOnTimer.stopRunningLocked(elapsedRealtime);
4939 }
4940 getUidStatsLocked(uid).noteCameraTurnedOffLocked(elapsedRealtime);
4941 }
4942
4943 public void noteResetCameraLocked() {
4944 if (mCameraOnNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08004945 final long elapsedRealtime = mClocks.elapsedRealtime();
4946 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004947 mCameraOnNesting = 0;
4948 mHistoryCur.states2 &= ~HistoryItem.STATE2_CAMERA_FLAG;
4949 if (DEBUG_HISTORY) Slog.v(TAG, "Camera off to: "
4950 + Integer.toHexString(mHistoryCur.states2));
4951 addHistoryRecordLocked(elapsedRealtime, uptime);
4952 mCameraOnTimer.stopAllRunningLocked(elapsedRealtime);
4953 for (int i=0; i<mUidStats.size(); i++) {
4954 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
4955 uid.noteResetCameraLocked(elapsedRealtime);
4956 }
4957 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004958 }
4959
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004960 public void noteResetFlashlightLocked() {
4961 if (mFlashlightOnNesting > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08004962 final long elapsedRealtime = mClocks.elapsedRealtime();
4963 final long uptime = mClocks.uptimeMillis();
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004964 mFlashlightOnNesting = 0;
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004965 mHistoryCur.states2 &= ~HistoryItem.STATE2_FLASHLIGHT_FLAG;
4966 if (DEBUG_HISTORY) Slog.v(TAG, "Flashlight off to: "
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004967 + Integer.toHexString(mHistoryCur.states2));
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004968 addHistoryRecordLocked(elapsedRealtime, uptime);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07004969 mFlashlightOnTimer.stopAllRunningLocked(elapsedRealtime);
4970 for (int i=0; i<mUidStats.size(); i++) {
4971 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
4972 uid.noteResetFlashlightLocked(elapsedRealtime);
4973 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -07004974 }
4975 }
4976
Bookatzb1f04f32017-05-19 13:57:32 -07004977 private void noteBluetoothScanStartedLocked(int uid, boolean isUnoptimized) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004978 uid = mapUid(uid);
Bookatz867c0d72017-03-07 18:23:42 -08004979 final long elapsedRealtime = mClocks.elapsedRealtime();
4980 final long uptime = mClocks.uptimeMillis();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004981 if (mBluetoothScanNesting == 0) {
4982 mHistoryCur.states2 |= HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
4983 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan started for: "
4984 + Integer.toHexString(mHistoryCur.states2));
4985 addHistoryRecordLocked(elapsedRealtime, uptime);
Adam Lesinskid9b99be2016-03-30 16:58:51 -07004986 mBluetoothScanTimer.startRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004987 }
4988 mBluetoothScanNesting++;
Bookatzb1f04f32017-05-19 13:57:32 -07004989 getUidStatsLocked(uid).noteBluetoothScanStartedLocked(elapsedRealtime, isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004990 }
4991
Bookatzb1f04f32017-05-19 13:57:32 -07004992 public void noteBluetoothScanStartedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004993 final int N = ws.size();
4994 for (int i = 0; i < N; i++) {
Bookatzb1f04f32017-05-19 13:57:32 -07004995 noteBluetoothScanStartedLocked(ws.get(i), isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08004996 }
4997 }
4998
Bookatz94c5a312017-07-11 16:49:17 -07004999 private void noteBluetoothScanStoppedLocked(int uid, boolean isUnoptimized) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005000 uid = mapUid(uid);
Bookatz867c0d72017-03-07 18:23:42 -08005001 final long elapsedRealtime = mClocks.elapsedRealtime();
5002 final long uptime = mClocks.uptimeMillis();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005003 mBluetoothScanNesting--;
5004 if (mBluetoothScanNesting == 0) {
5005 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
5006 if (DEBUG_HISTORY) Slog.v(TAG, "BLE scan stopped for: "
5007 + Integer.toHexString(mHistoryCur.states2));
5008 addHistoryRecordLocked(elapsedRealtime, uptime);
Adam Lesinskid9b99be2016-03-30 16:58:51 -07005009 mBluetoothScanTimer.stopRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005010 }
Bookatz94c5a312017-07-11 16:49:17 -07005011 getUidStatsLocked(uid).noteBluetoothScanStoppedLocked(elapsedRealtime, isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005012 }
5013
Bookatz94c5a312017-07-11 16:49:17 -07005014 public void noteBluetoothScanStoppedFromSourceLocked(WorkSource ws, boolean isUnoptimized) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005015 final int N = ws.size();
5016 for (int i = 0; i < N; i++) {
Bookatz94c5a312017-07-11 16:49:17 -07005017 noteBluetoothScanStoppedLocked(ws.get(i), isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005018 }
5019 }
5020
5021 public void noteResetBluetoothScanLocked() {
5022 if (mBluetoothScanNesting > 0) {
Bookatz867c0d72017-03-07 18:23:42 -08005023 final long elapsedRealtime = mClocks.elapsedRealtime();
5024 final long uptime = mClocks.uptimeMillis();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005025 mBluetoothScanNesting = 0;
5026 mHistoryCur.states2 &= ~HistoryItem.STATE2_BLUETOOTH_SCAN_FLAG;
5027 if (DEBUG_HISTORY) Slog.v(TAG, "BLE can stopped for: "
5028 + Integer.toHexString(mHistoryCur.states2));
5029 addHistoryRecordLocked(elapsedRealtime, uptime);
5030 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtime);
5031 for (int i=0; i<mUidStats.size(); i++) {
5032 BatteryStatsImpl.Uid uid = mUidStats.valueAt(i);
5033 uid.noteResetBluetoothScanLocked(elapsedRealtime);
5034 }
5035 }
5036 }
5037
Bookatz4ebc0642017-05-11 12:21:19 -07005038 public void noteBluetoothScanResultsFromSourceLocked(WorkSource ws, int numNewResults) {
Bookatz956f36bf2017-04-28 09:48:17 -07005039 final int N = ws.size();
5040 for (int i = 0; i < N; i++) {
5041 int uid = mapUid(ws.get(i));
Bookatz4ebc0642017-05-11 12:21:19 -07005042 getUidStatsLocked(uid).noteBluetoothScanResultsLocked(numNewResults);
Bookatz956f36bf2017-04-28 09:48:17 -07005043 }
5044 }
5045
Adam Lesinski5f056f62016-07-14 16:56:08 -07005046 private void noteWifiRadioApWakeupLocked(final long elapsedRealtimeMillis,
5047 final long uptimeMillis, int uid) {
5048 uid = mapUid(uid);
5049 addHistoryEventLocked(elapsedRealtimeMillis, uptimeMillis, HistoryItem.EVENT_WAKEUP_AP, "",
5050 uid);
5051 getUidStatsLocked(uid).noteWifiRadioApWakeupLocked();
5052 }
5053
5054 public void noteWifiRadioPowerState(int powerState, long timestampNs, int uid) {
Joe Onoratoabded112016-02-08 16:49:39 -08005055 final long elapsedRealtime = mClocks.elapsedRealtime();
5056 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn0c820db2015-04-14 17:47:34 -07005057 if (mWifiRadioPowerState != powerState) {
5058 final boolean active =
5059 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM
5060 || powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH;
5061 if (active) {
Adam Lesinski5f056f62016-07-14 16:56:08 -07005062 if (uid > 0) {
5063 noteWifiRadioApWakeupLocked(elapsedRealtime, uptime, uid);
5064 }
Dianne Hackborn0c820db2015-04-14 17:47:34 -07005065 mHistoryCur.states |= HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
5066 } else {
5067 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_RADIO_ACTIVE_FLAG;
5068 }
5069 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi network active " + active + " to: "
5070 + Integer.toHexString(mHistoryCur.states));
5071 addHistoryRecordLocked(elapsedRealtime, uptime);
5072 mWifiRadioPowerState = powerState;
5073 }
5074 }
5075
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005076 public void noteWifiRunningLocked(WorkSource ws) {
5077 if (!mGlobalWifiRunning) {
Joe Onoratoabded112016-02-08 16:49:39 -08005078 final long elapsedRealtime = mClocks.elapsedRealtime();
5079 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07005080 mHistoryCur.states2 |= HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005081 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: "
5082 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005083 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005084 mGlobalWifiRunning = true;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005085 mGlobalWifiRunningTimer.startRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005086 int N = ws.size();
5087 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005088 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005089 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005090 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005091 scheduleSyncExternalStatsLocked("wifi-running", ExternalStatsSync.UPDATE_WIFI);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005092 } else {
5093 Log.w(TAG, "noteWifiRunningLocked -- called while WIFI running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07005094 }
5095 }
5096
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005097 public void noteWifiRunningChangedLocked(WorkSource oldWs, WorkSource newWs) {
5098 if (mGlobalWifiRunning) {
Joe Onoratoabded112016-02-08 16:49:39 -08005099 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005100 int N = oldWs.size();
5101 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005102 int uid = mapUid(oldWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005103 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005104 }
5105 N = newWs.size();
5106 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005107 int uid = mapUid(newWs.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005108 getUidStatsLocked(uid).noteWifiRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005109 }
5110 } else {
5111 Log.w(TAG, "noteWifiRunningChangedLocked -- called while WIFI not running");
5112 }
5113 }
5114
5115 public void noteWifiStoppedLocked(WorkSource ws) {
5116 if (mGlobalWifiRunning) {
Joe Onoratoabded112016-02-08 16:49:39 -08005117 final long elapsedRealtime = mClocks.elapsedRealtime();
5118 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07005119 mHistoryCur.states2 &= ~HistoryItem.STATE2_WIFI_RUNNING_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005120 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: "
5121 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005122 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005123 mGlobalWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005124 mGlobalWifiRunningTimer.stopRunningLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005125 int N = ws.size();
5126 for (int i=0; i<N; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005127 int uid = mapUid(ws.get(i));
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005128 getUidStatsLocked(uid).noteWifiStoppedLocked(elapsedRealtime);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005129 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005130 scheduleSyncExternalStatsLocked("wifi-stopped", ExternalStatsSync.UPDATE_WIFI);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005131 } else {
5132 Log.w(TAG, "noteWifiStoppedLocked -- called while WIFI not running");
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07005133 }
5134 }
5135
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005136 public void noteWifiStateLocked(int wifiState, String accessPoint) {
5137 if (DEBUG) Log.i(TAG, "WiFi state -> " + wifiState);
5138 if (mWifiState != wifiState) {
Joe Onoratoabded112016-02-08 16:49:39 -08005139 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005140 if (mWifiState >= 0) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005141 mWifiStateTimer[mWifiState].stopRunningLocked(elapsedRealtime);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005142 }
5143 mWifiState = wifiState;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005144 mWifiStateTimer[wifiState].startRunningLocked(elapsedRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005145 scheduleSyncExternalStatsLocked("wifi-state", ExternalStatsSync.UPDATE_WIFI);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005146 }
5147 }
5148
Dianne Hackborn3251b902014-06-20 14:40:53 -07005149 public void noteWifiSupplicantStateChangedLocked(int supplState, boolean failedAuth) {
5150 if (DEBUG) Log.i(TAG, "WiFi suppl state -> " + supplState);
5151 if (mWifiSupplState != supplState) {
Joe Onoratoabded112016-02-08 16:49:39 -08005152 final long elapsedRealtime = mClocks.elapsedRealtime();
5153 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07005154 if (mWifiSupplState >= 0) {
5155 mWifiSupplStateTimer[mWifiSupplState].stopRunningLocked(elapsedRealtime);
5156 }
5157 mWifiSupplState = supplState;
5158 mWifiSupplStateTimer[supplState].startRunningLocked(elapsedRealtime);
5159 mHistoryCur.states2 =
5160 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SUPPL_STATE_MASK)
5161 | (supplState << HistoryItem.STATE2_WIFI_SUPPL_STATE_SHIFT);
5162 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi suppl state " + supplState + " to: "
5163 + Integer.toHexString(mHistoryCur.states2));
5164 addHistoryRecordLocked(elapsedRealtime, uptime);
5165 }
5166 }
5167
5168 void stopAllWifiSignalStrengthTimersLocked(int except) {
Joe Onoratoabded112016-02-08 16:49:39 -08005169 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackborn3251b902014-06-20 14:40:53 -07005170 for (int i = 0; i < NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
5171 if (i == except) {
5172 continue;
5173 }
5174 while (mWifiSignalStrengthsTimer[i].isRunningLocked()) {
5175 mWifiSignalStrengthsTimer[i].stopRunningLocked(elapsedRealtime);
5176 }
5177 }
5178 }
5179
5180 public void noteWifiRssiChangedLocked(int newRssi) {
5181 int strengthBin = WifiManager.calculateSignalLevel(newRssi, NUM_WIFI_SIGNAL_STRENGTH_BINS);
5182 if (DEBUG) Log.i(TAG, "WiFi rssi -> " + newRssi + " bin=" + strengthBin);
5183 if (mWifiSignalStrengthBin != strengthBin) {
Joe Onoratoabded112016-02-08 16:49:39 -08005184 final long elapsedRealtime = mClocks.elapsedRealtime();
5185 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn3251b902014-06-20 14:40:53 -07005186 if (mWifiSignalStrengthBin >= 0) {
5187 mWifiSignalStrengthsTimer[mWifiSignalStrengthBin].stopRunningLocked(
5188 elapsedRealtime);
5189 }
5190 if (strengthBin >= 0) {
5191 if (!mWifiSignalStrengthsTimer[strengthBin].isRunningLocked()) {
5192 mWifiSignalStrengthsTimer[strengthBin].startRunningLocked(elapsedRealtime);
Bookatze5885242017-10-24 20:10:31 -07005193 StatsLog.write(StatsLog.WIFI_SIGNAL_STRENGTH_CHANGED, strengthBin);
Dianne Hackborn3251b902014-06-20 14:40:53 -07005194 }
5195 mHistoryCur.states2 =
5196 (mHistoryCur.states2&~HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_MASK)
5197 | (strengthBin << HistoryItem.STATE2_WIFI_SIGNAL_STRENGTH_SHIFT);
5198 if (DEBUG_HISTORY) Slog.v(TAG, "Wifi signal strength " + strengthBin + " to: "
5199 + Integer.toHexString(mHistoryCur.states2));
5200 addHistoryRecordLocked(elapsedRealtime, uptime);
5201 } else {
5202 stopAllWifiSignalStrengthTimersLocked(-1);
5203 }
5204 mWifiSignalStrengthBin = strengthBin;
5205 }
5206 }
5207
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005208 int mWifiFullLockNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005209
The Android Open Source Project10592532009-03-18 17:39:46 -07005210 public void noteFullWifiLockAcquiredLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005211 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005212 final long elapsedRealtime = mClocks.elapsedRealtime();
5213 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005214 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005215 mHistoryCur.states |= HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005216 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: "
5217 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005218 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005219 }
5220 mWifiFullLockNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005221 getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005222 }
5223
5224 public void noteFullWifiLockReleasedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005225 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005226 final long elapsedRealtime = mClocks.elapsedRealtime();
5227 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005228 mWifiFullLockNesting--;
5229 if (mWifiFullLockNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005230 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_FULL_LOCK_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005231 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: "
5232 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005233 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005234 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005235 getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005236 }
5237
Nick Pelly6ccaa542012-06-15 15:22:47 -07005238 int mWifiScanNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005239
Nick Pelly6ccaa542012-06-15 15:22:47 -07005240 public void noteWifiScanStartedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005241 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005242 final long elapsedRealtime = mClocks.elapsedRealtime();
5243 final long uptime = mClocks.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07005244 if (mWifiScanNesting == 0) {
5245 mHistoryCur.states |= HistoryItem.STATE_WIFI_SCAN_FLAG;
5246 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan started for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005247 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005248 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005249 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07005250 mWifiScanNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005251 getUidStatsLocked(uid).noteWifiScanStartedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005252 }
5253
Nick Pelly6ccaa542012-06-15 15:22:47 -07005254 public void noteWifiScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005255 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005256 final long elapsedRealtime = mClocks.elapsedRealtime();
5257 final long uptime = mClocks.uptimeMillis();
Nick Pelly6ccaa542012-06-15 15:22:47 -07005258 mWifiScanNesting--;
5259 if (mWifiScanNesting == 0) {
5260 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_SCAN_FLAG;
5261 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan stopped for: "
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005262 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005263 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005264 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005265 getUidStatsLocked(uid).noteWifiScanStoppedLocked(elapsedRealtime);
The Android Open Source Project10592532009-03-18 17:39:46 -07005266 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005267
Robert Greenwalta029ea12013-09-25 16:38:12 -07005268 public void noteWifiBatchedScanStartedLocked(int uid, int csph) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005269 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005270 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005271 getUidStatsLocked(uid).noteWifiBatchedScanStartedLocked(csph, elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005272 }
5273
5274 public void noteWifiBatchedScanStoppedLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005275 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005276 final long elapsedRealtime = mClocks.elapsedRealtime();
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005277 getUidStatsLocked(uid).noteWifiBatchedScanStoppedLocked(elapsedRealtime);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005278 }
5279
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005280 int mWifiMulticastNesting = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005281
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005282 public void noteWifiMulticastEnabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005283 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005284 final long elapsedRealtime = mClocks.elapsedRealtime();
5285 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005286 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005287 mHistoryCur.states |= HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005288 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: "
5289 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005290 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005291 }
5292 mWifiMulticastNesting++;
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005293 getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005294 }
5295
5296 public void noteWifiMulticastDisabledLocked(int uid) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08005297 uid = mapUid(uid);
Joe Onoratoabded112016-02-08 16:49:39 -08005298 final long elapsedRealtime = mClocks.elapsedRealtime();
5299 final long uptime = mClocks.uptimeMillis();
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005300 mWifiMulticastNesting--;
5301 if (mWifiMulticastNesting == 0) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07005302 mHistoryCur.states &= ~HistoryItem.STATE_WIFI_MULTICAST_ON_FLAG;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005303 if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: "
5304 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -07005305 addHistoryRecordLocked(elapsedRealtime, uptime);
Dianne Hackborn32907cf2010-06-10 17:50:20 -07005306 }
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005307 getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(elapsedRealtime);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005308 }
5309
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005310 public void noteFullWifiLockAcquiredFromSourceLocked(WorkSource ws) {
5311 int N = ws.size();
5312 for (int i=0; i<N; i++) {
5313 noteFullWifiLockAcquiredLocked(ws.get(i));
5314 }
5315 }
5316
5317 public void noteFullWifiLockReleasedFromSourceLocked(WorkSource ws) {
5318 int N = ws.size();
5319 for (int i=0; i<N; i++) {
5320 noteFullWifiLockReleasedLocked(ws.get(i));
5321 }
5322 }
5323
Nick Pelly6ccaa542012-06-15 15:22:47 -07005324 public void noteWifiScanStartedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005325 int N = ws.size();
5326 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005327 noteWifiScanStartedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005328 }
5329 }
5330
Nick Pelly6ccaa542012-06-15 15:22:47 -07005331 public void noteWifiScanStoppedFromSourceLocked(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005332 int N = ws.size();
5333 for (int i=0; i<N; i++) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07005334 noteWifiScanStoppedLocked(ws.get(i));
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005335 }
5336 }
5337
Robert Greenwalta029ea12013-09-25 16:38:12 -07005338 public void noteWifiBatchedScanStartedFromSourceLocked(WorkSource ws, int csph) {
5339 int N = ws.size();
5340 for (int i=0; i<N; i++) {
5341 noteWifiBatchedScanStartedLocked(ws.get(i), csph);
5342 }
5343 }
5344
5345 public void noteWifiBatchedScanStoppedFromSourceLocked(WorkSource ws) {
5346 int N = ws.size();
5347 for (int i=0; i<N; i++) {
5348 noteWifiBatchedScanStoppedLocked(ws.get(i));
5349 }
5350 }
5351
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -07005352 public void noteWifiMulticastEnabledFromSourceLocked(WorkSource ws) {
5353 int N = ws.size();
5354 for (int i=0; i<N; i++) {
5355 noteWifiMulticastEnabledLocked(ws.get(i));
5356 }
5357 }
5358
5359 public void noteWifiMulticastDisabledFromSourceLocked(WorkSource ws) {
5360 int N = ws.size();
5361 for (int i=0; i<N; i++) {
5362 noteWifiMulticastDisabledLocked(ws.get(i));
5363 }
5364 }
5365
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -08005366 private static String[] includeInStringArray(String[] array, String str) {
5367 if (ArrayUtils.indexOf(array, str) >= 0) {
5368 return array;
5369 }
5370 String[] newArray = new String[array.length+1];
5371 System.arraycopy(array, 0, newArray, 0, array.length);
5372 newArray[array.length] = str;
5373 return newArray;
5374 }
5375
5376 private static String[] excludeFromStringArray(String[] array, String str) {
5377 int index = ArrayUtils.indexOf(array, str);
5378 if (index >= 0) {
5379 String[] newArray = new String[array.length-1];
5380 if (index > 0) {
5381 System.arraycopy(array, 0, newArray, 0, index);
5382 }
5383 if (index < array.length-1) {
5384 System.arraycopy(array, index+1, newArray, index, array.length-index-1);
5385 }
5386 return newArray;
5387 }
5388 return array;
5389 }
5390
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005391 public void noteNetworkInterfaceTypeLocked(String iface, int networkType) {
Jeff Sharkey9da2f1e2014-08-14 12:55:00 -07005392 if (TextUtils.isEmpty(iface)) return;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005393
Adam Lesinski14ae39a2017-05-26 11:50:40 -07005394 synchronized (mModemNetworkLock) {
5395 if (ConnectivityManager.isNetworkTypeMobile(networkType)) {
5396 mModemIfaces = includeInStringArray(mModemIfaces, iface);
5397 if (DEBUG) Slog.d(TAG, "Note mobile iface " + iface + ": " + mModemIfaces);
5398 } else {
5399 mModemIfaces = excludeFromStringArray(mModemIfaces, iface);
5400 if (DEBUG) Slog.d(TAG, "Note non-mobile iface " + iface + ": " + mModemIfaces);
5401 }
5402 }
5403
5404 synchronized (mWifiNetworkLock) {
5405 if (ConnectivityManager.isNetworkTypeWifi(networkType)) {
5406 mWifiIfaces = includeInStringArray(mWifiIfaces, iface);
5407 if (DEBUG) Slog.d(TAG, "Note wifi iface " + iface + ": " + mWifiIfaces);
5408 } else {
5409 mWifiIfaces = excludeFromStringArray(mWifiIfaces, iface);
5410 if (DEBUG) Slog.d(TAG, "Note non-wifi iface " + iface + ": " + mWifiIfaces);
5411 }
5412 }
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07005413 }
5414
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005415 @Override public long getScreenOnTime(long elapsedRealtimeUs, int which) {
5416 return mScreenOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005417 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005418
Dianne Hackborn77b987f2014-02-26 16:20:52 -08005419 @Override public int getScreenOnCount(int which) {
5420 return mScreenOnTimer.getCountLocked(which);
5421 }
5422
Mike Mac2f518a2017-09-19 16:06:03 -07005423 @Override public long getScreenDozeTime(long elapsedRealtimeUs, int which) {
5424 return mScreenDozeTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5425 }
5426
5427 @Override public int getScreenDozeCount(int which) {
5428 return mScreenDozeTimer.getCountLocked(which);
5429 }
5430
Dianne Hackborn617f8772009-03-31 15:04:46 -07005431 @Override public long getScreenBrightnessTime(int brightnessBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005432 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07005433 return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005434 elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005435 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005436
Kweku Adams87b19ec2017-10-09 12:40:03 -07005437 @Override public Timer getScreenBrightnessTimer(int brightnessBin) {
5438 return mScreenBrightnessTimer[brightnessBin];
5439 }
5440
Jeff Browne95c3cd2014-05-02 16:59:26 -07005441 @Override public long getInteractiveTime(long elapsedRealtimeUs, int which) {
5442 return mInteractiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005443 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005444
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07005445 @Override public long getPowerSaveModeEnabledTime(long elapsedRealtimeUs, int which) {
5446 return mPowerSaveModeEnabledTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005447 }
5448
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07005449 @Override public int getPowerSaveModeEnabledCount(int which) {
5450 return mPowerSaveModeEnabledTimer.getCountLocked(which);
5451 }
5452
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005453 @Override public long getDeviceIdleModeTime(int mode, long elapsedRealtimeUs,
5454 int which) {
5455 switch (mode) {
5456 case DEVICE_IDLE_MODE_LIGHT:
5457 return mDeviceIdleModeLightTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005458 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005459 return mDeviceIdleModeFullTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5460 }
5461 return 0;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07005462 }
5463
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005464 @Override public int getDeviceIdleModeCount(int mode, int which) {
5465 switch (mode) {
5466 case DEVICE_IDLE_MODE_LIGHT:
5467 return mDeviceIdleModeLightTimer.getCountLocked(which);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005468 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005469 return mDeviceIdleModeFullTimer.getCountLocked(which);
5470 }
5471 return 0;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07005472 }
5473
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005474 @Override public long getLongestDeviceIdleModeTime(int mode) {
5475 switch (mode) {
5476 case DEVICE_IDLE_MODE_LIGHT:
5477 return mLongestLightIdleTime;
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005478 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005479 return mLongestFullIdleTime;
5480 }
5481 return 0;
Dianne Hackborn88e98df2015-03-23 13:29:14 -07005482 }
5483
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005484 @Override public long getDeviceIdlingTime(int mode, long elapsedRealtimeUs, int which) {
5485 switch (mode) {
5486 case DEVICE_IDLE_MODE_LIGHT:
5487 return mDeviceLightIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005488 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005489 return mDeviceIdlingTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5490 }
5491 return 0;
5492 }
5493
5494 @Override public int getDeviceIdlingCount(int mode, int which) {
5495 switch (mode) {
5496 case DEVICE_IDLE_MODE_LIGHT:
5497 return mDeviceLightIdlingTimer.getCountLocked(which);
Dianne Hackborn2fefbcf2016-03-18 15:34:54 -07005498 case DEVICE_IDLE_MODE_DEEP:
Dianne Hackborn08c47a52015-10-15 12:38:14 -07005499 return mDeviceIdlingTimer.getCountLocked(which);
5500 }
5501 return 0;
Dianne Hackborn88e98df2015-03-23 13:29:14 -07005502 }
5503
Dianne Hackborn1e01d162014-12-04 17:46:42 -08005504 @Override public int getNumConnectivityChange(int which) {
5505 int val = mNumConnectivityChange;
5506 if (which == STATS_CURRENT) {
5507 val -= mLoadedNumConnectivityChange;
5508 } else if (which == STATS_SINCE_UNPLUGGED) {
5509 val -= mUnpluggedNumConnectivityChange;
5510 }
5511 return val;
5512 }
5513
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005514 @Override public long getPhoneOnTime(long elapsedRealtimeUs, int which) {
5515 return mPhoneOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005516 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005517
Dianne Hackborn77b987f2014-02-26 16:20:52 -08005518 @Override public int getPhoneOnCount(int which) {
5519 return mPhoneOnTimer.getCountLocked(which);
5520 }
5521
Dianne Hackborn627bba72009-03-24 22:32:56 -07005522 @Override public long getPhoneSignalStrengthTime(int strengthBin,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005523 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07005524 return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005525 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005526 }
Amith Yamasanif37447b2009-10-08 18:28:01 -07005527
5528 @Override public long getPhoneSignalScanningTime(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005529 long elapsedRealtimeUs, int which) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07005530 return mPhoneSignalScanningTimer.getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005531 elapsedRealtimeUs, which);
Amith Yamasanif37447b2009-10-08 18:28:01 -07005532 }
5533
Kweku Adams87b19ec2017-10-09 12:40:03 -07005534 @Override public Timer getPhoneSignalScanningTimer() {
5535 return mPhoneSignalScanningTimer;
5536 }
5537
Catherine Liufb900812012-07-17 14:12:56 -05005538 @Override public int getPhoneSignalStrengthCount(int strengthBin, int which) {
5539 return mPhoneSignalStrengthsTimer[strengthBin].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005540 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005541
Kweku Adams87b19ec2017-10-09 12:40:03 -07005542 @Override public Timer getPhoneSignalStrengthTimer(int strengthBin) {
5543 return mPhoneSignalStrengthsTimer[strengthBin];
5544 }
5545
Dianne Hackborn627bba72009-03-24 22:32:56 -07005546 @Override public long getPhoneDataConnectionTime(int dataType,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005547 long elapsedRealtimeUs, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07005548 return mPhoneDataConnectionsTimer[dataType].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005549 elapsedRealtimeUs, which);
Dianne Hackborn627bba72009-03-24 22:32:56 -07005550 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005551
Dianne Hackborn617f8772009-03-31 15:04:46 -07005552 @Override public int getPhoneDataConnectionCount(int dataType, int which) {
Evan Millarc64edde2009-04-18 12:26:32 -07005553 return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07005554 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005555
Kweku Adams87b19ec2017-10-09 12:40:03 -07005556 @Override public Timer getPhoneDataConnectionTimer(int dataType) {
5557 return mPhoneDataConnectionsTimer[dataType];
5558 }
5559
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005560 @Override public long getMobileRadioActiveTime(long elapsedRealtimeUs, int which) {
5561 return mMobileRadioActiveTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborne13c4c02014-02-11 17:18:35 -08005562 }
5563
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005564 @Override public int getMobileRadioActiveCount(int which) {
5565 return mMobileRadioActiveTimer.getCountLocked(which);
5566 }
5567
Dianne Hackborna1bd7922014-03-21 11:07:11 -07005568 @Override public long getMobileRadioActiveAdjustedTime(int which) {
5569 return mMobileRadioActiveAdjustedTime.getCountLocked(which);
5570 }
5571
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005572 @Override public long getMobileRadioActiveUnknownTime(int which) {
5573 return mMobileRadioActiveUnknownTime.getCountLocked(which);
5574 }
5575
5576 @Override public int getMobileRadioActiveUnknownCount(int which) {
5577 return (int)mMobileRadioActiveUnknownCount.getCountLocked(which);
5578 }
5579
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005580 @Override public long getWifiOnTime(long elapsedRealtimeUs, int which) {
5581 return mWifiOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07005582 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005583
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005584 @Override public long getGlobalWifiRunningTime(long elapsedRealtimeUs, int which) {
5585 return mGlobalWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -07005586 }
5587
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005588 @Override public long getWifiStateTime(int wifiState,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005589 long elapsedRealtimeUs, int which) {
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005590 return mWifiStateTimer[wifiState].getTotalTimeLocked(
Dianne Hackborn97ae5382014-03-05 16:43:25 -08005591 elapsedRealtimeUs, which);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08005592 }
5593
5594 @Override public int getWifiStateCount(int wifiState, int which) {
5595 return mWifiStateTimer[wifiState].getCountLocked(which);
5596 }
5597
Kweku Adams87b19ec2017-10-09 12:40:03 -07005598 @Override public Timer getWifiStateTimer(int wifiState) {
5599 return mWifiStateTimer[wifiState];
5600 }
5601
Dianne Hackborn3251b902014-06-20 14:40:53 -07005602 @Override public long getWifiSupplStateTime(int state,
5603 long elapsedRealtimeUs, int which) {
5604 return mWifiSupplStateTimer[state].getTotalTimeLocked(
5605 elapsedRealtimeUs, which);
5606 }
5607
5608 @Override public int getWifiSupplStateCount(int state, int which) {
5609 return mWifiSupplStateTimer[state].getCountLocked(which);
5610 }
5611
Kweku Adams87b19ec2017-10-09 12:40:03 -07005612 @Override public Timer getWifiSupplStateTimer(int state) {
5613 return mWifiSupplStateTimer[state];
5614 }
5615
Dianne Hackborn3251b902014-06-20 14:40:53 -07005616 @Override public long getWifiSignalStrengthTime(int strengthBin,
5617 long elapsedRealtimeUs, int which) {
5618 return mWifiSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
5619 elapsedRealtimeUs, which);
5620 }
5621
5622 @Override public int getWifiSignalStrengthCount(int strengthBin, int which) {
5623 return mWifiSignalStrengthsTimer[strengthBin].getCountLocked(which);
5624 }
5625
Kweku Adams87b19ec2017-10-09 12:40:03 -07005626 @Override public Timer getWifiSignalStrengthTimer(int strengthBin) {
5627 return mWifiSignalStrengthsTimer[strengthBin];
5628 }
5629
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005630 @Override
5631 public ControllerActivityCounter getBluetoothControllerActivity() {
5632 return mBluetoothActivity;
Adam Lesinski17390762015-04-10 13:17:47 -07005633 }
5634
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005635 @Override
5636 public ControllerActivityCounter getWifiControllerActivity() {
5637 return mWifiActivity;
Adam Lesinski33dac552015-03-09 15:24:48 -07005638 }
5639
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005640 @Override
5641 public ControllerActivityCounter getModemControllerActivity() {
5642 return mModemActivity;
Adam Lesinski17390762015-04-10 13:17:47 -07005643 }
5644
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005645 @Override
5646 public boolean hasBluetoothActivityReporting() {
5647 return mHasBluetoothReporting;
5648 }
5649
5650 @Override
5651 public boolean hasWifiActivityReporting() {
5652 return mHasWifiReporting;
5653 }
5654
5655 @Override
5656 public boolean hasModemActivityReporting() {
5657 return mHasModemReporting;
Adam Lesinski33dac552015-03-09 15:24:48 -07005658 }
5659
Ruben Brunk5b1308f2015-06-03 18:49:27 -07005660 @Override
5661 public long getFlashlightOnTime(long elapsedRealtimeUs, int which) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -07005662 return mFlashlightOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5663 }
5664
Ruben Brunk5b1308f2015-06-03 18:49:27 -07005665 @Override
5666 public long getFlashlightOnCount(int which) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -07005667 return mFlashlightOnTimer.getCountLocked(which);
5668 }
5669
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005670 @Override
Ruben Brunk5b1308f2015-06-03 18:49:27 -07005671 public long getCameraOnTime(long elapsedRealtimeUs, int which) {
5672 return mCameraOnTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5673 }
5674
5675 @Override
Adam Lesinski9f55cc72016-01-27 20:42:14 -08005676 public long getBluetoothScanTime(long elapsedRealtimeUs, int which) {
5677 return mBluetoothScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
5678 }
5679
5680 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005681 public long getNetworkActivityBytes(int type, int which) {
5682 if (type >= 0 && type < mNetworkByteActivityCounters.length) {
5683 return mNetworkByteActivityCounters[type].getCountLocked(which);
5684 } else {
5685 return 0;
5686 }
5687 }
5688
5689 @Override
5690 public long getNetworkActivityPackets(int type, int which) {
5691 if (type >= 0 && type < mNetworkPacketActivityCounters.length) {
5692 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005693 } else {
5694 return 0;
5695 }
5696 }
5697
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08005698 @Override public long getStartClockTime() {
Dianne Hackbornd48954f2015-07-22 17:20:33 -07005699 final long currentTime = System.currentTimeMillis();
5700 if (ensureStartClockTime(currentTime)) {
Joe Onoratoabded112016-02-08 16:49:39 -08005701 recordCurrentTimeChangeLocked(currentTime, mClocks.elapsedRealtime(),
5702 mClocks.uptimeMillis());
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -07005703 }
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08005704 return mStartClockTime;
5705 }
5706
Dianne Hackborncd0e3352014-08-07 17:08:09 -07005707 @Override public String getStartPlatformVersion() {
5708 return mStartPlatformVersion;
5709 }
5710
5711 @Override public String getEndPlatformVersion() {
5712 return mEndPlatformVersion;
5713 }
5714
5715 @Override public int getParcelVersion() {
5716 return VERSION;
5717 }
5718
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005719 @Override public boolean getIsOnBattery() {
5720 return mOnBattery;
5721 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005723 @Override public SparseArray<? extends BatteryStats.Uid> getUidStats() {
5724 return mUidStats;
5725 }
5726
Adam Lesinski5f056f62016-07-14 16:56:08 -07005727 private static void detachTimerIfNotNull(BatteryStatsImpl.Timer timer) {
5728 if (timer != null) {
5729 timer.detach();
5730 }
5731 }
5732
5733 private static boolean resetTimerIfNotNull(BatteryStatsImpl.Timer timer,
5734 boolean detachIfReset) {
5735 if (timer != null) {
5736 return timer.reset(detachIfReset);
5737 }
5738 return true;
5739 }
5740
Bookatz867c0d72017-03-07 18:23:42 -08005741 private static boolean resetTimerIfNotNull(DualTimer timer, boolean detachIfReset) {
5742 if (timer != null) {
5743 return timer.reset(detachIfReset);
5744 }
5745 return true;
5746 }
5747
Adam Lesinski5f056f62016-07-14 16:56:08 -07005748 private static void detachLongCounterIfNotNull(LongSamplingCounter counter) {
5749 if (counter != null) {
5750 counter.detach();
5751 }
5752 }
5753
5754 private static void resetLongCounterIfNotNull(LongSamplingCounter counter,
5755 boolean detachIfReset) {
5756 if (counter != null) {
5757 counter.reset(detachIfReset);
5758 }
5759 }
5760
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005761 /**
5762 * The statistics associated with a particular uid.
5763 */
Joe Onoratoabded112016-02-08 16:49:39 -08005764 public static class Uid extends BatteryStats.Uid {
5765 /**
5766 * BatteryStatsImpl that we are associated with.
5767 */
5768 protected BatteryStatsImpl mBsi;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005769
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005770 final int mUid;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005771
Bookatz867c0d72017-03-07 18:23:42 -08005772 /** TimeBase for when uid is in background and device is on battery. */
5773 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
5774 public final TimeBase mOnBatteryBackgroundTimeBase;
Bookatzc8c44962017-05-11 12:12:54 -07005775 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
5776 public final TimeBase mOnBatteryScreenOffBackgroundTimeBase;
Bookatz867c0d72017-03-07 18:23:42 -08005777
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07005778 boolean mWifiRunning;
5779 StopwatchTimer mWifiRunningTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005780
The Android Open Source Project10592532009-03-18 17:39:46 -07005781 boolean mFullWifiLockOut;
Evan Millarc64edde2009-04-18 12:26:32 -07005782 StopwatchTimer mFullWifiLockTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005783
Nick Pelly6ccaa542012-06-15 15:22:47 -07005784 boolean mWifiScanStarted;
Bookatz867c0d72017-03-07 18:23:42 -08005785 DualTimer mWifiScanTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005786
Dianne Hackborn61659e52014-07-09 16:13:01 -07005787 static final int NO_BATCHED_SCAN_STARTED = -1;
Robert Greenwalta029ea12013-09-25 16:38:12 -07005788 int mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
5789 StopwatchTimer[] mWifiBatchedScanTimer;
5790
Robert Greenwalt5347bd42009-05-13 15:10:16 -07005791 boolean mWifiMulticastEnabled;
5792 StopwatchTimer mWifiMulticastTimer;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005793
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005794 StopwatchTimer mAudioTurnedOnTimer;
Amith Yamasani244fa5c2009-05-22 14:36:07 -07005795 StopwatchTimer mVideoTurnedOnTimer;
Ruben Brunk6d2c3632015-05-26 17:32:16 -07005796 StopwatchTimer mFlashlightTurnedOnTimer;
5797 StopwatchTimer mCameraTurnedOnTimer;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005798 StopwatchTimer mForegroundActivityTimer;
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07005799 StopwatchTimer mForegroundServiceTimer;
Bookatzc8c44962017-05-11 12:12:54 -07005800 /** Total time spent by the uid holding any partial wakelocks. */
5801 DualTimer mAggregatedPartialWakelockTimer;
Bookatz867c0d72017-03-07 18:23:42 -08005802 DualTimer mBluetoothScanTimer;
Bookatzb1f04f32017-05-19 13:57:32 -07005803 DualTimer mBluetoothUnoptimizedScanTimer;
Bookatz956f36bf2017-04-28 09:48:17 -07005804 Counter mBluetoothScanResultCounter;
Bookatzb1f04f32017-05-19 13:57:32 -07005805 Counter mBluetoothScanResultBgCounter;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07005806
Dianne Hackborna8d10942015-11-19 17:55:19 -08005807 int mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
Dianne Hackborn61659e52014-07-09 16:13:01 -07005808 StopwatchTimer[] mProcessStateTimer;
5809
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07005810 boolean mInForegroundService = false;
5811
Dianne Hackborna06de0f2012-12-11 16:34:47 -08005812 BatchTimer mVibratorOnTimer;
5813
Dianne Hackborn617f8772009-03-31 15:04:46 -07005814 Counter[] mUserActivityCounters;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005815
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08005816 LongSamplingCounter[] mNetworkByteActivityCounters;
5817 LongSamplingCounter[] mNetworkPacketActivityCounters;
Dianne Hackbornd45665b2014-02-26 12:35:32 -08005818 LongSamplingCounter mMobileRadioActiveTime;
5819 LongSamplingCounter mMobileRadioActiveCount;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07005820
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005821 /**
Adam Lesinski5f056f62016-07-14 16:56:08 -07005822 * How many times this UID woke up the Application Processor due to a Mobile radio packet.
5823 */
5824 private LongSamplingCounter mMobileRadioApWakeupCount;
5825
5826 /**
5827 * How many times this UID woke up the Application Processor due to a Wifi packet.
5828 */
5829 private LongSamplingCounter mWifiRadioApWakeupCount;
5830
5831 /**
Adam Lesinskie08af192015-03-25 16:42:59 -07005832 * The amount of time this uid has kept the WiFi controller in idle, tx, and rx mode.
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005833 * Can be null if the UID has had no such activity.
Adam Lesinskie08af192015-03-25 16:42:59 -07005834 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005835 private ControllerActivityCounterImpl mWifiControllerActivity;
Adam Lesinskie08af192015-03-25 16:42:59 -07005836
5837 /**
5838 * The amount of time this uid has kept the Bluetooth controller in idle, tx, and rx mode.
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005839 * Can be null if the UID has had no such activity.
Adam Lesinskie08af192015-03-25 16:42:59 -07005840 */
Adam Lesinski21f76aa2016-01-25 12:27:06 -08005841 private ControllerActivityCounterImpl mBluetoothControllerActivity;
5842
5843 /**
5844 * The amount of time this uid has kept the Modem controller in idle, tx, and rx mode.
5845 * Can be null if the UID has had no such activity.
5846 */
5847 private ControllerActivityCounterImpl mModemControllerActivity;
Adam Lesinskie08af192015-03-25 16:42:59 -07005848
5849 /**
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005850 * The CPU times we had at the last history details update.
5851 */
5852 long mLastStepUserTime;
5853 long mLastStepSystemTime;
5854 long mCurStepUserTime;
5855 long mCurStepSystemTime;
5856
Joe Onoratoabded112016-02-08 16:49:39 -08005857 LongSamplingCounter mUserCpuTime;
5858 LongSamplingCounter mSystemCpuTime;
Sudheer Shankaaf857412017-07-21 00:14:24 -07005859 LongSamplingCounter[][] mCpuClusterSpeedTimesUs;
Adam Lesinski06af1fa2015-05-05 17:35:35 -07005860
Sudheer Shanka9b735c52017-05-09 18:26:18 -07005861 LongSamplingCounterArray mCpuFreqTimeMs;
5862 LongSamplingCounterArray mScreenOffCpuFreqTimeMs;
5863
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08005864 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005865 * The statistics we have collected for this uid's wake locks.
5866 */
Joe Onoratoabded112016-02-08 16:49:39 -08005867 final OverflowArrayMap<Wakelock> mWakelockStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005868
5869 /**
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005870 * The statistics we have collected for this uid's syncs.
5871 */
Bookatz2bffb5b2017-04-13 11:59:33 -07005872 final OverflowArrayMap<DualTimer> mSyncStats;
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005873
5874 /**
5875 * The statistics we have collected for this uid's jobs.
5876 */
Bookatzaa4594a2017-03-24 12:39:56 -07005877 final OverflowArrayMap<DualTimer> mJobStats;
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005878
5879 /**
Dianne Hackborn94326cb2017-06-28 16:17:20 -07005880 * Count of the jobs that have completed and the reasons why they completed.
5881 */
5882 final ArrayMap<String, SparseIntArray> mJobCompletions = new ArrayMap<>();
5883
5884 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005885 * The statistics we have collected for this uid's sensor activations.
5886 */
Adam Lesinskie08af192015-03-25 16:42:59 -07005887 final SparseArray<Sensor> mSensorStats = new SparseArray<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005888
5889 /**
5890 * The statistics we have collected for this uid's processes.
5891 */
Adam Lesinskie08af192015-03-25 16:42:59 -07005892 final ArrayMap<String, Proc> mProcessStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005893
5894 /**
5895 * The statistics we have collected for this uid's processes.
5896 */
Adam Lesinskie08af192015-03-25 16:42:59 -07005897 final ArrayMap<String, Pkg> mPackageStats = new ArrayMap<>();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07005898
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005899 /**
5900 * The transient wake stats we have collected for this uid's pids.
5901 */
Adam Lesinskie08af192015-03-25 16:42:59 -07005902 final SparseArray<Pid> mPids = new SparseArray<>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07005903
Joe Onoratoabded112016-02-08 16:49:39 -08005904 public Uid(BatteryStatsImpl bsi, int uid) {
5905 mBsi = bsi;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005906 mUid = uid;
Joe Onoratoabded112016-02-08 16:49:39 -08005907
Bookatz867c0d72017-03-07 18:23:42 -08005908 mOnBatteryBackgroundTimeBase = new TimeBase();
5909 mOnBatteryBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
5910 mBsi.mClocks.elapsedRealtime() * 1000);
5911
Bookatzc8c44962017-05-11 12:12:54 -07005912 mOnBatteryScreenOffBackgroundTimeBase = new TimeBase();
5913 mOnBatteryScreenOffBackgroundTimeBase.init(mBsi.mClocks.uptimeMillis() * 1000,
5914 mBsi.mClocks.elapsedRealtime() * 1000);
5915
Joe Onoratoabded112016-02-08 16:49:39 -08005916 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
5917 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
Joe Onoratoabded112016-02-08 16:49:39 -08005918
Dianne Hackborn657153b2016-07-29 14:54:14 -07005919 mWakelockStats = mBsi.new OverflowArrayMap<Wakelock>(uid) {
Joe Onoratoabded112016-02-08 16:49:39 -08005920 @Override public Wakelock instantiateObject() {
5921 return new Wakelock(mBsi, Uid.this);
5922 }
5923 };
Bookatz2bffb5b2017-04-13 11:59:33 -07005924 mSyncStats = mBsi.new OverflowArrayMap<DualTimer>(uid) {
5925 @Override public DualTimer instantiateObject() {
5926 return new DualTimer(mBsi.mClocks, Uid.this, SYNC, null,
5927 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
Joe Onoratoabded112016-02-08 16:49:39 -08005928 }
5929 };
Bookatzaa4594a2017-03-24 12:39:56 -07005930 mJobStats = mBsi.new OverflowArrayMap<DualTimer>(uid) {
5931 @Override public DualTimer instantiateObject() {
5932 return new DualTimer(mBsi.mClocks, Uid.this, JOB, null,
5933 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
Joe Onoratoabded112016-02-08 16:49:39 -08005934 }
5935 };
5936
5937 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_RUNNING,
5938 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase);
5939 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, this, FULL_WIFI_LOCK,
5940 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase);
Bookatz867c0d72017-03-07 18:23:42 -08005941 mWifiScanTimer = new DualTimer(mBsi.mClocks, this, WIFI_SCAN,
5942 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07005943 mWifiBatchedScanTimer = new StopwatchTimer[NUM_WIFI_BATCHED_SCAN_BINS];
Joe Onoratoabded112016-02-08 16:49:39 -08005944 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, this, WIFI_MULTICAST_ENABLED,
5945 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborn61659e52014-07-09 16:13:01 -07005946 mProcessStateTimer = new StopwatchTimer[NUM_PROCESS_STATE];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005947 }
5948
5949 @Override
Sudheer Shanka9b735c52017-05-09 18:26:18 -07005950 public long[] getCpuFreqTimes(int which) {
5951 if (mCpuFreqTimeMs == null) {
5952 return null;
5953 }
5954 final long[] cpuFreqTimes = mCpuFreqTimeMs.getCountsLocked(which);
5955 if (cpuFreqTimes == null) {
5956 return null;
5957 }
5958 // Return cpuFreqTimes only if atleast one of the elements in non-zero.
5959 for (int i = 0; i < cpuFreqTimes.length; ++i) {
5960 if (cpuFreqTimes[i] != 0) {
5961 return cpuFreqTimes;
5962 }
5963 }
5964 return null;
5965 }
5966
5967 @Override
5968 public long[] getScreenOffCpuFreqTimes(int which) {
5969 if (mScreenOffCpuFreqTimeMs == null) {
5970 return null;
5971 }
5972 final long[] cpuFreqTimes = mScreenOffCpuFreqTimeMs.getCountsLocked(which);
5973 if (cpuFreqTimes == null) {
5974 return null;
5975 }
5976 // Return cpuFreqTimes only if atleast one of the elements in non-zero.
5977 for (int i = 0; i < cpuFreqTimes.length; ++i) {
5978 if (cpuFreqTimes[i] != 0) {
5979 return cpuFreqTimes;
5980 }
5981 }
5982 return null;
5983 }
5984
5985 @Override
Bookatzc8c44962017-05-11 12:12:54 -07005986 public Timer getAggregatedPartialWakelockTimer() {
5987 return mAggregatedPartialWakelockTimer;
5988 }
5989
5990 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07005991 public ArrayMap<String, ? extends BatteryStats.Uid.Wakelock> getWakelockStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005992 return mWakelockStats.getMap();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08005993 }
5994
5995 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07005996 public ArrayMap<String, ? extends BatteryStats.Timer> getSyncStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07005997 return mSyncStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07005998 }
5999
6000 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006001 public ArrayMap<String, ? extends BatteryStats.Timer> getJobStats() {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006002 return mJobStats.getMap();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006003 }
6004
6005 @Override
Dianne Hackborn94326cb2017-06-28 16:17:20 -07006006 public ArrayMap<String, SparseIntArray> getJobCompletionStats() {
6007 return mJobCompletions;
6008 }
6009
6010 @Override
Dianne Hackborn61659e52014-07-09 16:13:01 -07006011 public SparseArray<? extends BatteryStats.Uid.Sensor> getSensorStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006012 return mSensorStats;
6013 }
6014
6015 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006016 public ArrayMap<String, ? extends BatteryStats.Uid.Proc> getProcessStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006017 return mProcessStats;
6018 }
6019
6020 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07006021 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg> getPackageStats() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006022 return mPackageStats;
6023 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006024
6025 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006026 public int getUid() {
6027 return mUid;
6028 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07006029
6030 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006031 public void noteWifiRunningLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006032 if (!mWifiRunning) {
6033 mWifiRunning = true;
6034 if (mWifiRunningTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006035 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING,
6036 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006037 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006038 mWifiRunningTimer.startRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006039 }
6040 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006041
Dianne Hackborn617f8772009-03-31 15:04:46 -07006042 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006043 public void noteWifiStoppedLocked(long elapsedRealtimeMs) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006044 if (mWifiRunning) {
6045 mWifiRunning = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006046 mWifiRunningTimer.stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006047 }
6048 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006049
Dianne Hackborn617f8772009-03-31 15:04:46 -07006050 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006051 public void noteFullWifiLockAcquiredLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07006052 if (!mFullWifiLockOut) {
6053 mFullWifiLockOut = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006054 if (mFullWifiLockTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006055 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK,
6056 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006057 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006058 mFullWifiLockTimer.startRunningLocked(elapsedRealtimeMs);
Bookatze5885242017-10-24 20:10:31 -07006059 // TODO(statsd): Possibly use a worksource instead of a uid.
6060 StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED, getUid(), 1);
The Android Open Source Project10592532009-03-18 17:39:46 -07006061 }
6062 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006063
The Android Open Source Project10592532009-03-18 17:39:46 -07006064 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006065 public void noteFullWifiLockReleasedLocked(long elapsedRealtimeMs) {
The Android Open Source Project10592532009-03-18 17:39:46 -07006066 if (mFullWifiLockOut) {
6067 mFullWifiLockOut = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006068 mFullWifiLockTimer.stopRunningLocked(elapsedRealtimeMs);
Bookatze5885242017-10-24 20:10:31 -07006069 if (!mFullWifiLockTimer.isRunningLocked()) { // only tell statsd if truly stopped
6070 // TODO(statsd): Possibly use a worksource instead of a uid.
6071 StatsLog.write(StatsLog.WIFI_LOCK_STATE_CHANGED, getUid(), 0);
6072 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006073 }
6074 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006075
The Android Open Source Project10592532009-03-18 17:39:46 -07006076 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006077 public void noteWifiScanStartedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07006078 if (!mWifiScanStarted) {
6079 mWifiScanStarted = true;
6080 if (mWifiScanTimer == null) {
Bookatz867c0d72017-03-07 18:23:42 -08006081 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN,
6082 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase,
6083 mOnBatteryBackgroundTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006084 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006085 mWifiScanTimer.startRunningLocked(elapsedRealtimeMs);
Bookatze5885242017-10-24 20:10:31 -07006086 // TODO(statsd): Possibly use a worksource instead of a uid.
6087 StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED, getUid(), 1);
The Android Open Source Project10592532009-03-18 17:39:46 -07006088 }
6089 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006090
The Android Open Source Project10592532009-03-18 17:39:46 -07006091 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006092 public void noteWifiScanStoppedLocked(long elapsedRealtimeMs) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07006093 if (mWifiScanStarted) {
6094 mWifiScanStarted = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006095 mWifiScanTimer.stopRunningLocked(elapsedRealtimeMs);
Bookatze5885242017-10-24 20:10:31 -07006096 if (!mWifiScanTimer.isRunningLocked()) { // only tell statsd if truly stopped
6097 // TODO(statsd): Possibly use a worksource instead of a uid.
6098 StatsLog.write(StatsLog.WIFI_SCAN_STATE_CHANGED, getUid(), 0);
6099 }
The Android Open Source Project10592532009-03-18 17:39:46 -07006100 }
6101 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006102
6103 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006104 public void noteWifiBatchedScanStartedLocked(int csph, long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07006105 int bin = 0;
Navtej Singh Mann3c0ce5c2015-06-11 16:53:11 -07006106 while (csph > 8 && bin < NUM_WIFI_BATCHED_SCAN_BINS-1) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07006107 csph = csph >> 3;
6108 bin++;
6109 }
6110
6111 if (mWifiBatchedScanBinStarted == bin) return;
6112
6113 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
6114 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006115 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006116 }
6117 mWifiBatchedScanBinStarted = bin;
6118 if (mWifiBatchedScanTimer[bin] == null) {
6119 makeWifiBatchedScanBin(bin, null);
6120 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006121 mWifiBatchedScanTimer[bin].startRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006122 }
6123
6124 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006125 public void noteWifiBatchedScanStoppedLocked(long elapsedRealtimeMs) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07006126 if (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED) {
6127 mWifiBatchedScanTimer[mWifiBatchedScanBinStarted].
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006128 stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006129 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
6130 }
6131 }
6132
6133 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006134 public void noteWifiMulticastEnabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006135 if (!mWifiMulticastEnabled) {
6136 mWifiMulticastEnabled = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006137 if (mWifiMulticastTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006138 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
6139 WIFI_MULTICAST_ENABLED, mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006140 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006141 mWifiMulticastTimer.startRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006142 }
6143 }
6144
6145 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006146 public void noteWifiMulticastDisabledLocked(long elapsedRealtimeMs) {
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006147 if (mWifiMulticastEnabled) {
6148 mWifiMulticastEnabled = false;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006149 mWifiMulticastTimer.stopRunningLocked(elapsedRealtimeMs);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006150 }
6151 }
6152
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006153 @Override
6154 public ControllerActivityCounter getWifiControllerActivity() {
6155 return mWifiControllerActivity;
Adam Lesinskie08af192015-03-25 16:42:59 -07006156 }
6157
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006158 @Override
6159 public ControllerActivityCounter getBluetoothControllerActivity() {
6160 return mBluetoothControllerActivity;
6161 }
6162
6163 @Override
6164 public ControllerActivityCounter getModemControllerActivity() {
6165 return mModemControllerActivity;
6166 }
6167
6168 public ControllerActivityCounterImpl getOrCreateWifiControllerActivityLocked() {
6169 if (mWifiControllerActivity == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006170 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006171 NUM_BT_TX_LEVELS);
Adam Lesinski50e47602015-12-04 17:04:54 -08006172 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006173 return mWifiControllerActivity;
6174 }
6175
6176 public ControllerActivityCounterImpl getOrCreateBluetoothControllerActivityLocked() {
6177 if (mBluetoothControllerActivity == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006178 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006179 NUM_BT_TX_LEVELS);
6180 }
6181 return mBluetoothControllerActivity;
6182 }
6183
6184 public ControllerActivityCounterImpl getOrCreateModemControllerActivityLocked() {
6185 if (mModemControllerActivity == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006186 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006187 ModemActivityInfo.TX_POWER_LEVELS);
6188 }
6189 return mModemControllerActivity;
Adam Lesinski50e47602015-12-04 17:04:54 -08006190 }
6191
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006192 public StopwatchTimer createAudioTurnedOnTimerLocked() {
6193 if (mAudioTurnedOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006194 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON,
6195 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006196 }
6197 return mAudioTurnedOnTimer;
6198 }
6199
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006200 public void noteAudioTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006201 createAudioTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006202 // TODO(statsd): Possibly use a worksource instead of a uid.
6203 StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, getUid(), 1);
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006204 }
6205
6206 public void noteAudioTurnedOffLocked(long elapsedRealtimeMs) {
6207 if (mAudioTurnedOnTimer != null) {
6208 mAudioTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006209 if (!mAudioTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
6210 // TODO(statsd): Possibly use a worksource instead of a uid.
6211 StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, getUid(), 0);
6212 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006213 }
6214 }
6215
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006216 public void noteResetAudioLocked(long elapsedRealtimeMs) {
6217 if (mAudioTurnedOnTimer != null) {
6218 mAudioTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006219 // TODO(statsd): Possibly use a worksource instead of a uid.
6220 StatsLog.write(StatsLog.AUDIO_STATE_CHANGED, getUid(), 0);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006221 }
6222 }
6223
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006224 public StopwatchTimer createVideoTurnedOnTimerLocked() {
6225 if (mVideoTurnedOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006226 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON,
6227 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006228 }
6229 return mVideoTurnedOnTimer;
6230 }
6231
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006232 public void noteVideoTurnedOnLocked(long elapsedRealtimeMs) {
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006233 createVideoTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006234 // TODO(statsd): Possibly use a worksource instead of a uid.
6235 StatsLog.write(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), 1);
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006236 }
6237
6238 public void noteVideoTurnedOffLocked(long elapsedRealtimeMs) {
6239 if (mVideoTurnedOnTimer != null) {
6240 mVideoTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006241 if (!mVideoTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
6242 // TODO(statsd): Possibly use a worksource instead of a uid.
6243 StatsLog.write(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), 0);
6244 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006245 }
6246 }
6247
Dianne Hackborn10eaa852014-07-22 22:54:55 -07006248 public void noteResetVideoLocked(long elapsedRealtimeMs) {
6249 if (mVideoTurnedOnTimer != null) {
6250 mVideoTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006251 // TODO(statsd): Possibly use a worksource instead of a uid.
6252 StatsLog.write(StatsLog.MEDIA_CODEC_ACTIVITY_CHANGED, getUid(), 0);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006253 }
6254 }
6255
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006256 public StopwatchTimer createFlashlightTurnedOnTimerLocked() {
6257 if (mFlashlightTurnedOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006258 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
6259 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006260 }
6261 return mFlashlightTurnedOnTimer;
6262 }
6263
6264 public void noteFlashlightTurnedOnLocked(long elapsedRealtimeMs) {
6265 createFlashlightTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006266 // TODO(statsd): Possibly use a worksource instead of a uid.
6267 StatsLog.write(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), 1);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006268 }
6269
6270 public void noteFlashlightTurnedOffLocked(long elapsedRealtimeMs) {
6271 if (mFlashlightTurnedOnTimer != null) {
6272 mFlashlightTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006273 if (!mFlashlightTurnedOnTimer.isRunningLocked()) {
6274 // TODO(statsd): Possibly use a worksource instead of a uid.
6275 StatsLog.write(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), 0);
6276 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006277 }
6278 }
6279
6280 public void noteResetFlashlightLocked(long elapsedRealtimeMs) {
6281 if (mFlashlightTurnedOnTimer != null) {
6282 mFlashlightTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006283 // TODO(statsd): Possibly use a worksource instead of a uid.
6284 StatsLog.write(StatsLog.FLASHLIGHT_STATE_CHANGED, getUid(), 0);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006285 }
6286 }
6287
6288 public StopwatchTimer createCameraTurnedOnTimerLocked() {
6289 if (mCameraTurnedOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006290 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON,
6291 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006292 }
6293 return mCameraTurnedOnTimer;
6294 }
6295
6296 public void noteCameraTurnedOnLocked(long elapsedRealtimeMs) {
6297 createCameraTurnedOnTimerLocked().startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006298 // TODO(statsd): Possibly use a worksource instead of a uid.
6299 StatsLog.write(StatsLog.CAMERA_STATE_CHANGED, getUid(), 1);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006300 }
6301
6302 public void noteCameraTurnedOffLocked(long elapsedRealtimeMs) {
6303 if (mCameraTurnedOnTimer != null) {
6304 mCameraTurnedOnTimer.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006305 if (!mCameraTurnedOnTimer.isRunningLocked()) { // only tell statsd if truly stopped
6306 // TODO(statsd): Possibly use a worksource instead of a uid.
6307 StatsLog.write(StatsLog.CAMERA_STATE_CHANGED, getUid(), 0);
6308 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006309 }
6310 }
6311
6312 public void noteResetCameraLocked(long elapsedRealtimeMs) {
6313 if (mCameraTurnedOnTimer != null) {
6314 mCameraTurnedOnTimer.stopAllRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006315 // TODO(statsd): Possibly use a worksource instead of a uid.
6316 StatsLog.write(StatsLog.CAMERA_STATE_CHANGED, getUid(), 0);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006317 }
6318 }
6319
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006320 public StopwatchTimer createForegroundActivityTimerLocked() {
6321 if (mForegroundActivityTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006322 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
6323 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006324 }
6325 return mForegroundActivityTimer;
6326 }
6327
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07006328 public StopwatchTimer createForegroundServiceTimerLocked() {
6329 if (mForegroundServiceTimer == null) {
6330 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
6331 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase);
6332 }
6333 return mForegroundServiceTimer;
6334 }
6335
Bookatzc8c44962017-05-11 12:12:54 -07006336 public DualTimer createAggregatedPartialWakelockTimerLocked() {
6337 if (mAggregatedPartialWakelockTimer == null) {
6338 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
6339 AGGREGATED_WAKE_TYPE_PARTIAL, null,
6340 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase);
6341 }
6342 return mAggregatedPartialWakelockTimer;
6343 }
6344
Bookatz867c0d72017-03-07 18:23:42 -08006345 public DualTimer createBluetoothScanTimerLocked() {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006346 if (mBluetoothScanTimer == null) {
Bookatz867c0d72017-03-07 18:23:42 -08006347 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
6348 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
6349 mOnBatteryBackgroundTimeBase);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006350 }
6351 return mBluetoothScanTimer;
6352 }
6353
Bookatzb1f04f32017-05-19 13:57:32 -07006354 public DualTimer createBluetoothUnoptimizedScanTimerLocked() {
6355 if (mBluetoothUnoptimizedScanTimer == null) {
6356 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
6357 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
6358 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
6359 }
6360 return mBluetoothUnoptimizedScanTimer;
6361 }
6362
6363 public void noteBluetoothScanStartedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006364 createBluetoothScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006365 // TODO(statsd): Possibly use a worksource instead of a uid.
6366 StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED, getUid(), 1);
Bookatzb1f04f32017-05-19 13:57:32 -07006367 if (isUnoptimized) {
6368 createBluetoothUnoptimizedScanTimerLocked().startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006369 // TODO(statsd): Possibly use a worksource instead of a uid.
6370 StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, getUid(), 1);
Bookatzb1f04f32017-05-19 13:57:32 -07006371 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006372 }
6373
Bookatz94c5a312017-07-11 16:49:17 -07006374 public void noteBluetoothScanStoppedLocked(long elapsedRealtimeMs, boolean isUnoptimized) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006375 if (mBluetoothScanTimer != null) {
6376 mBluetoothScanTimer.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006377 if (!mBluetoothScanTimer.isRunningLocked()) { // only tell statsd if truly stopped
6378 // TODO(statsd): Possibly use a worksource instead of a uid.
6379 StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED, getUid(), 0);
6380 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006381 }
Bookatz94c5a312017-07-11 16:49:17 -07006382 if (isUnoptimized && mBluetoothUnoptimizedScanTimer != null) {
Bookatzb1f04f32017-05-19 13:57:32 -07006383 mBluetoothUnoptimizedScanTimer.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006384 if (!mBluetoothUnoptimizedScanTimer.isRunningLocked()) {
6385 // TODO(statsd): Possibly use a worksource instead of a uid.
6386 StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, getUid(), 0);
6387 }
Bookatzb1f04f32017-05-19 13:57:32 -07006388 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006389 }
6390
6391 public void noteResetBluetoothScanLocked(long elapsedRealtimeMs) {
6392 if (mBluetoothScanTimer != null) {
6393 mBluetoothScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006394 // TODO(statsd): Possibly use a worksource instead of a uid.
6395 StatsLog.write(StatsLog.BLE_SCAN_STATE_CHANGED, getUid(), 0);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006396 }
Bookatzb1f04f32017-05-19 13:57:32 -07006397 if (mBluetoothUnoptimizedScanTimer != null) {
6398 mBluetoothUnoptimizedScanTimer.stopAllRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07006399 // TODO(statsd): Possibly use a worksource instead of a uid.
6400 StatsLog.write(StatsLog.BLE_UNOPTIMIZED_SCAN_STATE_CHANGED, getUid(), 0);
Bookatzb1f04f32017-05-19 13:57:32 -07006401 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006402 }
6403
Bookatz956f36bf2017-04-28 09:48:17 -07006404 public Counter createBluetoothScanResultCounterLocked() {
6405 if (mBluetoothScanResultCounter == null) {
6406 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase);
6407 }
6408 return mBluetoothScanResultCounter;
6409 }
6410
Bookatzb1f04f32017-05-19 13:57:32 -07006411 public Counter createBluetoothScanResultBgCounterLocked() {
6412 if (mBluetoothScanResultBgCounter == null) {
6413 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase);
6414 }
6415 return mBluetoothScanResultBgCounter;
6416 }
6417
Bookatz4ebc0642017-05-11 12:21:19 -07006418 public void noteBluetoothScanResultsLocked(int numNewResults) {
6419 createBluetoothScanResultCounterLocked().addAtomic(numNewResults);
Bookatzb1f04f32017-05-19 13:57:32 -07006420 // Uses background timebase, so the count will only be incremented if uid in background.
6421 createBluetoothScanResultBgCounterLocked().addAtomic(numNewResults);
Bookatzc1a050a2017-10-10 15:49:28 -07006422 // TODO(statsd): Possibly use a worksource instead of a uid.
6423 // TODO(statsd): This could be in AppScanStats instead, if desired.
6424 StatsLog.write(StatsLog.BLE_SCAN_RESULT_RECEIVED, getUid(), numNewResults);
Bookatz956f36bf2017-04-28 09:48:17 -07006425 }
6426
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006427 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006428 public void noteActivityResumedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006429 // We always start, since we want multiple foreground PIDs to nest
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006430 createForegroundActivityTimerLocked().startRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006431 }
6432
6433 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006434 public void noteActivityPausedLocked(long elapsedRealtimeMs) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006435 if (mForegroundActivityTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006436 mForegroundActivityTimer.stopRunningLocked(elapsedRealtimeMs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006437 }
6438 }
6439
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07006440 public void noteForegroundServiceResumedLocked(long elapsedRealtimeMs) {
6441 createForegroundServiceTimerLocked().startRunningLocked(elapsedRealtimeMs);
6442 }
6443
6444 public void noteForegroundServicePausedLocked(long elapsedRealtimeMs) {
6445 if (mForegroundServiceTimer != null) {
6446 mForegroundServiceTimer.stopRunningLocked(elapsedRealtimeMs);
6447 }
6448 }
6449
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006450 public BatchTimer createVibratorOnTimerLocked() {
6451 if (mVibratorOnTimer == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006452 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON,
6453 mBsi.mOnBatteryTimeBase);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006454 }
6455 return mVibratorOnTimer;
6456 }
6457
6458 public void noteVibratorOnLocked(long durationMillis) {
Joe Onoratoabded112016-02-08 16:49:39 -08006459 createVibratorOnTimerLocked().addDuration(mBsi, durationMillis);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006460 }
6461
6462 public void noteVibratorOffLocked() {
6463 if (mVibratorOnTimer != null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006464 mVibratorOnTimer.abortLastDuration(mBsi);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006465 }
6466 }
6467
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006468 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006469 public long getWifiRunningTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006470 if (mWifiRunningTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006471 return 0;
6472 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006473 return mWifiRunningTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006474 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07006475
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006476 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006477 public long getFullWifiLockTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006478 if (mFullWifiLockTimer == null) {
6479 return 0;
6480 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006481 return mFullWifiLockTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07006482 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006483
6484 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006485 public long getWifiScanTime(long elapsedRealtimeUs, int which) {
Nick Pelly6ccaa542012-06-15 15:22:47 -07006486 if (mWifiScanTimer == null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006487 return 0;
6488 }
Bookatzaa4594a2017-03-24 12:39:56 -07006489 return mWifiScanTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
The Android Open Source Project10592532009-03-18 17:39:46 -07006490 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006491
6492 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07006493 public int getWifiScanCount(int which) {
6494 if (mWifiScanTimer == null) {
6495 return 0;
6496 }
Bookatzaa4594a2017-03-24 12:39:56 -07006497 return mWifiScanTimer.getCountLocked(which);
Bookatz867c0d72017-03-07 18:23:42 -08006498 }
6499
6500 @Override
Kweku Adams103351f2017-10-16 14:39:34 -07006501 public Timer getWifiScanTimer() {
6502 return mWifiScanTimer;
6503 }
6504
6505 @Override
Bookatz867c0d72017-03-07 18:23:42 -08006506 public int getWifiScanBackgroundCount(int which) {
Bookatzaa4594a2017-03-24 12:39:56 -07006507 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) {
Bookatz867c0d72017-03-07 18:23:42 -08006508 return 0;
6509 }
6510 return mWifiScanTimer.getSubTimer().getCountLocked(which);
6511 }
6512
6513 @Override
6514 public long getWifiScanActualTime(final long elapsedRealtimeUs) {
6515 if (mWifiScanTimer == null) {
6516 return 0;
6517 }
6518 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000;
Bookatzaa4594a2017-03-24 12:39:56 -07006519 return mWifiScanTimer.getTotalDurationMsLocked(elapsedRealtimeMs) * 1000;
Bookatz867c0d72017-03-07 18:23:42 -08006520 }
6521
6522 @Override
6523 public long getWifiScanBackgroundTime(final long elapsedRealtimeUs) {
Bookatzaa4594a2017-03-24 12:39:56 -07006524 if (mWifiScanTimer == null || mWifiScanTimer.getSubTimer() == null) {
Bookatz867c0d72017-03-07 18:23:42 -08006525 return 0;
6526 }
6527 final long elapsedRealtimeMs = (elapsedRealtimeUs + 500) / 1000;
6528 return mWifiScanTimer.getSubTimer().getTotalDurationMsLocked(elapsedRealtimeMs) * 1000;
Dianne Hackborn62793e42015-03-09 11:15:41 -07006529 }
6530
6531 @Override
Kweku Adams103351f2017-10-16 14:39:34 -07006532 public Timer getWifiScanBackgroundTimer() {
6533 if (mWifiScanTimer == null) {
6534 return null;
6535 }
6536 return mWifiScanTimer.getSubTimer();
6537 }
6538
6539 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006540 public long getWifiBatchedScanTime(int csphBin, long elapsedRealtimeUs, int which) {
Robert Greenwalta029ea12013-09-25 16:38:12 -07006541 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
6542 if (mWifiBatchedScanTimer[csphBin] == null) {
6543 return 0;
6544 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006545 return mWifiBatchedScanTimer[csphBin].getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006546 }
6547
6548 @Override
Dianne Hackborn62793e42015-03-09 11:15:41 -07006549 public int getWifiBatchedScanCount(int csphBin, int which) {
6550 if (csphBin < 0 || csphBin >= NUM_WIFI_BATCHED_SCAN_BINS) return 0;
6551 if (mWifiBatchedScanTimer[csphBin] == null) {
6552 return 0;
6553 }
6554 return mWifiBatchedScanTimer[csphBin].getCountLocked(which);
6555 }
6556
6557 @Override
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006558 public long getWifiMulticastTime(long elapsedRealtimeUs, int which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006559 if (mWifiMulticastTimer == null) {
6560 return 0;
6561 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006562 return mWifiMulticastTimer.getTotalTimeLocked(elapsedRealtimeUs, which);
Robert Greenwalt5347bd42009-05-13 15:10:16 -07006563 }
6564
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006565 @Override
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006566 public Timer getAudioTurnedOnTimer() {
6567 return mAudioTurnedOnTimer;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006568 }
6569
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006570 @Override
Ruben Brunk6d2c3632015-05-26 17:32:16 -07006571 public Timer getVideoTurnedOnTimer() {
6572 return mVideoTurnedOnTimer;
6573 }
6574
6575 @Override
6576 public Timer getFlashlightTurnedOnTimer() {
6577 return mFlashlightTurnedOnTimer;
6578 }
6579
6580 @Override
6581 public Timer getCameraTurnedOnTimer() {
6582 return mCameraTurnedOnTimer;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006583 }
6584
Dianne Hackborn617f8772009-03-31 15:04:46 -07006585 @Override
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006586 public Timer getForegroundActivityTimer() {
6587 return mForegroundActivityTimer;
6588 }
6589
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006590 @Override
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07006591 public Timer getForegroundServiceTimer() {
6592 return mForegroundServiceTimer;
6593 }
6594
6595 @Override
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006596 public Timer getBluetoothScanTimer() {
Bookatzaa4594a2017-03-24 12:39:56 -07006597 return mBluetoothScanTimer;
Bookatz867c0d72017-03-07 18:23:42 -08006598 }
6599
6600 @Override
6601 public Timer getBluetoothScanBackgroundTimer() {
6602 if (mBluetoothScanTimer == null) {
6603 return null;
6604 }
6605 return mBluetoothScanTimer.getSubTimer();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08006606 }
6607
Bookatz956f36bf2017-04-28 09:48:17 -07006608 @Override
Bookatzb1f04f32017-05-19 13:57:32 -07006609 public Timer getBluetoothUnoptimizedScanTimer() {
6610 return mBluetoothUnoptimizedScanTimer;
6611 }
6612
6613 @Override
6614 public Timer getBluetoothUnoptimizedScanBackgroundTimer() {
6615 if (mBluetoothUnoptimizedScanTimer == null) {
6616 return null;
6617 }
6618 return mBluetoothUnoptimizedScanTimer.getSubTimer();
6619 }
6620
6621 @Override
Bookatz956f36bf2017-04-28 09:48:17 -07006622 public Counter getBluetoothScanResultCounter() {
6623 return mBluetoothScanResultCounter;
6624 }
6625
Bookatzb1f04f32017-05-19 13:57:32 -07006626 @Override
6627 public Counter getBluetoothScanResultBgCounter() {
6628 return mBluetoothScanResultBgCounter;
6629 }
6630
Dianne Hackborn61659e52014-07-09 16:13:01 -07006631 void makeProcessState(int i, Parcel in) {
6632 if (i < 0 || i >= NUM_PROCESS_STATE) return;
6633
6634 if (in == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006635 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null,
6636 mBsi.mOnBatteryTimeBase);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006637 } else {
Joe Onoratoabded112016-02-08 16:49:39 -08006638 mProcessStateTimer[i] = new StopwatchTimer(mBsi.mClocks, this, PROCESS_STATE, null,
6639 mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006640 }
6641 }
6642
6643 @Override
6644 public long getProcessStateTime(int state, long elapsedRealtimeUs, int which) {
6645 if (state < 0 || state >= NUM_PROCESS_STATE) return 0;
6646 if (mProcessStateTimer[state] == null) {
6647 return 0;
6648 }
6649 return mProcessStateTimer[state].getTotalTimeLocked(elapsedRealtimeUs, which);
6650 }
6651
Jeff Sharkey3e013e82013-04-25 14:48:19 -07006652 @Override
Joe Onorato713fec82016-03-04 10:34:02 -08006653 public Timer getProcessStateTimer(int state) {
6654 if (state < 0 || state >= NUM_PROCESS_STATE) return null;
6655 return mProcessStateTimer[state];
6656 }
6657
6658 @Override
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006659 public Timer getVibratorOnTimer() {
6660 return mVibratorOnTimer;
6661 }
6662
6663 @Override
Dianne Hackborn617f8772009-03-31 15:04:46 -07006664 public void noteUserActivityLocked(int type) {
6665 if (mUserActivityCounters == null) {
6666 initUserActivityLocked();
6667 }
Jeff Browndf693de2012-07-27 12:03:38 -07006668 if (type >= 0 && type < NUM_USER_ACTIVITY_TYPES) {
6669 mUserActivityCounters[type].stepAtomic();
6670 } else {
6671 Slog.w(TAG, "Unknown user activity type " + type + " was specified.",
6672 new Throwable());
6673 }
Dianne Hackborn617f8772009-03-31 15:04:46 -07006674 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006675
Dianne Hackborn617f8772009-03-31 15:04:46 -07006676 @Override
6677 public boolean hasUserActivity() {
6678 return mUserActivityCounters != null;
6679 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006680
Dianne Hackborn617f8772009-03-31 15:04:46 -07006681 @Override
6682 public int getUserActivityCount(int type, int which) {
6683 if (mUserActivityCounters == null) {
6684 return 0;
6685 }
Evan Millarc64edde2009-04-18 12:26:32 -07006686 return mUserActivityCounters[type].getCountLocked(which);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006687 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006688
Robert Greenwalta029ea12013-09-25 16:38:12 -07006689 void makeWifiBatchedScanBin(int i, Parcel in) {
6690 if (i < 0 || i >= NUM_WIFI_BATCHED_SCAN_BINS) return;
6691
Joe Onoratoabded112016-02-08 16:49:39 -08006692 ArrayList<StopwatchTimer> collected = mBsi.mWifiBatchedScanTimers.get(i);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006693 if (collected == null) {
6694 collected = new ArrayList<StopwatchTimer>();
Joe Onoratoabded112016-02-08 16:49:39 -08006695 mBsi.mWifiBatchedScanTimers.put(i, collected);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006696 }
6697 if (in == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08006698 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN,
6699 collected, mBsi.mOnBatteryTimeBase);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006700 } else {
Joe Onoratoabded112016-02-08 16:49:39 -08006701 mWifiBatchedScanTimer[i] = new StopwatchTimer(mBsi.mClocks, this, WIFI_BATCHED_SCAN,
6702 collected, mBsi.mOnBatteryTimeBase, in);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006703 }
6704 }
6705
6706
Dianne Hackborn617f8772009-03-31 15:04:46 -07006707 void initUserActivityLocked() {
6708 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
6709 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08006710 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07006711 }
6712 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006713
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006714 void noteNetworkActivityLocked(int type, long deltaBytes, long deltaPackets) {
6715 if (mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006716 initNetworkActivityLocked();
6717 }
6718 if (type >= 0 && type < NUM_NETWORK_ACTIVITY_TYPES) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006719 mNetworkByteActivityCounters[type].addCountLocked(deltaBytes);
6720 mNetworkPacketActivityCounters[type].addCountLocked(deltaPackets);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006721 } else {
6722 Slog.w(TAG, "Unknown network activity type " + type + " was specified.",
6723 new Throwable());
6724 }
6725 }
6726
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006727 void noteMobileRadioActiveTimeLocked(long batteryUptime) {
6728 if (mNetworkByteActivityCounters == null) {
6729 initNetworkActivityLocked();
6730 }
6731 mMobileRadioActiveTime.addCountLocked(batteryUptime);
6732 mMobileRadioActiveCount.addCountLocked(1);
6733 }
6734
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006735 @Override
6736 public boolean hasNetworkActivity() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006737 return mNetworkByteActivityCounters != null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006738 }
6739
6740 @Override
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006741 public long getNetworkActivityBytes(int type, int which) {
6742 if (mNetworkByteActivityCounters != null && type >= 0
6743 && type < mNetworkByteActivityCounters.length) {
6744 return mNetworkByteActivityCounters[type].getCountLocked(which);
6745 } else {
6746 return 0;
6747 }
6748 }
6749
6750 @Override
6751 public long getNetworkActivityPackets(int type, int which) {
6752 if (mNetworkPacketActivityCounters != null && type >= 0
6753 && type < mNetworkPacketActivityCounters.length) {
6754 return mNetworkPacketActivityCounters[type].getCountLocked(which);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006755 } else {
6756 return 0;
6757 }
6758 }
6759
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006760 @Override
6761 public long getMobileRadioActiveTime(int which) {
6762 return mMobileRadioActiveTime != null
6763 ? mMobileRadioActiveTime.getCountLocked(which) : 0;
6764 }
6765
6766 @Override
6767 public int getMobileRadioActiveCount(int which) {
6768 return mMobileRadioActiveCount != null
6769 ? (int)mMobileRadioActiveCount.getCountLocked(which) : 0;
6770 }
6771
Adam Lesinskie08af192015-03-25 16:42:59 -07006772 @Override
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006773 public long getUserCpuTimeUs(int which) {
6774 return mUserCpuTime.getCountLocked(which);
6775 }
6776
6777 @Override
6778 public long getSystemCpuTimeUs(int which) {
6779 return mSystemCpuTime.getCountLocked(which);
6780 }
6781
6782 @Override
Adam Lesinski6832f392015-09-05 18:05:40 -07006783 public long getTimeAtCpuSpeed(int cluster, int step, int which) {
Sudheer Shankaaf857412017-07-21 00:14:24 -07006784 if (mCpuClusterSpeedTimesUs != null) {
6785 if (cluster >= 0 && cluster < mCpuClusterSpeedTimesUs.length) {
6786 final LongSamplingCounter[] cpuSpeedTimesUs = mCpuClusterSpeedTimesUs[cluster];
6787 if (cpuSpeedTimesUs != null) {
6788 if (step >= 0 && step < cpuSpeedTimesUs.length) {
6789 final LongSamplingCounter c = cpuSpeedTimesUs[step];
Adam Lesinski6832f392015-09-05 18:05:40 -07006790 if (c != null) {
6791 return c.getCountLocked(which);
6792 }
6793 }
6794 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006795 }
6796 }
6797 return 0;
6798 }
6799
Adam Lesinski5f056f62016-07-14 16:56:08 -07006800 public void noteMobileRadioApWakeupLocked() {
6801 if (mMobileRadioApWakeupCount == null) {
6802 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6803 }
6804 mMobileRadioApWakeupCount.addCountLocked(1);
6805 }
6806
6807 @Override
6808 public long getMobileRadioApWakeupCount(int which) {
6809 if (mMobileRadioApWakeupCount != null) {
6810 return mMobileRadioApWakeupCount.getCountLocked(which);
6811 }
6812 return 0;
6813 }
6814
6815 public void noteWifiRadioApWakeupLocked() {
6816 if (mWifiRadioApWakeupCount == null) {
6817 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6818 }
6819 mWifiRadioApWakeupCount.addCountLocked(1);
6820 }
6821
6822 @Override
6823 public long getWifiRadioApWakeupCount(int which) {
6824 if (mWifiRadioApWakeupCount != null) {
6825 return mWifiRadioApWakeupCount.getCountLocked(which);
6826 }
6827 return 0;
6828 }
6829
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006830 void initNetworkActivityLocked() {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006831 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
6832 mNetworkPacketActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006833 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08006834 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6835 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006836 }
Joe Onoratoabded112016-02-08 16:49:39 -08006837 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
6838 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08006839 }
Amith Yamasani244fa5c2009-05-22 14:36:07 -07006840
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006841 /**
6842 * Clear all stats for this uid. Returns true if the uid is completely
6843 * inactive so can be dropped.
6844 */
Adam Lesinski5f212c82017-03-13 12:25:13 -07006845 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
Bookatz993a0be2017-07-21 09:03:23 -07006846 public boolean reset(long uptime, long realtime) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006847 boolean active = false;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006848
Bookatz993a0be2017-07-21 09:03:23 -07006849 mOnBatteryBackgroundTimeBase.init(uptime, realtime);
6850 mOnBatteryScreenOffBackgroundTimeBase.init(uptime, realtime);
6851
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006852 if (mWifiRunningTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006853 active |= !mWifiRunningTimer.reset(false);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07006854 active |= mWifiRunning;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006855 }
6856 if (mFullWifiLockTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006857 active |= !mFullWifiLockTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006858 active |= mFullWifiLockOut;
6859 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07006860 if (mWifiScanTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006861 active |= !mWifiScanTimer.reset(false);
Nick Pelly6ccaa542012-06-15 15:22:47 -07006862 active |= mWifiScanStarted;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006863 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07006864 if (mWifiBatchedScanTimer != null) {
6865 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
6866 if (mWifiBatchedScanTimer[i] != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006867 active |= !mWifiBatchedScanTimer[i].reset(false);
Robert Greenwalta029ea12013-09-25 16:38:12 -07006868 }
6869 }
6870 active |= (mWifiBatchedScanBinStarted != NO_BATCHED_SCAN_STARTED);
6871 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006872 if (mWifiMulticastTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006873 active |= !mWifiMulticastTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006874 active |= mWifiMulticastEnabled;
6875 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07006876
6877 active |= !resetTimerIfNotNull(mAudioTurnedOnTimer, false);
6878 active |= !resetTimerIfNotNull(mVideoTurnedOnTimer, false);
6879 active |= !resetTimerIfNotNull(mFlashlightTurnedOnTimer, false);
6880 active |= !resetTimerIfNotNull(mCameraTurnedOnTimer, false);
6881 active |= !resetTimerIfNotNull(mForegroundActivityTimer, false);
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07006882 active |= !resetTimerIfNotNull(mForegroundServiceTimer, false);
Bookatzc8c44962017-05-11 12:12:54 -07006883 active |= !resetTimerIfNotNull(mAggregatedPartialWakelockTimer, false);
Adam Lesinski5f056f62016-07-14 16:56:08 -07006884 active |= !resetTimerIfNotNull(mBluetoothScanTimer, false);
Bookatzb1f04f32017-05-19 13:57:32 -07006885 active |= !resetTimerIfNotNull(mBluetoothUnoptimizedScanTimer, false);
Bookatz956f36bf2017-04-28 09:48:17 -07006886 if (mBluetoothScanResultCounter != null) {
6887 mBluetoothScanResultCounter.reset(false);
6888 }
Bookatzb1f04f32017-05-19 13:57:32 -07006889 if (mBluetoothScanResultBgCounter != null) {
6890 mBluetoothScanResultBgCounter.reset(false);
6891 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07006892
Dianne Hackborn61659e52014-07-09 16:13:01 -07006893 if (mProcessStateTimer != null) {
6894 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
6895 if (mProcessStateTimer[i] != null) {
6896 active |= !mProcessStateTimer[i].reset(false);
6897 }
6898 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08006899 active |= (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006900 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006901 if (mVibratorOnTimer != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08006902 if (mVibratorOnTimer.reset(false)) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -08006903 mVibratorOnTimer.detach();
6904 mVibratorOnTimer = null;
6905 } else {
6906 active = true;
6907 }
6908 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07006909
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006910 if (mUserActivityCounters != null) {
6911 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
6912 mUserActivityCounters[i].reset(false);
6913 }
6914 }
6915
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006916 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006917 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08006918 mNetworkByteActivityCounters[i].reset(false);
6919 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006920 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08006921 mMobileRadioActiveTime.reset(false);
6922 mMobileRadioActiveCount.reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07006923 }
6924
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006925 if (mWifiControllerActivity != null) {
6926 mWifiControllerActivity.reset(false);
6927 }
Adam Lesinskie08af192015-03-25 16:42:59 -07006928
Adam Lesinski1a2b39e2016-04-29 17:56:58 -07006929 if (mBluetoothControllerActivity != null) {
6930 mBluetoothControllerActivity.reset(false);
Adam Lesinski21f76aa2016-01-25 12:27:06 -08006931 }
6932
Adam Lesinski1a2b39e2016-04-29 17:56:58 -07006933 if (mModemControllerActivity != null) {
6934 mModemControllerActivity.reset(false);
Adam Lesinskie08af192015-03-25 16:42:59 -07006935 }
6936
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006937 mUserCpuTime.reset(false);
6938 mSystemCpuTime.reset(false);
Adam Lesinski6832f392015-09-05 18:05:40 -07006939
Sudheer Shankaaf857412017-07-21 00:14:24 -07006940 if (mCpuClusterSpeedTimesUs != null) {
6941 for (LongSamplingCounter[] speeds : mCpuClusterSpeedTimesUs) {
Adam Lesinski6832f392015-09-05 18:05:40 -07006942 if (speeds != null) {
6943 for (LongSamplingCounter speed : speeds) {
6944 if (speed != null) {
6945 speed.reset(false);
6946 }
6947 }
6948 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07006949 }
6950 }
6951
Sudheer Shanka9b735c52017-05-09 18:26:18 -07006952 if (mCpuFreqTimeMs != null) {
6953 mCpuFreqTimeMs.reset(false);
6954 }
6955 if (mScreenOffCpuFreqTimeMs != null) {
6956 mScreenOffCpuFreqTimeMs.reset(false);
6957 }
6958
Adam Lesinski5f056f62016-07-14 16:56:08 -07006959 resetLongCounterIfNotNull(mMobileRadioApWakeupCount, false);
6960 resetLongCounterIfNotNull(mWifiRadioApWakeupCount, false);
6961
Dianne Hackbornd953c532014-08-16 18:17:38 -07006962 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
6963 for (int iw=wakeStats.size()-1; iw>=0; iw--) {
6964 Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006965 if (wl.reset()) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006966 wakeStats.removeAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -07006967 } else {
6968 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07006969 }
6970 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006971 mWakelockStats.cleanup();
Bookatz2bffb5b2017-04-13 11:59:33 -07006972 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -07006973 for (int is=syncStats.size()-1; is>=0; is--) {
Bookatz2bffb5b2017-04-13 11:59:33 -07006974 DualTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006975 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006976 syncStats.removeAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006977 timer.detach();
6978 } else {
6979 active = true;
6980 }
6981 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006982 mSyncStats.cleanup();
Bookatzaa4594a2017-03-24 12:39:56 -07006983 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -07006984 for (int ij=jobStats.size()-1; ij>=0; ij--) {
Bookatzaa4594a2017-03-24 12:39:56 -07006985 DualTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006986 if (timer.reset(false)) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07006987 jobStats.removeAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07006988 timer.detach();
6989 } else {
6990 active = true;
6991 }
6992 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07006993 mJobStats.cleanup();
Dianne Hackborn94326cb2017-06-28 16:17:20 -07006994 mJobCompletions.clear();
Dianne Hackborn61659e52014-07-09 16:13:01 -07006995 for (int ise=mSensorStats.size()-1; ise>=0; ise--) {
6996 Sensor s = mSensorStats.valueAt(ise);
6997 if (s.reset()) {
6998 mSensorStats.removeAt(ise);
6999 } else {
7000 active = true;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007001 }
7002 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07007003 for (int ip=mProcessStats.size()-1; ip>=0; ip--) {
7004 Proc proc = mProcessStats.valueAt(ip);
Dianne Hackborna8d10942015-11-19 17:55:19 -08007005 proc.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007006 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08007007 mProcessStats.clear();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007008 if (mPids.size() > 0) {
Dianne Hackborne5167ca2014-03-08 14:39:10 -08007009 for (int i=mPids.size()-1; i>=0; i--) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007010 Pid pid = mPids.valueAt(i);
Dianne Hackborne5167ca2014-03-08 14:39:10 -08007011 if (pid.mWakeNesting > 0) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007012 active = true;
Dianne Hackborne5167ca2014-03-08 14:39:10 -08007013 } else {
7014 mPids.removeAt(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07007015 }
7016 }
7017 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007018 if (mPackageStats.size() > 0) {
7019 Iterator<Map.Entry<String, Pkg>> it = mPackageStats.entrySet().iterator();
7020 while (it.hasNext()) {
7021 Map.Entry<String, Pkg> pkgEntry = it.next();
7022 Pkg p = pkgEntry.getValue();
7023 p.detach();
7024 if (p.mServiceStats.size() > 0) {
7025 Iterator<Map.Entry<String, Pkg.Serv>> it2
7026 = p.mServiceStats.entrySet().iterator();
7027 while (it2.hasNext()) {
7028 Map.Entry<String, Pkg.Serv> servEntry = it2.next();
7029 servEntry.getValue().detach();
7030 }
7031 }
7032 }
7033 mPackageStats.clear();
7034 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007035
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08007036 mLastStepUserTime = mLastStepSystemTime = 0;
7037 mCurStepUserTime = mCurStepSystemTime = 0;
7038
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007039 if (!active) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007040 if (mWifiRunningTimer != null) {
7041 mWifiRunningTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007042 }
7043 if (mFullWifiLockTimer != null) {
7044 mFullWifiLockTimer.detach();
7045 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07007046 if (mWifiScanTimer != null) {
7047 mWifiScanTimer.detach();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007048 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07007049 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7050 if (mWifiBatchedScanTimer[i] != null) {
7051 mWifiBatchedScanTimer[i].detach();
7052 }
7053 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007054 if (mWifiMulticastTimer != null) {
7055 mWifiMulticastTimer.detach();
7056 }
7057 if (mAudioTurnedOnTimer != null) {
7058 mAudioTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007059 mAudioTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007060 }
7061 if (mVideoTurnedOnTimer != null) {
7062 mVideoTurnedOnTimer.detach();
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007063 mVideoTurnedOnTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007064 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07007065 if (mFlashlightTurnedOnTimer != null) {
7066 mFlashlightTurnedOnTimer.detach();
7067 mFlashlightTurnedOnTimer = null;
7068 }
7069 if (mCameraTurnedOnTimer != null) {
7070 mCameraTurnedOnTimer.detach();
7071 mCameraTurnedOnTimer = null;
7072 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007073 if (mForegroundActivityTimer != null) {
7074 mForegroundActivityTimer.detach();
7075 mForegroundActivityTimer = null;
7076 }
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07007077 if (mForegroundServiceTimer != null) {
7078 mForegroundServiceTimer.detach();
7079 mForegroundServiceTimer = null;
7080 }
Bookatzc8c44962017-05-11 12:12:54 -07007081 if (mAggregatedPartialWakelockTimer != null) {
7082 mAggregatedPartialWakelockTimer.detach();
7083 mAggregatedPartialWakelockTimer = null;
7084 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08007085 if (mBluetoothScanTimer != null) {
7086 mBluetoothScanTimer.detach();
7087 mBluetoothScanTimer = null;
7088 }
Bookatzb1f04f32017-05-19 13:57:32 -07007089 if (mBluetoothUnoptimizedScanTimer != null) {
7090 mBluetoothUnoptimizedScanTimer.detach();
7091 mBluetoothUnoptimizedScanTimer = null;
7092 }
Bookatz956f36bf2017-04-28 09:48:17 -07007093 if (mBluetoothScanResultCounter != null) {
7094 mBluetoothScanResultCounter.detach();
7095 mBluetoothScanResultCounter = null;
7096 }
Bookatzb1f04f32017-05-19 13:57:32 -07007097 if (mBluetoothScanResultBgCounter != null) {
7098 mBluetoothScanResultBgCounter.detach();
7099 mBluetoothScanResultBgCounter = null;
7100 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007101 if (mUserActivityCounters != null) {
7102 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
7103 mUserActivityCounters[i].detach();
7104 }
7105 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007106 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007107 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007108 mNetworkByteActivityCounters[i].detach();
7109 mNetworkPacketActivityCounters[i].detach();
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007110 }
7111 }
Adam Lesinskie08af192015-03-25 16:42:59 -07007112
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007113 if (mWifiControllerActivity != null) {
7114 mWifiControllerActivity.detach();
Adam Lesinskie08af192015-03-25 16:42:59 -07007115 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007116
7117 if (mBluetoothControllerActivity != null) {
7118 mBluetoothControllerActivity.detach();
7119 }
7120
7121 if (mModemControllerActivity != null) {
7122 mModemControllerActivity.detach();
7123 }
7124
Dianne Hackborne5167ca2014-03-08 14:39:10 -08007125 mPids.clear();
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007126
7127 mUserCpuTime.detach();
7128 mSystemCpuTime.detach();
Adam Lesinski6832f392015-09-05 18:05:40 -07007129
Sudheer Shankaaf857412017-07-21 00:14:24 -07007130 if (mCpuClusterSpeedTimesUs != null) {
7131 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) {
Adam Lesinski6832f392015-09-05 18:05:40 -07007132 if (cpuSpeeds != null) {
7133 for (LongSamplingCounter c : cpuSpeeds) {
7134 if (c != null) {
7135 c.detach();
7136 }
7137 }
7138 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007139 }
7140 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07007141
Sudheer Shanka9b735c52017-05-09 18:26:18 -07007142 if (mCpuFreqTimeMs != null) {
7143 mCpuFreqTimeMs.detach();
7144 }
7145 if (mScreenOffCpuFreqTimeMs != null) {
7146 mScreenOffCpuFreqTimeMs.detach();
7147 }
7148
Adam Lesinski5f056f62016-07-14 16:56:08 -07007149 detachLongCounterIfNotNull(mMobileRadioApWakeupCount);
7150 detachLongCounterIfNotNull(mWifiRadioApWakeupCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007151 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007152
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007153 return !active;
7154 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007155
Dianne Hackborn94326cb2017-06-28 16:17:20 -07007156 void writeJobCompletionsToParcelLocked(Parcel out) {
7157 int NJC = mJobCompletions.size();
7158 out.writeInt(NJC);
7159 for (int ijc=0; ijc<NJC; ijc++) {
7160 out.writeString(mJobCompletions.keyAt(ijc));
7161 SparseIntArray types = mJobCompletions.valueAt(ijc);
7162 int NT = types.size();
7163 out.writeInt(NT);
7164 for (int it=0; it<NT; it++) {
7165 out.writeInt(types.keyAt(it));
7166 out.writeInt(types.valueAt(it));
7167 }
7168 }
7169 }
7170
Bookatz867c0d72017-03-07 18:23:42 -08007171 void writeToParcelLocked(Parcel out, long uptimeUs, long elapsedRealtimeUs) {
7172 mOnBatteryBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
Bookatzc8c44962017-05-11 12:12:54 -07007173 mOnBatteryScreenOffBackgroundTimeBase.writeToParcel(out, uptimeUs, elapsedRealtimeUs);
Bookatz867c0d72017-03-07 18:23:42 -08007174
Dianne Hackbornd953c532014-08-16 18:17:38 -07007175 final ArrayMap<String, Wakelock> wakeStats = mWakelockStats.getMap();
7176 int NW = wakeStats.size();
Dianne Hackborn61659e52014-07-09 16:13:01 -07007177 out.writeInt(NW);
7178 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07007179 out.writeString(wakeStats.keyAt(iw));
7180 Uid.Wakelock wakelock = wakeStats.valueAt(iw);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007181 wakelock.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007182 }
7183
Bookatz2bffb5b2017-04-13 11:59:33 -07007184 final ArrayMap<String, DualTimer> syncStats = mSyncStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -07007185 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007186 out.writeInt(NS);
7187 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07007188 out.writeString(syncStats.keyAt(is));
Bookatz2bffb5b2017-04-13 11:59:33 -07007189 DualTimer timer = syncStats.valueAt(is);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007190 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
7191 }
7192
Bookatzaa4594a2017-03-24 12:39:56 -07007193 final ArrayMap<String, DualTimer> jobStats = mJobStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -07007194 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007195 out.writeInt(NJ);
7196 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07007197 out.writeString(jobStats.keyAt(ij));
Bookatzaa4594a2017-03-24 12:39:56 -07007198 DualTimer timer = jobStats.valueAt(ij);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007199 Timer.writeTimerToParcel(out, timer, elapsedRealtimeUs);
7200 }
7201
Dianne Hackborn94326cb2017-06-28 16:17:20 -07007202 writeJobCompletionsToParcelLocked(out);
7203
Dianne Hackborn61659e52014-07-09 16:13:01 -07007204 int NSE = mSensorStats.size();
7205 out.writeInt(NSE);
7206 for (int ise=0; ise<NSE; ise++) {
7207 out.writeInt(mSensorStats.keyAt(ise));
7208 Uid.Sensor sensor = mSensorStats.valueAt(ise);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007209 sensor.writeToParcelLocked(out, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007210 }
7211
Dianne Hackborn61659e52014-07-09 16:13:01 -07007212 int NP = mProcessStats.size();
7213 out.writeInt(NP);
7214 for (int ip=0; ip<NP; ip++) {
7215 out.writeString(mProcessStats.keyAt(ip));
7216 Uid.Proc proc = mProcessStats.valueAt(ip);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007217 proc.writeToParcelLocked(out);
7218 }
7219
7220 out.writeInt(mPackageStats.size());
7221 for (Map.Entry<String, Uid.Pkg> pkgEntry : mPackageStats.entrySet()) {
7222 out.writeString(pkgEntry.getKey());
7223 Uid.Pkg pkg = pkgEntry.getValue();
7224 pkg.writeToParcelLocked(out);
7225 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007226
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007227 if (mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007228 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007229 mWifiRunningTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007230 } else {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007231 out.writeInt(0);
7232 }
7233 if (mFullWifiLockTimer != null) {
7234 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007235 mFullWifiLockTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007236 } else {
7237 out.writeInt(0);
7238 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07007239 if (mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007240 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007241 mWifiScanTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007242 } else {
7243 out.writeInt(0);
7244 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07007245 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7246 if (mWifiBatchedScanTimer[i] != null) {
7247 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007248 mWifiBatchedScanTimer[i].writeToParcel(out, elapsedRealtimeUs);
Robert Greenwalta029ea12013-09-25 16:38:12 -07007249 } else {
7250 out.writeInt(0);
7251 }
7252 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007253 if (mWifiMulticastTimer != null) {
7254 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007255 mWifiMulticastTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007256 } else {
7257 out.writeInt(0);
7258 }
Adam Lesinskie08af192015-03-25 16:42:59 -07007259
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007260 if (mAudioTurnedOnTimer != null) {
7261 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007262 mAudioTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007263 } else {
7264 out.writeInt(0);
7265 }
7266 if (mVideoTurnedOnTimer != null) {
7267 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007268 mVideoTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007269 } else {
7270 out.writeInt(0);
7271 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -07007272 if (mFlashlightTurnedOnTimer != null) {
7273 out.writeInt(1);
7274 mFlashlightTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
7275 } else {
7276 out.writeInt(0);
7277 }
7278 if (mCameraTurnedOnTimer != null) {
7279 out.writeInt(1);
7280 mCameraTurnedOnTimer.writeToParcel(out, elapsedRealtimeUs);
7281 } else {
7282 out.writeInt(0);
7283 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007284 if (mForegroundActivityTimer != null) {
7285 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007286 mForegroundActivityTimer.writeToParcel(out, elapsedRealtimeUs);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007287 } else {
7288 out.writeInt(0);
7289 }
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07007290 if (mForegroundServiceTimer != null) {
7291 out.writeInt(1);
7292 mForegroundServiceTimer.writeToParcel(out, elapsedRealtimeUs);
7293 } else {
7294 out.writeInt(0);
7295 }
Bookatzc8c44962017-05-11 12:12:54 -07007296 if (mAggregatedPartialWakelockTimer != null) {
7297 out.writeInt(1);
7298 mAggregatedPartialWakelockTimer.writeToParcel(out, elapsedRealtimeUs);
7299 } else {
7300 out.writeInt(0);
7301 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08007302 if (mBluetoothScanTimer != null) {
7303 out.writeInt(1);
7304 mBluetoothScanTimer.writeToParcel(out, elapsedRealtimeUs);
7305 } else {
7306 out.writeInt(0);
7307 }
Bookatzb1f04f32017-05-19 13:57:32 -07007308 if (mBluetoothUnoptimizedScanTimer != null) {
7309 out.writeInt(1);
7310 mBluetoothUnoptimizedScanTimer.writeToParcel(out, elapsedRealtimeUs);
7311 } else {
7312 out.writeInt(0);
7313 }
Bookatz956f36bf2017-04-28 09:48:17 -07007314 if (mBluetoothScanResultCounter != null) {
7315 out.writeInt(1);
7316 mBluetoothScanResultCounter.writeToParcel(out);
7317 } else {
7318 out.writeInt(0);
7319 }
Bookatzb1f04f32017-05-19 13:57:32 -07007320 if (mBluetoothScanResultBgCounter != null) {
7321 out.writeInt(1);
7322 mBluetoothScanResultBgCounter.writeToParcel(out);
7323 } else {
7324 out.writeInt(0);
7325 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07007326 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
7327 if (mProcessStateTimer[i] != null) {
7328 out.writeInt(1);
7329 mProcessStateTimer[i].writeToParcel(out, elapsedRealtimeUs);
7330 } else {
7331 out.writeInt(0);
7332 }
7333 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007334 if (mVibratorOnTimer != null) {
7335 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007336 mVibratorOnTimer.writeToParcel(out, elapsedRealtimeUs);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007337 } else {
7338 out.writeInt(0);
7339 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007340 if (mUserActivityCounters != null) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07007341 out.writeInt(1);
7342 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
7343 mUserActivityCounters[i].writeToParcel(out);
7344 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007345 } else {
7346 out.writeInt(0);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007347 }
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007348 if (mNetworkByteActivityCounters != null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007349 out.writeInt(1);
7350 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007351 mNetworkByteActivityCounters[i].writeToParcel(out);
7352 mNetworkPacketActivityCounters[i].writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007353 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -08007354 mMobileRadioActiveTime.writeToParcel(out);
7355 mMobileRadioActiveCount.writeToParcel(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007356 } else {
7357 out.writeInt(0);
7358 }
Adam Lesinskie08af192015-03-25 16:42:59 -07007359
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007360 if (mWifiControllerActivity != null) {
7361 out.writeInt(1);
7362 mWifiControllerActivity.writeToParcel(out, 0);
7363 } else {
7364 out.writeInt(0);
Adam Lesinskie08af192015-03-25 16:42:59 -07007365 }
7366
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007367 if (mBluetoothControllerActivity != null) {
7368 out.writeInt(1);
7369 mBluetoothControllerActivity.writeToParcel(out, 0);
7370 } else {
7371 out.writeInt(0);
7372 }
7373
7374 if (mModemControllerActivity != null) {
7375 out.writeInt(1);
7376 mModemControllerActivity.writeToParcel(out, 0);
7377 } else {
7378 out.writeInt(0);
Adam Lesinskie08af192015-03-25 16:42:59 -07007379 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007380
7381 mUserCpuTime.writeToParcel(out);
7382 mSystemCpuTime.writeToParcel(out);
7383
Sudheer Shankaaf857412017-07-21 00:14:24 -07007384 if (mCpuClusterSpeedTimesUs != null) {
Adam Lesinski6832f392015-09-05 18:05:40 -07007385 out.writeInt(1);
Sudheer Shankaaf857412017-07-21 00:14:24 -07007386 out.writeInt(mCpuClusterSpeedTimesUs.length);
7387 for (LongSamplingCounter[] cpuSpeeds : mCpuClusterSpeedTimesUs) {
Adam Lesinski6832f392015-09-05 18:05:40 -07007388 if (cpuSpeeds != null) {
7389 out.writeInt(1);
7390 out.writeInt(cpuSpeeds.length);
7391 for (LongSamplingCounter c : cpuSpeeds) {
7392 if (c != null) {
7393 out.writeInt(1);
7394 c.writeToParcel(out);
7395 } else {
7396 out.writeInt(0);
7397 }
7398 }
7399 } else {
7400 out.writeInt(0);
7401 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007402 }
Adam Lesinski6832f392015-09-05 18:05:40 -07007403 } else {
7404 out.writeInt(0);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007405 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07007406
Sudheer Shanka59f5c002017-05-15 10:57:15 -07007407 LongSamplingCounterArray.writeToParcel(out, mCpuFreqTimeMs);
7408 LongSamplingCounterArray.writeToParcel(out, mScreenOffCpuFreqTimeMs);
Sudheer Shanka9b735c52017-05-09 18:26:18 -07007409
Adam Lesinski5f056f62016-07-14 16:56:08 -07007410 if (mMobileRadioApWakeupCount != null) {
7411 out.writeInt(1);
7412 mMobileRadioApWakeupCount.writeToParcel(out);
7413 } else {
7414 out.writeInt(0);
7415 }
7416
7417 if (mWifiRadioApWakeupCount != null) {
7418 out.writeInt(1);
7419 mWifiRadioApWakeupCount.writeToParcel(out);
7420 } else {
7421 out.writeInt(0);
7422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007423 }
7424
Dianne Hackborn94326cb2017-06-28 16:17:20 -07007425 void readJobCompletionsFromParcelLocked(Parcel in) {
7426 int numJobCompletions = in.readInt();
7427 mJobCompletions.clear();
7428 for (int j = 0; j < numJobCompletions; j++) {
7429 String jobName = in.readString();
7430 int numTypes = in.readInt();
7431 if (numTypes > 0) {
7432 SparseIntArray types = new SparseIntArray();
7433 for (int k = 0; k < numTypes; k++) {
7434 int type = in.readInt();
7435 int count = in.readInt();
7436 types.put(type, count);
7437 }
7438 mJobCompletions.put(jobName, types);
7439 }
7440 }
7441 }
7442
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007443 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase, Parcel in) {
Bookatz867c0d72017-03-07 18:23:42 -08007444 mOnBatteryBackgroundTimeBase.readFromParcel(in);
Bookatzc8c44962017-05-11 12:12:54 -07007445 mOnBatteryScreenOffBackgroundTimeBase.readFromParcel(in);
Bookatz867c0d72017-03-07 18:23:42 -08007446
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007447 int numWakelocks = in.readInt();
7448 mWakelockStats.clear();
7449 for (int j = 0; j < numWakelocks; j++) {
7450 String wakelockName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -08007451 Uid.Wakelock wakelock = new Wakelock(mBsi, this);
Bookatz5b5ec322017-05-26 09:40:38 -07007452 wakelock.readFromParcelLocked(
7453 timeBase, screenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase, in);
Dianne Hackbornd953c532014-08-16 18:17:38 -07007454 mWakelockStats.add(wakelockName, wakelock);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007455 }
7456
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007457 int numSyncs = in.readInt();
7458 mSyncStats.clear();
7459 for (int j = 0; j < numSyncs; j++) {
7460 String syncName = in.readString();
7461 if (in.readInt() != 0) {
Bookatz2bffb5b2017-04-13 11:59:33 -07007462 mSyncStats.add(syncName, new DualTimer(mBsi.mClocks, Uid.this, SYNC, null,
7463 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in));
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007464 }
7465 }
7466
7467 int numJobs = in.readInt();
7468 mJobStats.clear();
7469 for (int j = 0; j < numJobs; j++) {
7470 String jobName = in.readString();
7471 if (in.readInt() != 0) {
Bookatzaa4594a2017-03-24 12:39:56 -07007472 mJobStats.add(jobName, new DualTimer(mBsi.mClocks, Uid.this, JOB, null,
7473 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in));
Dianne Hackbornfdb19562014-07-11 16:03:36 -07007474 }
7475 }
7476
Dianne Hackborn94326cb2017-06-28 16:17:20 -07007477 readJobCompletionsFromParcelLocked(in);
7478
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007479 int numSensors = in.readInt();
7480 mSensorStats.clear();
7481 for (int k = 0; k < numSensors; k++) {
7482 int sensorNumber = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -08007483 Uid.Sensor sensor = new Sensor(mBsi, this, sensorNumber);
Bookatz867c0d72017-03-07 18:23:42 -08007484 sensor.readFromParcelLocked(mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase,
7485 in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007486 mSensorStats.put(sensorNumber, sensor);
7487 }
7488
7489 int numProcs = in.readInt();
7490 mProcessStats.clear();
7491 for (int k = 0; k < numProcs; k++) {
7492 String processName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -08007493 Uid.Proc proc = new Proc(mBsi, processName);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007494 proc.readFromParcelLocked(in);
7495 mProcessStats.put(processName, proc);
7496 }
7497
7498 int numPkgs = in.readInt();
7499 mPackageStats.clear();
7500 for (int l = 0; l < numPkgs; l++) {
7501 String packageName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -08007502 Uid.Pkg pkg = new Pkg(mBsi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007503 pkg.readFromParcelLocked(in);
7504 mPackageStats.put(packageName, pkg);
7505 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007506
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007507 mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007508 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007509 mWifiRunningTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_RUNNING,
7510 mBsi.mWifiRunningTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007511 } else {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -07007512 mWifiRunningTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007513 }
7514 mFullWifiLockOut = false;
7515 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007516 mFullWifiLockTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, FULL_WIFI_LOCK,
7517 mBsi.mFullWifiLockTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007518 } else {
7519 mFullWifiLockTimer = null;
7520 }
Nick Pelly6ccaa542012-06-15 15:22:47 -07007521 mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007522 if (in.readInt() != 0) {
Bookatz867c0d72017-03-07 18:23:42 -08007523 mWifiScanTimer = new DualTimer(mBsi.mClocks, Uid.this, WIFI_SCAN,
7524 mBsi.mWifiScanTimers, mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase,
7525 in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007526 } else {
Nick Pelly6ccaa542012-06-15 15:22:47 -07007527 mWifiScanTimer = null;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007528 }
Robert Greenwalta029ea12013-09-25 16:38:12 -07007529 mWifiBatchedScanBinStarted = NO_BATCHED_SCAN_STARTED;
7530 for (int i = 0; i < NUM_WIFI_BATCHED_SCAN_BINS; i++) {
7531 if (in.readInt() != 0) {
7532 makeWifiBatchedScanBin(i, in);
7533 } else {
7534 mWifiBatchedScanTimer[i] = null;
7535 }
7536 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007537 mWifiMulticastEnabled = false;
7538 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007539 mWifiMulticastTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, WIFI_MULTICAST_ENABLED,
7540 mBsi.mWifiMulticastTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007541 } else {
7542 mWifiMulticastTimer = null;
7543 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007544 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007545 mAudioTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, AUDIO_TURNED_ON,
7546 mBsi.mAudioTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007547 } else {
7548 mAudioTurnedOnTimer = null;
7549 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007550 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007551 mVideoTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, VIDEO_TURNED_ON,
7552 mBsi.mVideoTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007553 } else {
7554 mVideoTurnedOnTimer = null;
7555 }
7556 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007557 mFlashlightTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7558 FLASHLIGHT_TURNED_ON, mBsi.mFlashlightTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07007559 } else {
7560 mFlashlightTurnedOnTimer = null;
7561 }
7562 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007563 mCameraTurnedOnTimer = new StopwatchTimer(mBsi.mClocks, Uid.this, CAMERA_TURNED_ON,
7564 mBsi.mCameraTurnedOnTimers, mBsi.mOnBatteryTimeBase, in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07007565 } else {
7566 mCameraTurnedOnTimer = null;
7567 }
7568 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007569 mForegroundActivityTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7570 FOREGROUND_ACTIVITY, null, mBsi.mOnBatteryTimeBase, in);
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007571 } else {
7572 mForegroundActivityTimer = null;
7573 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -08007574 if (in.readInt() != 0) {
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07007575 mForegroundServiceTimer = new StopwatchTimer(mBsi.mClocks, Uid.this,
7576 FOREGROUND_SERVICE, null, mBsi.mOnBatteryTimeBase, in);
7577 } else {
7578 mForegroundServiceTimer = null;
7579 }
7580 if (in.readInt() != 0) {
Bookatzc8c44962017-05-11 12:12:54 -07007581 mAggregatedPartialWakelockTimer = new DualTimer(mBsi.mClocks, this,
7582 AGGREGATED_WAKE_TYPE_PARTIAL, null,
7583 mBsi.mOnBatteryScreenOffTimeBase, mOnBatteryScreenOffBackgroundTimeBase,
7584 in);
7585 } else {
7586 mAggregatedPartialWakelockTimer = null;
7587 }
7588 if (in.readInt() != 0) {
Bookatz867c0d72017-03-07 18:23:42 -08007589 mBluetoothScanTimer = new DualTimer(mBsi.mClocks, Uid.this, BLUETOOTH_SCAN_ON,
7590 mBsi.mBluetoothScanOnTimers, mBsi.mOnBatteryTimeBase,
7591 mOnBatteryBackgroundTimeBase, in);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08007592 } else {
7593 mBluetoothScanTimer = null;
7594 }
Bookatz956f36bf2017-04-28 09:48:17 -07007595 if (in.readInt() != 0) {
Bookatzb1f04f32017-05-19 13:57:32 -07007596 mBluetoothUnoptimizedScanTimer = new DualTimer(mBsi.mClocks, Uid.this,
7597 BLUETOOTH_UNOPTIMIZED_SCAN_ON, null,
7598 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase, in);
7599 } else {
7600 mBluetoothUnoptimizedScanTimer = null;
7601 }
7602 if (in.readInt() != 0) {
Bookatz956f36bf2017-04-28 09:48:17 -07007603 mBluetoothScanResultCounter = new Counter(mBsi.mOnBatteryTimeBase, in);
7604 } else {
7605 mBluetoothScanResultCounter = null;
7606 }
Bookatzb1f04f32017-05-19 13:57:32 -07007607 if (in.readInt() != 0) {
7608 mBluetoothScanResultBgCounter = new Counter(mOnBatteryBackgroundTimeBase, in);
7609 } else {
7610 mBluetoothScanResultBgCounter = null;
7611 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08007612 mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
Dianne Hackborn61659e52014-07-09 16:13:01 -07007613 for (int i = 0; i < NUM_PROCESS_STATE; i++) {
7614 if (in.readInt() != 0) {
7615 makeProcessState(i, in);
7616 } else {
7617 mProcessStateTimer[i] = null;
7618 }
7619 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007620 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007621 mVibratorOnTimer = new BatchTimer(mBsi.mClocks, Uid.this, VIBRATOR_ON,
7622 mBsi.mOnBatteryTimeBase, in);
Dianne Hackborna06de0f2012-12-11 16:34:47 -08007623 } else {
7624 mVibratorOnTimer = null;
7625 }
7626 if (in.readInt() != 0) {
Dianne Hackborn617f8772009-03-31 15:04:46 -07007627 mUserActivityCounters = new Counter[NUM_USER_ACTIVITY_TYPES];
7628 for (int i=0; i<NUM_USER_ACTIVITY_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08007629 mUserActivityCounters[i] = new Counter(mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn617f8772009-03-31 15:04:46 -07007630 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007631 } else {
7632 mUserActivityCounters = null;
Dianne Hackborn617f8772009-03-31 15:04:46 -07007633 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007634 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007635 mNetworkByteActivityCounters = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
7636 mNetworkPacketActivityCounters
7637 = new LongSamplingCounter[NUM_NETWORK_ACTIVITY_TYPES];
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007638 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007639 mNetworkByteActivityCounters[i]
Joe Onoratoabded112016-02-08 16:49:39 -08007640 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007641 mNetworkPacketActivityCounters[i]
Joe Onoratoabded112016-02-08 16:49:39 -08007642 = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007643 }
Joe Onoratoabded112016-02-08 16:49:39 -08007644 mMobileRadioActiveTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
7645 mMobileRadioActiveCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007646 } else {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08007647 mNetworkByteActivityCounters = null;
7648 mNetworkPacketActivityCounters = null;
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07007649 }
Adam Lesinskie08af192015-03-25 16:42:59 -07007650
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007651 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007652 mWifiControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007653 NUM_WIFI_TX_LEVELS, in);
7654 } else {
7655 mWifiControllerActivity = null;
Adam Lesinskie08af192015-03-25 16:42:59 -07007656 }
7657
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007658 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007659 mBluetoothControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007660 NUM_BT_TX_LEVELS, in);
7661 } else {
7662 mBluetoothControllerActivity = null;
7663 }
7664
7665 if (in.readInt() != 0) {
Joe Onoratoabded112016-02-08 16:49:39 -08007666 mModemControllerActivity = new ControllerActivityCounterImpl(mBsi.mOnBatteryTimeBase,
Adam Lesinski21f76aa2016-01-25 12:27:06 -08007667 ModemActivityInfo.TX_POWER_LEVELS, in);
7668 } else {
7669 mModemControllerActivity = null;
Adam Lesinskie08af192015-03-25 16:42:59 -07007670 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007671
Joe Onoratoabded112016-02-08 16:49:39 -08007672 mUserCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
7673 mSystemCpuTime = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007674
Adam Lesinski6832f392015-09-05 18:05:40 -07007675 if (in.readInt() != 0) {
7676 int numCpuClusters = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -08007677 if (mBsi.mPowerProfile != null && mBsi.mPowerProfile.getNumCpuClusters() != numCpuClusters) {
Adam Lesinski6832f392015-09-05 18:05:40 -07007678 throw new ParcelFormatException("Incompatible number of cpu clusters");
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007679 }
Adam Lesinski6832f392015-09-05 18:05:40 -07007680
Sudheer Shankaaf857412017-07-21 00:14:24 -07007681 mCpuClusterSpeedTimesUs = new LongSamplingCounter[numCpuClusters][];
Adam Lesinski6832f392015-09-05 18:05:40 -07007682 for (int cluster = 0; cluster < numCpuClusters; cluster++) {
7683 if (in.readInt() != 0) {
7684 int numSpeeds = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -08007685 if (mBsi.mPowerProfile != null &&
7686 mBsi.mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != numSpeeds) {
Adam Lesinski6832f392015-09-05 18:05:40 -07007687 throw new ParcelFormatException("Incompatible number of cpu speeds");
7688 }
7689
7690 final LongSamplingCounter[] cpuSpeeds = new LongSamplingCounter[numSpeeds];
Sudheer Shankaaf857412017-07-21 00:14:24 -07007691 mCpuClusterSpeedTimesUs[cluster] = cpuSpeeds;
Adam Lesinski6832f392015-09-05 18:05:40 -07007692 for (int speed = 0; speed < numSpeeds; speed++) {
7693 if (in.readInt() != 0) {
Sudheer Shankaaf857412017-07-21 00:14:24 -07007694 cpuSpeeds[speed] = new LongSamplingCounter(
7695 mBsi.mOnBatteryTimeBase, in);
Adam Lesinski6832f392015-09-05 18:05:40 -07007696 }
7697 }
Adam Lesinskia57a5402015-09-28 10:21:33 -07007698 } else {
Sudheer Shankaaf857412017-07-21 00:14:24 -07007699 mCpuClusterSpeedTimesUs[cluster] = null;
Adam Lesinski6832f392015-09-05 18:05:40 -07007700 }
7701 }
7702 } else {
Sudheer Shankaaf857412017-07-21 00:14:24 -07007703 mCpuClusterSpeedTimesUs = null;
Adam Lesinski06af1fa2015-05-05 17:35:35 -07007704 }
Adam Lesinski5f056f62016-07-14 16:56:08 -07007705
Sudheer Shanka59f5c002017-05-15 10:57:15 -07007706 mCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(in, mBsi.mOnBatteryTimeBase);
7707 mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readFromParcel(
7708 in, mBsi.mOnBatteryScreenOffTimeBase);
Sudheer Shanka9b735c52017-05-09 18:26:18 -07007709
7710 if (in.readInt() != 0) {
Adam Lesinski5f056f62016-07-14 16:56:08 -07007711 mMobileRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
7712 } else {
7713 mMobileRadioApWakeupCount = null;
7714 }
7715
7716 if (in.readInt() != 0) {
7717 mWifiRadioApWakeupCount = new LongSamplingCounter(mBsi.mOnBatteryTimeBase, in);
7718 } else {
7719 mWifiRadioApWakeupCount = null;
7720 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007721 }
7722
7723 /**
7724 * The statistics associated with a particular wake lock.
7725 */
Joe Onoratoabded112016-02-08 16:49:39 -08007726 public static class Wakelock extends BatteryStats.Uid.Wakelock {
7727 /**
7728 * BatteryStatsImpl that we are associated with.
7729 */
7730 protected BatteryStatsImpl mBsi;
7731
7732 /**
7733 * BatteryStatsImpl that we are associated with.
7734 */
7735 protected Uid mUid;
7736
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007737 /**
7738 * How long (in ms) this uid has been keeping the device partially awake.
Bookatz5b5ec322017-05-26 09:40:38 -07007739 * 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 -08007740 */
Bookatz5b5ec322017-05-26 09:40:38 -07007741 DualTimer mTimerPartial;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007742
7743 /**
7744 * How long (in ms) this uid has been keeping the device fully awake.
7745 */
Evan Millarc64edde2009-04-18 12:26:32 -07007746 StopwatchTimer mTimerFull;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007747
7748 /**
7749 * How long (in ms) this uid has had a window keeping the device awake.
7750 */
Evan Millarc64edde2009-04-18 12:26:32 -07007751 StopwatchTimer mTimerWindow;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007752
7753 /**
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007754 * How long (in ms) this uid has had a draw wake lock.
Adam Lesinski9425fe22015-06-19 12:02:13 -07007755 */
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007756 StopwatchTimer mTimerDraw;
Adam Lesinski9425fe22015-06-19 12:02:13 -07007757
Joe Onoratoabded112016-02-08 16:49:39 -08007758 public Wakelock(BatteryStatsImpl bsi, Uid uid) {
7759 mBsi = bsi;
7760 mUid = uid;
7761 }
7762
Adam Lesinski9425fe22015-06-19 12:02:13 -07007763 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007764 * Reads a possibly null Timer from a Parcel. The timer is associated with the
7765 * proper timer pool from the given BatteryStatsImpl object.
7766 *
7767 * @param in the Parcel to be read from.
7768 * return a new Timer, or null.
7769 */
Joe Onorato92fd23f2016-07-25 11:18:42 -07007770 private StopwatchTimer readStopwatchTimerFromParcel(int type,
7771 ArrayList<StopwatchTimer> pool, TimeBase timeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007772 if (in.readInt() == 0) {
7773 return null;
7774 }
7775
Joe Onoratoabded112016-02-08 16:49:39 -08007776 return new StopwatchTimer(mBsi.mClocks, mUid, type, pool, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007777 }
7778
Joe Onorato92fd23f2016-07-25 11:18:42 -07007779 /**
7780 * Reads a possibly null Timer from a Parcel. The timer is associated with the
7781 * proper timer pool from the given BatteryStatsImpl object.
7782 *
7783 * @param in the Parcel to be read from.
7784 * return a new Timer, or null.
7785 */
Bookatz5b5ec322017-05-26 09:40:38 -07007786 private DualTimer readDualTimerFromParcel(int type, ArrayList<StopwatchTimer> pool,
7787 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
Joe Onorato92fd23f2016-07-25 11:18:42 -07007788 if (in.readInt() == 0) {
7789 return null;
7790 }
7791
Bookatz5b5ec322017-05-26 09:40:38 -07007792 return new DualTimer(mBsi.mClocks, mUid, type, pool, timeBase, bgTimeBase, in);
Joe Onorato92fd23f2016-07-25 11:18:42 -07007793 }
7794
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007795 boolean reset() {
7796 boolean wlactive = false;
7797 if (mTimerFull != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007798 wlactive |= !mTimerFull.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007799 }
7800 if (mTimerPartial != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007801 wlactive |= !mTimerPartial.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007802 }
7803 if (mTimerWindow != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007804 wlactive |= !mTimerWindow.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007805 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007806 if (mTimerDraw != null) {
7807 wlactive |= !mTimerDraw.reset(false);
Adam Lesinski9425fe22015-06-19 12:02:13 -07007808 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007809 if (!wlactive) {
7810 if (mTimerFull != null) {
7811 mTimerFull.detach();
7812 mTimerFull = null;
7813 }
7814 if (mTimerPartial != null) {
7815 mTimerPartial.detach();
7816 mTimerPartial = null;
7817 }
7818 if (mTimerWindow != null) {
7819 mTimerWindow.detach();
7820 mTimerWindow = null;
7821 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007822 if (mTimerDraw != null) {
7823 mTimerDraw.detach();
7824 mTimerDraw = null;
Adam Lesinski9425fe22015-06-19 12:02:13 -07007825 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007826 }
7827 return !wlactive;
7828 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007829
Bookatz5b5ec322017-05-26 09:40:38 -07007830 void readFromParcelLocked(TimeBase timeBase, TimeBase screenOffTimeBase,
7831 TimeBase screenOffBgTimeBase, Parcel in) {
7832 mTimerPartial = readDualTimerFromParcel(WAKE_TYPE_PARTIAL,
7833 mBsi.mPartialTimers, screenOffTimeBase, screenOffBgTimeBase, in);
Joe Onorato92fd23f2016-07-25 11:18:42 -07007834 mTimerFull = readStopwatchTimerFromParcel(WAKE_TYPE_FULL,
7835 mBsi.mFullTimers, timeBase, in);
7836 mTimerWindow = readStopwatchTimerFromParcel(WAKE_TYPE_WINDOW,
7837 mBsi.mWindowTimers, timeBase, in);
7838 mTimerDraw = readStopwatchTimerFromParcel(WAKE_TYPE_DRAW,
7839 mBsi.mDrawTimers, timeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007840 }
7841
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007842 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
7843 Timer.writeTimerToParcel(out, mTimerPartial, elapsedRealtimeUs);
7844 Timer.writeTimerToParcel(out, mTimerFull, elapsedRealtimeUs);
7845 Timer.writeTimerToParcel(out, mTimerWindow, elapsedRealtimeUs);
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007846 Timer.writeTimerToParcel(out, mTimerDraw, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007847 }
7848
7849 @Override
7850 public Timer getWakeTime(int type) {
7851 switch (type) {
7852 case WAKE_TYPE_FULL: return mTimerFull;
7853 case WAKE_TYPE_PARTIAL: return mTimerPartial;
7854 case WAKE_TYPE_WINDOW: return mTimerWindow;
Jeff Brown6a8bd7b2015-06-19 15:07:51 -07007855 case WAKE_TYPE_DRAW: return mTimerDraw;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007856 default: throw new IllegalArgumentException("type = " + type);
7857 }
7858 }
7859 }
7860
Joe Onoratoabded112016-02-08 16:49:39 -08007861 public static class Sensor extends BatteryStats.Uid.Sensor {
7862 /**
7863 * BatteryStatsImpl that we are associated with.
7864 */
7865 protected BatteryStatsImpl mBsi;
7866
7867 /**
Bookatz867c0d72017-03-07 18:23:42 -08007868 * Uid that we are associated with.
Joe Onoratoabded112016-02-08 16:49:39 -08007869 */
7870 protected Uid mUid;
7871
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007872 final int mHandle;
Bookatz867c0d72017-03-07 18:23:42 -08007873 DualTimer mTimer;
Amith Yamasaniab9ad192016-12-06 12:46:59 -08007874
Joe Onoratoabded112016-02-08 16:49:39 -08007875 public Sensor(BatteryStatsImpl bsi, Uid uid, int handle) {
7876 mBsi = bsi;
7877 mUid = uid;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007878 mHandle = handle;
7879 }
7880
Bookatz867c0d72017-03-07 18:23:42 -08007881 private DualTimer readTimersFromParcel(
7882 TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007883 if (in.readInt() == 0) {
7884 return null;
7885 }
7886
Joe Onoratoabded112016-02-08 16:49:39 -08007887 ArrayList<StopwatchTimer> pool = mBsi.mSensorTimers.get(mHandle);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007888 if (pool == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07007889 pool = new ArrayList<StopwatchTimer>();
Joe Onoratoabded112016-02-08 16:49:39 -08007890 mBsi.mSensorTimers.put(mHandle, pool);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007891 }
Bookatz867c0d72017-03-07 18:23:42 -08007892 return new DualTimer(mBsi.mClocks, mUid, 0, pool, timeBase, bgTimeBase, in);
Amith Yamasaniab9ad192016-12-06 12:46:59 -08007893 }
7894
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007895 boolean reset() {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007896 if (mTimer.reset(true)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07007897 mTimer = null;
7898 return true;
7899 }
7900 return false;
7901 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07007902
Bookatz867c0d72017-03-07 18:23:42 -08007903 void readFromParcelLocked(TimeBase timeBase, TimeBase bgTimeBase, Parcel in) {
7904 mTimer = readTimersFromParcel(timeBase, bgTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007905 }
7906
Dianne Hackborn97ae5382014-03-05 16:43:25 -08007907 void writeToParcelLocked(Parcel out, long elapsedRealtimeUs) {
Bookatzaa4594a2017-03-24 12:39:56 -07007908 Timer.writeTimerToParcel(out, mTimer, elapsedRealtimeUs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007909 }
7910
7911 @Override
7912 public Timer getSensorTime() {
Bookatzaa4594a2017-03-24 12:39:56 -07007913 return mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007914 }
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007915
7916 @Override
Bookatz867c0d72017-03-07 18:23:42 -08007917 public Timer getSensorBackgroundTime() {
7918 if (mTimer == null) {
7919 return null;
7920 }
7921 return mTimer.getSubTimer();
Amith Yamasaniab9ad192016-12-06 12:46:59 -08007922 }
7923
7924 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007925 public int getHandle() {
7926 return mHandle;
7927 }
7928 }
7929
7930 /**
7931 * The statistics associated with a particular process.
7932 */
Joe Onoratoabded112016-02-08 16:49:39 -08007933 public static class Proc extends BatteryStats.Uid.Proc implements TimeBaseObs {
7934 /**
7935 * BatteryStatsImpl that we are associated with.
7936 */
7937 protected BatteryStatsImpl mBsi;
7938
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007939 /**
Dianne Hackborncd0e3352014-08-07 17:08:09 -07007940 * The name of this process.
7941 */
7942 final String mName;
7943
7944 /**
Dianne Hackborn099bc622014-01-22 13:39:16 -08007945 * Remains true until removed from the stats.
7946 */
7947 boolean mActive = true;
7948
7949 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07007950 * Total time (in ms) spent executing in user code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007951 */
7952 long mUserTime;
7953
7954 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07007955 * Total time (in ms) spent executing in kernel code.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007956 */
7957 long mSystemTime;
7958
7959 /**
Dianne Hackborn62793e42015-03-09 11:15:41 -07007960 * Amount of time (in ms) the process was running in the foreground.
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007961 */
7962 long mForegroundTime;
7963
7964 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007965 * Number of times the process has been started.
7966 */
7967 int mStarts;
7968
7969 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08007970 * Number of times the process has crashed.
7971 */
7972 int mNumCrashes;
7973
7974 /**
7975 * Number of times the process has had an ANR.
7976 */
7977 int mNumAnrs;
7978
7979 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08007980 * The amount of user time loaded from a previous save.
7981 */
7982 long mLoadedUserTime;
7983
7984 /**
7985 * The amount of system time loaded from a previous save.
7986 */
7987 long mLoadedSystemTime;
7988
7989 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07007990 * The amount of foreground time loaded from a previous save.
7991 */
7992 long mLoadedForegroundTime;
7993
7994 /**
Jeff Sharkey3e013e82013-04-25 14:48:19 -07007995 * The number of times the process has started from a previous save.
7996 */
7997 int mLoadedStarts;
7998
7999 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008000 * Number of times the process has crashed from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008001 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008002 int mLoadedNumCrashes;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008003
8004 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008005 * Number of times the process has had an ANR from a previous save.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008006 */
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008007 int mLoadedNumAnrs;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07008008
8009 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008010 * The amount of user time when last unplugged.
8011 */
8012 long mUnpluggedUserTime;
8013
8014 /**
8015 * The amount of system time when last unplugged.
8016 */
8017 long mUnpluggedSystemTime;
8018
8019 /**
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008020 * The amount of foreground time since unplugged.
8021 */
8022 long mUnpluggedForegroundTime;
8023
Jeff Sharkey3e013e82013-04-25 14:48:19 -07008024 /**
8025 * The number of times the process has started before unplugged.
8026 */
8027 int mUnpluggedStarts;
8028
Dianne Hackborn61659e52014-07-09 16:13:01 -07008029 /**
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008030 * Number of times the process has crashed before unplugged.
8031 */
8032 int mUnpluggedNumCrashes;
8033
8034 /**
8035 * Number of times the process has had an ANR before unplugged.
8036 */
8037 int mUnpluggedNumAnrs;
8038
Dianne Hackborn287952c2010-09-22 22:34:31 -07008039 ArrayList<ExcessivePower> mExcessivePower;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008040
Joe Onoratoabded112016-02-08 16:49:39 -08008041 public Proc(BatteryStatsImpl bsi, String name) {
8042 mBsi = bsi;
Dianne Hackborncd0e3352014-08-07 17:08:09 -07008043 mName = name;
Joe Onoratoabded112016-02-08 16:49:39 -08008044 mBsi.mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008045 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07008046
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008047 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008048 mUnpluggedUserTime = mUserTime;
8049 mUnpluggedSystemTime = mSystemTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008050 mUnpluggedForegroundTime = mForegroundTime;
Jeff Sharkey3e013e82013-04-25 14:48:19 -07008051 mUnpluggedStarts = mStarts;
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008052 mUnpluggedNumCrashes = mNumCrashes;
8053 mUnpluggedNumAnrs = mNumAnrs;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008054 }
8055
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008056 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008057 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008058
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008059 void detach() {
Dianne Hackborn099bc622014-01-22 13:39:16 -08008060 mActive = false;
Joe Onoratoabded112016-02-08 16:49:39 -08008061 mBsi.mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008062 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008063
Dianne Hackborn287952c2010-09-22 22:34:31 -07008064 public int countExcessivePowers() {
8065 return mExcessivePower != null ? mExcessivePower.size() : 0;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008066 }
8067
Dianne Hackborn287952c2010-09-22 22:34:31 -07008068 public ExcessivePower getExcessivePower(int i) {
8069 if (mExcessivePower != null) {
8070 return mExcessivePower.get(i);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008071 }
8072 return null;
8073 }
8074
Dianne Hackborn287952c2010-09-22 22:34:31 -07008075 public void addExcessiveCpu(long overTime, long usedTime) {
8076 if (mExcessivePower == null) {
8077 mExcessivePower = new ArrayList<ExcessivePower>();
8078 }
8079 ExcessivePower ew = new ExcessivePower();
8080 ew.type = ExcessivePower.TYPE_CPU;
8081 ew.overTime = overTime;
8082 ew.usedTime = usedTime;
8083 mExcessivePower.add(ew);
8084 }
8085
8086 void writeExcessivePowerToParcelLocked(Parcel out) {
8087 if (mExcessivePower == null) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008088 out.writeInt(0);
8089 return;
8090 }
8091
Dianne Hackborn287952c2010-09-22 22:34:31 -07008092 final int N = mExcessivePower.size();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008093 out.writeInt(N);
8094 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008095 ExcessivePower ew = mExcessivePower.get(i);
8096 out.writeInt(ew.type);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008097 out.writeLong(ew.overTime);
8098 out.writeLong(ew.usedTime);
8099 }
8100 }
8101
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07008102 void readExcessivePowerFromParcelLocked(Parcel in) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008103 final int N = in.readInt();
8104 if (N == 0) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008105 mExcessivePower = null;
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07008106 return;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008107 }
8108
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08008109 if (N > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07008110 throw new ParcelFormatException(
8111 "File corrupt: too many excessive power entries " + N);
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -08008112 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07008113
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07008114 mExcessivePower = new ArrayList<>();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008115 for (int i=0; i<N; i++) {
Dianne Hackborn287952c2010-09-22 22:34:31 -07008116 ExcessivePower ew = new ExcessivePower();
8117 ew.type = in.readInt();
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008118 ew.overTime = in.readLong();
8119 ew.usedTime = in.readLong();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008120 mExcessivePower.add(ew);
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008121 }
8122 }
8123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008124 void writeToParcelLocked(Parcel out) {
8125 out.writeLong(mUserTime);
8126 out.writeLong(mSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008127 out.writeLong(mForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008128 out.writeInt(mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008129 out.writeInt(mNumCrashes);
8130 out.writeInt(mNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008131 out.writeLong(mLoadedUserTime);
8132 out.writeLong(mLoadedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008133 out.writeLong(mLoadedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008134 out.writeInt(mLoadedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008135 out.writeInt(mLoadedNumCrashes);
8136 out.writeInt(mLoadedNumAnrs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008137 out.writeLong(mUnpluggedUserTime);
8138 out.writeLong(mUnpluggedSystemTime);
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008139 out.writeLong(mUnpluggedForegroundTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008140 out.writeInt(mUnpluggedStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008141 out.writeInt(mUnpluggedNumCrashes);
8142 out.writeInt(mUnpluggedNumAnrs);
Dianne Hackborn287952c2010-09-22 22:34:31 -07008143 writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008144 }
8145
8146 void readFromParcelLocked(Parcel in) {
8147 mUserTime = in.readLong();
8148 mSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008149 mForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008150 mStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008151 mNumCrashes = in.readInt();
8152 mNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008153 mLoadedUserTime = in.readLong();
8154 mLoadedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008155 mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008156 mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008157 mLoadedNumCrashes = in.readInt();
8158 mLoadedNumAnrs = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008159 mUnpluggedUserTime = in.readLong();
8160 mUnpluggedSystemTime = in.readLong();
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008161 mUnpluggedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008162 mUnpluggedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008163 mUnpluggedNumCrashes = in.readInt();
8164 mUnpluggedNumAnrs = in.readInt();
Dianne Hackborn287952c2010-09-22 22:34:31 -07008165 readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008166 }
8167
Adam Lesinski06af1fa2015-05-05 17:35:35 -07008168 public void addCpuTimeLocked(int utime, int stime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008169 mUserTime += utime;
8170 mSystemTime += stime;
8171 }
8172
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008173 public void addForegroundTimeLocked(long ttime) {
8174 mForegroundTime += ttime;
8175 }
8176
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008177 public void incStartsLocked() {
8178 mStarts++;
8179 }
8180
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008181 public void incNumCrashesLocked() {
8182 mNumCrashes++;
8183 }
8184
8185 public void incNumAnrsLocked() {
8186 mNumAnrs++;
8187 }
8188
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008189 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08008190 public boolean isActive() {
8191 return mActive;
8192 }
8193
8194 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008195 public long getUserTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008196 long val = mUserTime;
8197 if (which == STATS_CURRENT) {
8198 val -= mLoadedUserTime;
8199 } else if (which == STATS_SINCE_UNPLUGGED) {
8200 val -= mUnpluggedUserTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008201 }
8202 return val;
8203 }
8204
8205 @Override
8206 public long getSystemTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008207 long val = mSystemTime;
8208 if (which == STATS_CURRENT) {
8209 val -= mLoadedSystemTime;
8210 } else if (which == STATS_SINCE_UNPLUGGED) {
8211 val -= mUnpluggedSystemTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008212 }
8213 return val;
8214 }
8215
8216 @Override
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008217 public long getForegroundTime(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008218 long val = mForegroundTime;
8219 if (which == STATS_CURRENT) {
8220 val -= mLoadedForegroundTime;
8221 } else if (which == STATS_SINCE_UNPLUGGED) {
8222 val -= mUnpluggedForegroundTime;
Amith Yamasanieaeb6632009-06-03 15:16:10 -07008223 }
8224 return val;
8225 }
8226
8227 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008228 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008229 int val = mStarts;
8230 if (which == STATS_CURRENT) {
8231 val -= mLoadedStarts;
8232 } else if (which == STATS_SINCE_UNPLUGGED) {
8233 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008234 }
8235 return val;
8236 }
Amith Yamasanie43530a2009-08-21 13:11:37 -07008237
Dianne Hackborn1e01d162014-12-04 17:46:42 -08008238 @Override
8239 public int getNumCrashes(int which) {
8240 int val = mNumCrashes;
8241 if (which == STATS_CURRENT) {
8242 val -= mLoadedNumCrashes;
8243 } else if (which == STATS_SINCE_UNPLUGGED) {
8244 val -= mUnpluggedNumCrashes;
8245 }
8246 return val;
8247 }
8248
8249 @Override
8250 public int getNumAnrs(int which) {
8251 int val = mNumAnrs;
8252 if (which == STATS_CURRENT) {
8253 val -= mLoadedNumAnrs;
8254 } else if (which == STATS_SINCE_UNPLUGGED) {
8255 val -= mUnpluggedNumAnrs;
8256 }
8257 return val;
8258 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008259 }
8260
8261 /**
8262 * The statistics associated with a particular package.
8263 */
Joe Onoratoabded112016-02-08 16:49:39 -08008264 public static class Pkg extends BatteryStats.Uid.Pkg implements TimeBaseObs {
8265 /**
8266 * BatteryStatsImpl that we are associated with.
8267 */
8268 protected BatteryStatsImpl mBsi;
8269
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008270 /**
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008271 * Number of times wakeup alarms have occurred for this app.
Bookatz98d4d5c2017-08-01 19:07:54 -07008272 * On screen-off timebase starting in report v25.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008273 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008274 ArrayMap<String, Counter> mWakeupAlarms = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008275
8276 /**
8277 * The statics we have collected for this package's services.
8278 */
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008279 final ArrayMap<String, Serv> mServiceStats = new ArrayMap<>();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008280
Joe Onoratoabded112016-02-08 16:49:39 -08008281 public Pkg(BatteryStatsImpl bsi) {
8282 mBsi = bsi;
8283 mBsi.mOnBatteryScreenOffTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008284 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008285
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008286 public void onTimeStarted(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008287 }
8288
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008289 public void onTimeStopped(long elapsedRealtime, long baseUptime, long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008290 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008291
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008292 void detach() {
Joe Onoratoabded112016-02-08 16:49:39 -08008293 mBsi.mOnBatteryScreenOffTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008294 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008295
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008296 void readFromParcelLocked(Parcel in) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008297 int numWA = in.readInt();
8298 mWakeupAlarms.clear();
8299 for (int i=0; i<numWA; i++) {
8300 String tag = in.readString();
Bookatz98d4d5c2017-08-01 19:07:54 -07008301 mWakeupAlarms.put(tag, new Counter(mBsi.mOnBatteryScreenOffTimeBase, in));
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008302 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008303
8304 int numServs = in.readInt();
8305 mServiceStats.clear();
8306 for (int m = 0; m < numServs; m++) {
8307 String serviceName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -08008308 Uid.Pkg.Serv serv = new Serv(mBsi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008309 mServiceStats.put(serviceName, serv);
8310
8311 serv.readFromParcelLocked(in);
8312 }
8313 }
8314
8315 void writeToParcelLocked(Parcel out) {
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008316 int numWA = mWakeupAlarms.size();
8317 out.writeInt(numWA);
8318 for (int i=0; i<numWA; i++) {
8319 out.writeString(mWakeupAlarms.keyAt(i));
8320 mWakeupAlarms.valueAt(i).writeToParcel(out);
8321 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008322
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008323 final int NS = mServiceStats.size();
8324 out.writeInt(NS);
8325 for (int i=0; i<NS; i++) {
8326 out.writeString(mServiceStats.keyAt(i));
8327 Uid.Pkg.Serv serv = mServiceStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008328 serv.writeToParcelLocked(out);
8329 }
8330 }
8331
8332 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008333 public ArrayMap<String, ? extends BatteryStats.Counter> getWakeupAlarmStats() {
8334 return mWakeupAlarms;
8335 }
8336
8337 public void noteWakeupAlarmLocked(String tag) {
8338 Counter c = mWakeupAlarms.get(tag);
8339 if (c == null) {
Bookatz98d4d5c2017-08-01 19:07:54 -07008340 c = new Counter(mBsi.mOnBatteryScreenOffTimeBase);
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008341 mWakeupAlarms.put(tag, c);
8342 }
8343 c.stepAtomic();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008344 }
8345
8346 @Override
Dianne Hackborn1e725a72015-03-24 18:23:19 -07008347 public ArrayMap<String, ? extends BatteryStats.Uid.Pkg.Serv> getServiceStats() {
8348 return mServiceStats;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008349 }
8350
8351 /**
8352 * The statistics associated with a particular service.
8353 */
Joe Onoratoabded112016-02-08 16:49:39 -08008354 public static class Serv extends BatteryStats.Uid.Pkg.Serv implements TimeBaseObs {
8355 /**
8356 * BatteryStatsImpl that we are associated with.
8357 */
8358 protected BatteryStatsImpl mBsi;
8359
8360 /**
8361 * The android package in which this service resides.
8362 */
8363 protected Pkg mPkg;
8364
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008365 /**
8366 * Total time (ms in battery uptime) the service has been left started.
8367 */
Joe Onoratoabded112016-02-08 16:49:39 -08008368 protected long mStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008369
8370 /**
8371 * If service has been started and not yet stopped, this is
8372 * when it was started.
8373 */
Joe Onoratoabded112016-02-08 16:49:39 -08008374 protected long mRunningSince;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008375
8376 /**
8377 * True if we are currently running.
8378 */
Joe Onoratoabded112016-02-08 16:49:39 -08008379 protected boolean mRunning;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008380
8381 /**
8382 * Total number of times startService() has been called.
8383 */
Joe Onoratoabded112016-02-08 16:49:39 -08008384 protected int mStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008385
8386 /**
8387 * Total time (ms in battery uptime) the service has been left launched.
8388 */
Joe Onoratoabded112016-02-08 16:49:39 -08008389 protected long mLaunchedTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008390
8391 /**
8392 * If service has been launched and not yet exited, this is
8393 * when it was launched (ms in battery uptime).
8394 */
Joe Onoratoabded112016-02-08 16:49:39 -08008395 protected long mLaunchedSince;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008396
8397 /**
8398 * True if we are currently launched.
8399 */
Joe Onoratoabded112016-02-08 16:49:39 -08008400 protected boolean mLaunched;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008401
8402 /**
8403 * Total number times the service has been launched.
8404 */
Joe Onoratoabded112016-02-08 16:49:39 -08008405 protected int mLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008406
8407 /**
8408 * The amount of time spent started loaded from a previous save
8409 * (ms in battery uptime).
8410 */
Joe Onoratoabded112016-02-08 16:49:39 -08008411 protected long mLoadedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008412
8413 /**
8414 * The number of starts loaded from a previous save.
8415 */
Joe Onoratoabded112016-02-08 16:49:39 -08008416 protected int mLoadedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008417
8418 /**
8419 * The number of launches loaded from a previous save.
8420 */
Joe Onoratoabded112016-02-08 16:49:39 -08008421 protected int mLoadedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008422
8423 /**
8424 * The amount of time spent started as of the last run (ms
8425 * in battery uptime).
8426 */
Joe Onoratoabded112016-02-08 16:49:39 -08008427 protected long mLastStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008428
8429 /**
8430 * The number of starts as of the last run.
8431 */
Joe Onoratoabded112016-02-08 16:49:39 -08008432 protected int mLastStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008433
8434 /**
8435 * The number of launches as of the last run.
8436 */
Joe Onoratoabded112016-02-08 16:49:39 -08008437 protected int mLastLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008438
8439 /**
8440 * The amount of time spent started when last unplugged (ms
8441 * in battery uptime).
8442 */
Joe Onoratoabded112016-02-08 16:49:39 -08008443 protected long mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008444
8445 /**
8446 * The number of starts when last unplugged.
8447 */
Joe Onoratoabded112016-02-08 16:49:39 -08008448 protected int mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008449
8450 /**
8451 * The number of launches when last unplugged.
8452 */
Joe Onoratoabded112016-02-08 16:49:39 -08008453 protected int mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008454
Joe Onoratoabded112016-02-08 16:49:39 -08008455 /**
8456 * Construct a Serv. Also adds it to the on-battery time base as a listener.
8457 */
8458 public Serv(BatteryStatsImpl bsi) {
8459 mBsi = bsi;
8460 mBsi.mOnBatteryTimeBase.add(this);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008461 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008462
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008463 public void onTimeStarted(long elapsedRealtime, long baseUptime,
8464 long baseRealtime) {
8465 mUnpluggedStartTime = getStartTimeToNowLocked(baseUptime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008466 mUnpluggedStarts = mStarts;
8467 mUnpluggedLaunches = mLaunches;
8468 }
8469
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008470 public void onTimeStopped(long elapsedRealtime, long baseUptime,
8471 long baseRealtime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008472 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008473
Joe Onoratoabded112016-02-08 16:49:39 -08008474 /**
8475 * Remove this Serv as a listener from the time base.
8476 */
8477 public void detach() {
8478 mBsi.mOnBatteryTimeBase.remove(this);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07008479 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008480
Joe Onoratoabded112016-02-08 16:49:39 -08008481 public void readFromParcelLocked(Parcel in) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008482 mStartTime = in.readLong();
8483 mRunningSince = in.readLong();
8484 mRunning = in.readInt() != 0;
8485 mStarts = in.readInt();
8486 mLaunchedTime = in.readLong();
8487 mLaunchedSince = in.readLong();
8488 mLaunched = in.readInt() != 0;
8489 mLaunches = in.readInt();
8490 mLoadedStartTime = in.readLong();
8491 mLoadedStarts = in.readInt();
8492 mLoadedLaunches = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -07008493 mLastStartTime = 0;
8494 mLastStarts = 0;
8495 mLastLaunches = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008496 mUnpluggedStartTime = in.readLong();
8497 mUnpluggedStarts = in.readInt();
8498 mUnpluggedLaunches = in.readInt();
8499 }
8500
Joe Onoratoabded112016-02-08 16:49:39 -08008501 public void writeToParcelLocked(Parcel out) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008502 out.writeLong(mStartTime);
8503 out.writeLong(mRunningSince);
8504 out.writeInt(mRunning ? 1 : 0);
8505 out.writeInt(mStarts);
8506 out.writeLong(mLaunchedTime);
8507 out.writeLong(mLaunchedSince);
8508 out.writeInt(mLaunched ? 1 : 0);
8509 out.writeInt(mLaunches);
8510 out.writeLong(mLoadedStartTime);
8511 out.writeInt(mLoadedStarts);
8512 out.writeInt(mLoadedLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008513 out.writeLong(mUnpluggedStartTime);
8514 out.writeInt(mUnpluggedStarts);
8515 out.writeInt(mUnpluggedLaunches);
8516 }
8517
Joe Onoratoabded112016-02-08 16:49:39 -08008518 public long getLaunchTimeToNowLocked(long batteryUptime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008519 if (!mLaunched) return mLaunchedTime;
8520 return mLaunchedTime + batteryUptime - mLaunchedSince;
8521 }
8522
Joe Onoratoabded112016-02-08 16:49:39 -08008523 public long getStartTimeToNowLocked(long batteryUptime) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008524 if (!mRunning) return mStartTime;
8525 return mStartTime + batteryUptime - mRunningSince;
8526 }
8527
8528 public void startLaunchedLocked() {
8529 if (!mLaunched) {
8530 mLaunches++;
Joe Onoratoabded112016-02-08 16:49:39 -08008531 mLaunchedSince = mBsi.getBatteryUptimeLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008532 mLaunched = true;
8533 }
8534 }
8535
8536 public void stopLaunchedLocked() {
8537 if (mLaunched) {
Joe Onoratoabded112016-02-08 16:49:39 -08008538 long time = mBsi.getBatteryUptimeLocked() - mLaunchedSince;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008539 if (time > 0) {
8540 mLaunchedTime += time;
8541 } else {
8542 mLaunches--;
8543 }
8544 mLaunched = false;
8545 }
8546 }
8547
8548 public void startRunningLocked() {
8549 if (!mRunning) {
8550 mStarts++;
Joe Onoratoabded112016-02-08 16:49:39 -08008551 mRunningSince = mBsi.getBatteryUptimeLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008552 mRunning = true;
8553 }
8554 }
8555
8556 public void stopRunningLocked() {
8557 if (mRunning) {
Joe Onoratoabded112016-02-08 16:49:39 -08008558 long time = mBsi.getBatteryUptimeLocked() - mRunningSince;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008559 if (time > 0) {
8560 mStartTime += time;
8561 } else {
8562 mStarts--;
8563 }
8564 mRunning = false;
8565 }
8566 }
8567
8568 public BatteryStatsImpl getBatteryStats() {
Joe Onoratoabded112016-02-08 16:49:39 -08008569 return mBsi;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008570 }
8571
8572 @Override
8573 public int getLaunches(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008574 int val = mLaunches;
8575 if (which == STATS_CURRENT) {
8576 val -= mLoadedLaunches;
8577 } else if (which == STATS_SINCE_UNPLUGGED) {
8578 val -= mUnpluggedLaunches;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008579 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008580 return val;
8581 }
8582
8583 @Override
8584 public long getStartTime(long now, int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008585 long val = getStartTimeToNowLocked(now);
8586 if (which == STATS_CURRENT) {
8587 val -= mLoadedStartTime;
8588 } else if (which == STATS_SINCE_UNPLUGGED) {
8589 val -= mUnpluggedStartTime;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008590 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008591 return val;
8592 }
8593
8594 @Override
8595 public int getStarts(int which) {
Dianne Hackborn4590e522014-03-24 13:36:46 -07008596 int val = mStarts;
8597 if (which == STATS_CURRENT) {
8598 val -= mLoadedStarts;
8599 } else if (which == STATS_SINCE_UNPLUGGED) {
8600 val -= mUnpluggedStarts;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008601 }
8602
8603 return val;
8604 }
8605 }
8606
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008607 final Serv newServiceStatsLocked() {
Joe Onoratoabded112016-02-08 16:49:39 -08008608 return new Serv(mBsi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008609 }
8610 }
8611
8612 /**
8613 * Retrieve the statistics object for a particular process, creating
8614 * if needed.
8615 */
8616 public Proc getProcessStatsLocked(String name) {
8617 Proc ps = mProcessStats.get(name);
8618 if (ps == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08008619 ps = new Proc(mBsi, name);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008620 mProcessStats.put(name, ps);
8621 }
8622
8623 return ps;
8624 }
8625
Dianne Hackborna8d10942015-11-19 17:55:19 -08008626 public void updateUidProcessStateLocked(int procState) {
8627 int uidRunningState;
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008628 // Make special note of Foreground Services
8629 final boolean userAwareService =
8630 (procState == ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
Dianne Hackborna8d10942015-11-19 17:55:19 -08008631 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
8632 uidRunningState = ActivityManager.PROCESS_STATE_NONEXISTENT;
8633 } else if (procState == ActivityManager.PROCESS_STATE_TOP) {
8634 uidRunningState = PROCESS_STATE_TOP;
8635 } else if (procState <= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
8636 // Persistent and other foreground states go here.
8637 uidRunningState = PROCESS_STATE_FOREGROUND_SERVICE;
8638 } else if (procState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
8639 uidRunningState = PROCESS_STATE_TOP_SLEEPING;
8640 } else if (procState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
8641 // Persistent and other foreground states go here.
8642 uidRunningState = PROCESS_STATE_FOREGROUND;
8643 } else if (procState <= ActivityManager.PROCESS_STATE_RECEIVER) {
8644 uidRunningState = PROCESS_STATE_BACKGROUND;
Dianne Hackborn61659e52014-07-09 16:13:01 -07008645 } else {
Dianne Hackborna8d10942015-11-19 17:55:19 -08008646 uidRunningState = PROCESS_STATE_CACHED;
Dianne Hackborn61659e52014-07-09 16:13:01 -07008647 }
Dianne Hackborn61659e52014-07-09 16:13:01 -07008648
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008649 if (mProcessState == uidRunningState && userAwareService == mInForegroundService) {
8650 return;
8651 }
Dianne Hackborna8d10942015-11-19 17:55:19 -08008652
Bookatz867c0d72017-03-07 18:23:42 -08008653 final long elapsedRealtimeMs = mBsi.mClocks.elapsedRealtime();
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008654 if (mProcessState != uidRunningState) {
8655 final long uptimeMs = mBsi.mClocks.uptimeMillis();
Dianne Hackborna8d10942015-11-19 17:55:19 -08008656
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008657 if (mProcessState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
8658 mProcessStateTimer[mProcessState].stopRunningLocked(elapsedRealtimeMs);
Dianne Hackborn61659e52014-07-09 16:13:01 -07008659 }
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008660 mProcessState = uidRunningState;
8661 if (uidRunningState != ActivityManager.PROCESS_STATE_NONEXISTENT) {
8662 if (mProcessStateTimer[uidRunningState] == null) {
8663 makeProcessState(uidRunningState, null);
8664 }
8665 mProcessStateTimer[uidRunningState].startRunningLocked(elapsedRealtimeMs);
8666 }
8667
8668 updateOnBatteryBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
8669 updateOnBatteryScreenOffBgTimeBase(uptimeMs * 1000, elapsedRealtimeMs * 1000);
Dianne Hackborn61659e52014-07-09 16:13:01 -07008670 }
Bookatz867c0d72017-03-07 18:23:42 -08008671
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -07008672 if (userAwareService != mInForegroundService) {
8673 if (userAwareService) {
8674 noteForegroundServiceResumedLocked(elapsedRealtimeMs);
8675 } else {
8676 noteForegroundServicePausedLocked(elapsedRealtimeMs);
8677 }
8678 mInForegroundService = userAwareService;
8679 }
Bookatz867c0d72017-03-07 18:23:42 -08008680 }
8681
Bookatzc8c44962017-05-11 12:12:54 -07008682 /** Whether to consider Uid to be in the background for background timebase purposes. */
8683 public boolean isInBackground() {
Bookatz867c0d72017-03-07 18:23:42 -08008684 // Note that PROCESS_STATE_CACHED and ActivityManager.PROCESS_STATE_NONEXISTENT is
8685 // also considered to be 'background' for our purposes, because it's not foreground.
Bookatzc8c44962017-05-11 12:12:54 -07008686 return mProcessState >= PROCESS_STATE_BACKGROUND;
8687 }
8688
8689 public boolean updateOnBatteryBgTimeBase(long uptimeUs, long realtimeUs) {
8690 boolean on = mBsi.mOnBatteryTimeBase.isRunning() && isInBackground();
8691 return mOnBatteryBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
8692 }
8693
8694 public boolean updateOnBatteryScreenOffBgTimeBase(long uptimeUs, long realtimeUs) {
8695 boolean on = mBsi.mOnBatteryScreenOffTimeBase.isRunning() && isInBackground();
8696 return mOnBatteryScreenOffBackgroundTimeBase.setRunning(on, uptimeUs, realtimeUs);
Dianne Hackborn61659e52014-07-09 16:13:01 -07008697 }
8698
Dianne Hackbornb5e31652010-09-07 12:13:55 -07008699 public SparseArray<? extends Pid> getPidStats() {
8700 return mPids;
8701 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008702
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008703 public Pid getPidStatsLocked(int pid) {
8704 Pid p = mPids.get(pid);
8705 if (p == null) {
8706 p = new Pid();
8707 mPids.put(pid, p);
8708 }
8709 return p;
8710 }
8711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008712 /**
8713 * Retrieve the statistics object for a particular service, creating
8714 * if needed.
8715 */
8716 public Pkg getPackageStatsLocked(String name) {
8717 Pkg ps = mPackageStats.get(name);
8718 if (ps == null) {
Joe Onoratoabded112016-02-08 16:49:39 -08008719 ps = new Pkg(mBsi);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008720 mPackageStats.put(name, ps);
8721 }
8722
8723 return ps;
8724 }
8725
8726 /**
8727 * Retrieve the statistics object for a particular service, creating
8728 * if needed.
8729 */
8730 public Pkg.Serv getServiceStatsLocked(String pkg, String serv) {
8731 Pkg ps = getPackageStatsLocked(pkg);
8732 Pkg.Serv ss = ps.mServiceStats.get(serv);
8733 if (ss == null) {
8734 ss = ps.newServiceStatsLocked();
8735 ps.mServiceStats.put(serv, ss);
8736 }
8737
8738 return ss;
8739 }
8740
Dianne Hackbornd953c532014-08-16 18:17:38 -07008741 public void readSyncSummaryFromParcelLocked(String name, Parcel in) {
Bookatz2bffb5b2017-04-13 11:59:33 -07008742 DualTimer timer = mSyncStats.instantiateObject();
Dianne Hackbornd953c532014-08-16 18:17:38 -07008743 timer.readSummaryFromParcelLocked(in);
8744 mSyncStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008745 }
8746
Dianne Hackbornd953c532014-08-16 18:17:38 -07008747 public void readJobSummaryFromParcelLocked(String name, Parcel in) {
Bookatzaa4594a2017-03-24 12:39:56 -07008748 DualTimer timer = mJobStats.instantiateObject();
Dianne Hackbornd953c532014-08-16 18:17:38 -07008749 timer.readSummaryFromParcelLocked(in);
8750 mJobStats.add(name, timer);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008751 }
8752
Dianne Hackbornd953c532014-08-16 18:17:38 -07008753 public void readWakeSummaryFromParcelLocked(String wlName, Parcel in) {
Joe Onoratoabded112016-02-08 16:49:39 -08008754 Wakelock wl = new Wakelock(mBsi, this);
Dianne Hackbornd953c532014-08-16 18:17:38 -07008755 mWakelockStats.add(wlName, wl);
8756 if (in.readInt() != 0) {
Bookatz5b5ec322017-05-26 09:40:38 -07008757 getWakelockTimerLocked(wl, WAKE_TYPE_FULL).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008758 }
Dianne Hackbornd953c532014-08-16 18:17:38 -07008759 if (in.readInt() != 0) {
Bookatz5b5ec322017-05-26 09:40:38 -07008760 getWakelockTimerLocked(wl, WAKE_TYPE_PARTIAL).readSummaryFromParcelLocked(in);
Dianne Hackbornd953c532014-08-16 18:17:38 -07008761 }
8762 if (in.readInt() != 0) {
Bookatz5b5ec322017-05-26 09:40:38 -07008763 getWakelockTimerLocked(wl, WAKE_TYPE_WINDOW).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008764 }
Adam Lesinski9425fe22015-06-19 12:02:13 -07008765 if (in.readInt() != 0) {
Bookatz5b5ec322017-05-26 09:40:38 -07008766 getWakelockTimerLocked(wl, WAKE_TYPE_DRAW).readSummaryFromParcelLocked(in);
Adam Lesinski9425fe22015-06-19 12:02:13 -07008767 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008768 }
8769
Bookatz867c0d72017-03-07 18:23:42 -08008770 public DualTimer getSensorTimerLocked(int sensor, boolean create) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008771 Sensor se = mSensorStats.get(sensor);
8772 if (se == null) {
8773 if (!create) {
8774 return null;
8775 }
Joe Onoratoabded112016-02-08 16:49:39 -08008776 se = new Sensor(mBsi, this, sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008777 mSensorStats.put(sensor, se);
8778 }
Bookatz867c0d72017-03-07 18:23:42 -08008779 DualTimer t = se.mTimer;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008780 if (t != null) {
8781 return t;
8782 }
Joe Onoratoabded112016-02-08 16:49:39 -08008783 ArrayList<StopwatchTimer> timers = mBsi.mSensorTimers.get(sensor);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008784 if (timers == null) {
Evan Millarc64edde2009-04-18 12:26:32 -07008785 timers = new ArrayList<StopwatchTimer>();
Joe Onoratoabded112016-02-08 16:49:39 -08008786 mBsi.mSensorTimers.put(sensor, timers);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008787 }
Bookatz867c0d72017-03-07 18:23:42 -08008788 t = new DualTimer(mBsi.mClocks, this, BatteryStats.SENSOR, timers,
8789 mBsi.mOnBatteryTimeBase, mOnBatteryBackgroundTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008790 se.mTimer = t;
8791 return t;
8792 }
8793
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008794 public void noteStartSyncLocked(String name, long elapsedRealtimeMs) {
Bookatz2bffb5b2017-04-13 11:59:33 -07008795 DualTimer t = mSyncStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008796 if (t != null) {
8797 t.startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07008798 // TODO(statsd): Possibly use a worksource instead of a uid.
8799 StatsLog.write(StatsLog.SYNC_STATE_CHANGED, getUid(), name, 1);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008800 }
8801 }
8802
8803 public void noteStopSyncLocked(String name, long elapsedRealtimeMs) {
Bookatz2bffb5b2017-04-13 11:59:33 -07008804 DualTimer t = mSyncStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008805 if (t != null) {
8806 t.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07008807 if (!t.isRunningLocked()) { // only tell statsd if truly stopped
8808 // TODO(statsd): Possibly use a worksource instead of a uid.
8809 StatsLog.write(StatsLog.SYNC_STATE_CHANGED, getUid(), name, 0);
8810 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008811 }
8812 }
8813
8814 public void noteStartJobLocked(String name, long elapsedRealtimeMs) {
Bookatzaa4594a2017-03-24 12:39:56 -07008815 DualTimer t = mJobStats.startObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008816 if (t != null) {
8817 t.startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07008818 // TODO(statsd): Possibly use a worksource instead of a uid.
8819 StatsLog.write(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), name, 1);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008820 }
8821 }
8822
Dianne Hackborn94326cb2017-06-28 16:17:20 -07008823 public void noteStopJobLocked(String name, long elapsedRealtimeMs, int stopReason) {
Bookatzaa4594a2017-03-24 12:39:56 -07008824 DualTimer t = mJobStats.stopObject(name);
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008825 if (t != null) {
8826 t.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07008827 if (!t.isRunningLocked()) { // only tell statsd if truly stopped
8828 // TODO(statsd): Possibly use a worksource instead of a uid.
8829 StatsLog.write(StatsLog.SCHEDULED_JOB_STATE_CHANGED, getUid(), name, 0);
8830 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008831 }
Dianne Hackborn94326cb2017-06-28 16:17:20 -07008832 if (mBsi.mOnBatteryTimeBase.isRunning()) {
8833 SparseIntArray types = mJobCompletions.get(name);
8834 if (types == null) {
8835 types = new SparseIntArray();
8836 mJobCompletions.put(name, types);
8837 }
8838 int last = types.get(stopReason, 0);
8839 types.put(stopReason, last + 1);
8840 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -07008841 }
8842
Bookatz5b5ec322017-05-26 09:40:38 -07008843 public StopwatchTimer getWakelockTimerLocked(Wakelock wl, int type) {
8844 if (wl == null) {
8845 return null;
8846 }
8847 switch (type) {
8848 case WAKE_TYPE_PARTIAL: {
8849 DualTimer t = wl.mTimerPartial;
8850 if (t == null) {
8851 t = new DualTimer(mBsi.mClocks, this, WAKE_TYPE_PARTIAL,
8852 mBsi.mPartialTimers, mBsi.mOnBatteryScreenOffTimeBase,
8853 mOnBatteryScreenOffBackgroundTimeBase);
8854 wl.mTimerPartial = t;
8855 }
8856 return t;
8857 }
8858 case WAKE_TYPE_FULL: {
8859 StopwatchTimer t = wl.mTimerFull;
8860 if (t == null) {
8861 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_FULL,
8862 mBsi.mFullTimers, mBsi.mOnBatteryTimeBase);
8863 wl.mTimerFull = t;
8864 }
8865 return t;
8866 }
8867 case WAKE_TYPE_WINDOW: {
8868 StopwatchTimer t = wl.mTimerWindow;
8869 if (t == null) {
8870 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_WINDOW,
8871 mBsi.mWindowTimers, mBsi.mOnBatteryTimeBase);
8872 wl.mTimerWindow = t;
8873 }
8874 return t;
8875 }
8876 case WAKE_TYPE_DRAW: {
8877 StopwatchTimer t = wl.mTimerDraw;
8878 if (t == null) {
8879 t = new StopwatchTimer(mBsi.mClocks, this, WAKE_TYPE_DRAW,
8880 mBsi.mDrawTimers, mBsi.mOnBatteryTimeBase);
8881 wl.mTimerDraw = t;
8882 }
8883 return t;
8884 }
8885 default:
8886 throw new IllegalArgumentException("type=" + type);
8887 }
8888 }
8889
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008890 public void noteStartWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07008891 Wakelock wl = mWakelockStats.startObject(name);
8892 if (wl != null) {
Bookatz5b5ec322017-05-26 09:40:38 -07008893 getWakelockTimerLocked(wl, type).startRunningLocked(elapsedRealtimeMs);
Bookatzd6746242017-10-24 18:39:35 -07008894 // TODO(statsd): Hopefully use a worksource instead of a uid (so move elsewhere)
8895 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, getUid(), type, name, 1);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008896 }
Bookatzc8c44962017-05-11 12:12:54 -07008897 if (type == WAKE_TYPE_PARTIAL) {
8898 createAggregatedPartialWakelockTimerLocked().startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07008899 // TODO(statsd): Possibly use a worksource instead of a uid.
8900 StatsLog.write(StatsLog.UID_WAKELOCK_STATE_CHANGED, getUid(), type, 1);
Bookatzc8c44962017-05-11 12:12:54 -07008901 if (pid >= 0) {
8902 Pid p = getPidStatsLocked(pid);
8903 if (p.mWakeNesting++ == 0) {
8904 p.mWakeStartMs = elapsedRealtimeMs;
8905 }
Dianne Hackbornb8071d792010-09-09 16:45:15 -07008906 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008907 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008908 }
8909
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008910 public void noteStopWakeLocked(int pid, String name, int type, long elapsedRealtimeMs) {
Dianne Hackbornd953c532014-08-16 18:17:38 -07008911 Wakelock wl = mWakelockStats.stopObject(name);
8912 if (wl != null) {
Bookatzd6746242017-10-24 18:39:35 -07008913 StopwatchTimer wlt = getWakelockTimerLocked(wl, type);
8914 wlt.stopRunningLocked(elapsedRealtimeMs);
8915 if (!wlt.isRunningLocked()) { // only tell statsd if truly stopped
8916 // TODO(statsd): Possibly use a worksource instead of a uid.
8917 StatsLog.write(StatsLog.WAKELOCK_STATE_CHANGED, getUid(), type, name, 0);
8918 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008919 }
Bookatzc8c44962017-05-11 12:12:54 -07008920 if (type == WAKE_TYPE_PARTIAL) {
8921 if (mAggregatedPartialWakelockTimer != null) {
8922 mAggregatedPartialWakelockTimer.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07008923 if (!mAggregatedPartialWakelockTimer.isRunningLocked()) {
8924 // TODO(statsd): Possibly use a worksource instead of a uid.
8925 StatsLog.write(StatsLog.UID_WAKELOCK_STATE_CHANGED, getUid(), type,
8926 0);
8927 }
Bookatzc8c44962017-05-11 12:12:54 -07008928 }
8929 if (pid >= 0) {
8930 Pid p = mPids.get(pid);
8931 if (p != null && p.mWakeNesting > 0) {
8932 if (p.mWakeNesting-- == 1) {
8933 p.mWakeSumMs += elapsedRealtimeMs - p.mWakeStartMs;
8934 p.mWakeStartMs = 0;
8935 }
Dianne Hackborne5167ca2014-03-08 14:39:10 -08008936 }
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07008937 }
8938 }
8939 }
8940
Dianne Hackborn287952c2010-09-22 22:34:31 -07008941 public void reportExcessiveCpuLocked(String proc, long overTime, long usedTime) {
8942 Proc p = getProcessStatsLocked(proc);
8943 if (p != null) {
8944 p.addExcessiveCpu(overTime, usedTime);
8945 }
8946 }
8947
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008948 public void noteStartSensor(int sensor, long elapsedRealtimeMs) {
Bookatz867c0d72017-03-07 18:23:42 -08008949 DualTimer t = getSensorTimerLocked(sensor, /* create= */ true);
Amith Yamasani154d1242017-02-16 10:01:48 -08008950 t.startRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07008951 // TODO(statsd): Possibly use a worksource instead of a uid.
8952 if (sensor == Sensor.GPS) {
8953 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, getUid(), 1);
8954 } else {
8955 StatsLog.write(StatsLog.SENSOR_STATE_CHANGED, getUid(), sensor, 1);
8956 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008957 }
8958
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008959 public void noteStopSensor(int sensor, long elapsedRealtimeMs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008960 // Don't create a timer if one doesn't already exist
Bookatz867c0d72017-03-07 18:23:42 -08008961 DualTimer t = getSensorTimerLocked(sensor, false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008962 if (t != null) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008963 t.stopRunningLocked(elapsedRealtimeMs);
Bookatzc1a050a2017-10-10 15:49:28 -07008964 if (!t.isRunningLocked()) { // only tell statsd if truly stopped
8965 // TODO(statsd): Possibly use a worksource instead of a uid.
8966 if (sensor == Sensor.GPS) {
8967 StatsLog.write(StatsLog.GPS_SCAN_STATE_CHANGED, getUid(), 0);
8968 } else {
8969 StatsLog.write(StatsLog.SENSOR_STATE_CHANGED, getUid(), sensor, 0);
8970 }
8971 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008972 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008973 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008974
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008975 public void noteStartGps(long elapsedRealtimeMs) {
Bookatz867c0d72017-03-07 18:23:42 -08008976 noteStartSensor(Sensor.GPS, elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008977 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07008978
Dianne Hackborn97ae5382014-03-05 16:43:25 -08008979 public void noteStopGps(long elapsedRealtimeMs) {
Bookatz867c0d72017-03-07 18:23:42 -08008980 noteStopSensor(Sensor.GPS, elapsedRealtimeMs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008981 }
8982
8983 public BatteryStatsImpl getBatteryStats() {
Joe Onoratoabded112016-02-08 16:49:39 -08008984 return mBsi;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008985 }
8986 }
8987
Sudheer Shanka9b735c52017-05-09 18:26:18 -07008988 public long[] getCpuFreqs() {
8989 return mCpuFreqs;
8990 }
8991
Suprabh Shuklae6e723d2017-06-14 16:14:43 -07008992 public BatteryStatsImpl(File systemDir, Handler handler, PlatformIdleStateCallback cb,
8993 UserInfoProvider userInfoProvider) {
8994 this(new SystemClocks(), systemDir, handler, cb, userInfoProvider);
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07008995 }
8996
Suprabh Shuklae6e723d2017-06-14 16:14:43 -07008997 private BatteryStatsImpl(Clocks clocks, File systemDir, Handler handler,
8998 PlatformIdleStateCallback cb,
8999 UserInfoProvider userInfoProvider) {
Joe Onoratoabded112016-02-08 16:49:39 -08009000 init(clocks);
9001
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009002 if (systemDir != null) {
9003 mFile = new JournaledFile(new File(systemDir, "batterystats.bin"),
9004 new File(systemDir, "batterystats.bin.tmp"));
9005 } else {
9006 mFile = null;
9007 }
9008 mCheckinFile = new AtomicFile(new File(systemDir, "batterystats-checkin.bin"));
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009009 mDailyFile = new AtomicFile(new File(systemDir, "batterystats-daily.xml"));
Jeff Brown6f357d32014-01-15 20:40:55 -08009010 mHandler = new MyHandler(handler.getLooper());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009011 mStartCount++;
Joe Onoratoabded112016-02-08 16:49:39 -08009012 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase);
Mike Mac2f518a2017-09-19 16:06:03 -07009013 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase);
Dianne Hackborn617f8772009-03-31 15:04:46 -07009014 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08009015 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009016 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009017 }
Joe Onoratoabded112016-02-08 16:49:39 -08009018 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase);
9019 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null,
9020 mOnBatteryTimeBase);
9021 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -11, null,
9022 mOnBatteryTimeBase);
9023 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase);
9024 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null, mOnBatteryTimeBase);
9025 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase);
9026 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase);
9027 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
9028 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i, null,
9029 mOnBatteryTimeBase);
9030 }
9031 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null,
9032 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009033 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08009034 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i, null,
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009035 mOnBatteryTimeBase);
Dianne Hackborn627bba72009-03-24 22:32:56 -07009036 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009037 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009038 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
9039 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009040 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009041 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase, NUM_WIFI_TX_LEVELS);
9042 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
9043 NUM_BT_TX_LEVELS);
9044 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
9045 ModemActivityInfo.TX_POWER_LEVELS);
Joe Onoratoabded112016-02-08 16:49:39 -08009046 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null, mOnBatteryTimeBase);
9047 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null,
9048 mOnBatteryTimeBase);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009049 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009050 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase);
9051 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase);
Joe Onoratoabded112016-02-08 16:49:39 -08009052 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase);
9053 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null, mOnBatteryTimeBase);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009054 for (int i=0; i<NUM_WIFI_STATES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -08009055 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i, null,
Dianne Hackborn3251b902014-06-20 14:40:53 -07009056 mOnBatteryTimeBase);
9057 }
Joe Onoratoabded112016-02-08 16:49:39 -08009058 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9059 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i, null,
9060 mOnBatteryTimeBase);
9061 }
9062 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9063 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i, null,
9064 mOnBatteryTimeBase);
9065 }
9066 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase);
9067 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase);
9068 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase);
9069 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase);
9070 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase);
Adam Lesinski3ee3f632016-06-08 13:55:55 -07009071 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase);
Mike Mac2f518a2017-09-19 16:06:03 -07009072 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
Adam Lesinski3ee3f632016-06-08 13:55:55 -07009073 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009074 mOnBattery = mOnBatteryInternal = false;
Joe Onoratoabded112016-02-08 16:49:39 -08009075 long uptime = mClocks.uptimeMillis() * 1000;
9076 long realtime = mClocks.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009077 initTimes(uptime, realtime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -07009078 mStartPlatformVersion = mEndPlatformVersion = Build.ID;
Evan Millar633a1742009-04-02 16:36:33 -07009079 mDischargeStartLevel = 0;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009080 mDischargeUnplugLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009081 mDischargePlugLevel = -1;
Evan Millar633a1742009-04-02 16:36:33 -07009082 mDischargeCurrentLevel = 0;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009083 mCurrentBatteryLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009084 initDischarge();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009085 clearHistoryLocked();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009086 updateDailyDeadlineLocked();
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07009087 mPlatformIdleStateCallback = cb;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -07009088 mUserInfoProvider = userInfoProvider;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009089 }
9090
9091 public BatteryStatsImpl(Parcel p) {
Joe Onoratoabded112016-02-08 16:49:39 -08009092 this(new SystemClocks(), p);
9093 }
9094
9095 public BatteryStatsImpl(Clocks clocks, Parcel p) {
9096 init(clocks);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -07009097 mFile = null;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009098 mCheckinFile = null;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009099 mDailyFile = null;
Dianne Hackborn0d903a82010-09-07 23:51:03 -07009100 mHandler = null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009101 mExternalSync = null;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009102 clearHistoryLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009103 readFromParcel(p);
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -07009104 mPlatformIdleStateCallback = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009105 }
9106
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009107 public void setPowerProfileLocked(PowerProfile profile) {
9108 mPowerProfile = profile;
Adam Lesinski6832f392015-09-05 18:05:40 -07009109
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009110 // We need to initialize the KernelCpuSpeedReaders to read from
9111 // the first cpu of each core. Once we have the PowerProfile, we have access to this
9112 // information.
9113 final int numClusters = mPowerProfile.getNumCpuClusters();
9114 mKernelCpuSpeedReaders = new KernelCpuSpeedReader[numClusters];
9115 int firstCpuOfCluster = 0;
9116 for (int i = 0; i < numClusters; i++) {
9117 final int numSpeedSteps = mPowerProfile.getNumSpeedStepsInCpuCluster(i);
9118 mKernelCpuSpeedReaders[i] = new KernelCpuSpeedReader(firstCpuOfCluster,
9119 numSpeedSteps);
9120 firstCpuOfCluster += mPowerProfile.getNumCoresInCpuCluster(i);
9121 }
Adam Lesinskif9b20a92016-06-17 17:30:01 -07009122
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009123 if (mEstimatedBatteryCapacity == -1) {
9124 // Initialize the estimated battery capacity to a known preset one.
9125 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity();
Adam Lesinskie08af192015-03-25 16:42:59 -07009126 }
9127 }
9128
Dianne Hackborn0d903a82010-09-07 23:51:03 -07009129 public void setCallback(BatteryCallback cb) {
9130 mCallback = cb;
9131 }
9132
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009133 public void setRadioScanningTimeoutLocked(long timeout) {
Amith Yamasanif37447b2009-10-08 18:28:01 -07009134 if (mPhoneSignalScanningTimer != null) {
9135 mPhoneSignalScanningTimer.setTimeout(timeout);
9136 }
9137 }
9138
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07009139 public void setExternalStatsSyncLocked(ExternalStatsSync sync) {
9140 mExternalSync = sync;
9141 }
9142
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009143 public void updateDailyDeadlineLocked() {
9144 // Get the current time.
9145 long currentTime = mDailyStartTime = System.currentTimeMillis();
9146 Calendar calDeadline = Calendar.getInstance();
9147 calDeadline.setTimeInMillis(currentTime);
9148
9149 // Move time up to the next day, ranging from 1am to 3pm.
9150 calDeadline.set(Calendar.DAY_OF_YEAR, calDeadline.get(Calendar.DAY_OF_YEAR) + 1);
9151 calDeadline.set(Calendar.MILLISECOND, 0);
9152 calDeadline.set(Calendar.SECOND, 0);
9153 calDeadline.set(Calendar.MINUTE, 0);
9154 calDeadline.set(Calendar.HOUR_OF_DAY, 1);
9155 mNextMinDailyDeadline = calDeadline.getTimeInMillis();
9156 calDeadline.set(Calendar.HOUR_OF_DAY, 3);
9157 mNextMaxDailyDeadline = calDeadline.getTimeInMillis();
9158 }
9159
9160 public void recordDailyStatsIfNeededLocked(boolean settled) {
9161 long currentTime = System.currentTimeMillis();
9162 if (currentTime >= mNextMaxDailyDeadline) {
9163 recordDailyStatsLocked();
9164 } else if (settled && currentTime >= mNextMinDailyDeadline) {
9165 recordDailyStatsLocked();
9166 } else if (currentTime < (mDailyStartTime-(1000*60*60*24))) {
9167 recordDailyStatsLocked();
9168 }
9169 }
9170
9171 public void recordDailyStatsLocked() {
9172 DailyItem item = new DailyItem();
9173 item.mStartTime = mDailyStartTime;
9174 item.mEndTime = System.currentTimeMillis();
9175 boolean hasData = false;
9176 if (mDailyDischargeStepTracker.mNumStepDurations > 0) {
9177 hasData = true;
9178 item.mDischargeSteps = new LevelStepTracker(
9179 mDailyDischargeStepTracker.mNumStepDurations,
9180 mDailyDischargeStepTracker.mStepDurations);
9181 }
9182 if (mDailyChargeStepTracker.mNumStepDurations > 0) {
9183 hasData = true;
9184 item.mChargeSteps = new LevelStepTracker(
9185 mDailyChargeStepTracker.mNumStepDurations,
9186 mDailyChargeStepTracker.mStepDurations);
9187 }
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009188 if (mDailyPackageChanges != null) {
9189 hasData = true;
9190 item.mPackageChanges = mDailyPackageChanges;
9191 mDailyPackageChanges = null;
9192 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009193 mDailyDischargeStepTracker.init();
9194 mDailyChargeStepTracker.init();
9195 updateDailyDeadlineLocked();
9196
9197 if (hasData) {
9198 mDailyItems.add(item);
9199 while (mDailyItems.size() > MAX_DAILY_ITEMS) {
9200 mDailyItems.remove(0);
9201 }
9202 final ByteArrayOutputStream memStream = new ByteArrayOutputStream();
9203 try {
9204 XmlSerializer out = new FastXmlSerializer();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01009205 out.setOutput(memStream, StandardCharsets.UTF_8.name());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009206 writeDailyItemsLocked(out);
9207 BackgroundThread.getHandler().post(new Runnable() {
9208 @Override
9209 public void run() {
9210 synchronized (mCheckinFile) {
9211 FileOutputStream stream = null;
9212 try {
9213 stream = mDailyFile.startWrite();
9214 memStream.writeTo(stream);
9215 stream.flush();
9216 FileUtils.sync(stream);
9217 stream.close();
9218 mDailyFile.finishWrite(stream);
9219 } catch (IOException e) {
9220 Slog.w("BatteryStats",
9221 "Error writing battery daily items", e);
9222 mDailyFile.failWrite(stream);
9223 }
9224 }
9225 }
9226 });
9227 } catch (IOException e) {
9228 }
9229 }
9230 }
9231
9232 private void writeDailyItemsLocked(XmlSerializer out) throws IOException {
9233 StringBuilder sb = new StringBuilder(64);
9234 out.startDocument(null, true);
9235 out.startTag(null, "daily-items");
9236 for (int i=0; i<mDailyItems.size(); i++) {
9237 final DailyItem dit = mDailyItems.get(i);
9238 out.startTag(null, "item");
9239 out.attribute(null, "start", Long.toString(dit.mStartTime));
9240 out.attribute(null, "end", Long.toString(dit.mEndTime));
9241 writeDailyLevelSteps(out, "dis", dit.mDischargeSteps, sb);
9242 writeDailyLevelSteps(out, "chg", dit.mChargeSteps, sb);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009243 if (dit.mPackageChanges != null) {
9244 for (int j=0; j<dit.mPackageChanges.size(); j++) {
9245 PackageChange pc = dit.mPackageChanges.get(j);
9246 if (pc.mUpdate) {
9247 out.startTag(null, "upd");
9248 out.attribute(null, "pkg", pc.mPackageName);
9249 out.attribute(null, "ver", Integer.toString(pc.mVersionCode));
9250 out.endTag(null, "upd");
9251 } else {
9252 out.startTag(null, "rem");
9253 out.attribute(null, "pkg", pc.mPackageName);
9254 out.endTag(null, "rem");
9255 }
9256 }
9257 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009258 out.endTag(null, "item");
9259 }
9260 out.endTag(null, "daily-items");
9261 out.endDocument();
9262 }
9263
9264 private void writeDailyLevelSteps(XmlSerializer out, String tag, LevelStepTracker steps,
9265 StringBuilder tmpBuilder) throws IOException {
9266 if (steps != null) {
9267 out.startTag(null, tag);
9268 out.attribute(null, "n", Integer.toString(steps.mNumStepDurations));
9269 for (int i=0; i<steps.mNumStepDurations; i++) {
9270 out.startTag(null, "s");
9271 tmpBuilder.setLength(0);
9272 steps.encodeEntryAt(i, tmpBuilder);
9273 out.attribute(null, "v", tmpBuilder.toString());
9274 out.endTag(null, "s");
9275 }
9276 out.endTag(null, tag);
9277 }
9278 }
9279
9280 public void readDailyStatsLocked() {
9281 Slog.d(TAG, "Reading daily items from " + mDailyFile.getBaseFile());
9282 mDailyItems.clear();
9283 FileInputStream stream;
9284 try {
9285 stream = mDailyFile.openRead();
9286 } catch (FileNotFoundException e) {
9287 return;
9288 }
9289 try {
9290 XmlPullParser parser = Xml.newPullParser();
Wojciech Staszkiewicz9e9e2e72015-05-08 14:58:46 +01009291 parser.setInput(stream, StandardCharsets.UTF_8.name());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009292 readDailyItemsLocked(parser);
9293 } catch (XmlPullParserException e) {
9294 } finally {
9295 try {
9296 stream.close();
9297 } catch (IOException e) {
9298 }
9299 }
9300 }
9301
9302 private void readDailyItemsLocked(XmlPullParser parser) {
9303 try {
9304 int type;
9305 while ((type = parser.next()) != XmlPullParser.START_TAG
9306 && type != XmlPullParser.END_DOCUMENT) {
9307 ;
9308 }
9309
9310 if (type != XmlPullParser.START_TAG) {
9311 throw new IllegalStateException("no start tag found");
9312 }
9313
9314 int outerDepth = parser.getDepth();
9315 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
9316 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
9317 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
9318 continue;
9319 }
9320
9321 String tagName = parser.getName();
9322 if (tagName.equals("item")) {
9323 readDailyItemTagLocked(parser);
9324 } else {
9325 Slog.w(TAG, "Unknown element under <daily-items>: "
9326 + parser.getName());
9327 XmlUtils.skipCurrentTag(parser);
9328 }
9329 }
9330
9331 } catch (IllegalStateException e) {
9332 Slog.w(TAG, "Failed parsing daily " + e);
9333 } catch (NullPointerException e) {
9334 Slog.w(TAG, "Failed parsing daily " + e);
9335 } catch (NumberFormatException e) {
9336 Slog.w(TAG, "Failed parsing daily " + e);
9337 } catch (XmlPullParserException e) {
9338 Slog.w(TAG, "Failed parsing daily " + e);
9339 } catch (IOException e) {
9340 Slog.w(TAG, "Failed parsing daily " + e);
9341 } catch (IndexOutOfBoundsException e) {
9342 Slog.w(TAG, "Failed parsing daily " + e);
9343 }
9344 }
9345
9346 void readDailyItemTagLocked(XmlPullParser parser) throws NumberFormatException,
9347 XmlPullParserException, IOException {
9348 DailyItem dit = new DailyItem();
9349 String attr = parser.getAttributeValue(null, "start");
9350 if (attr != null) {
9351 dit.mStartTime = Long.parseLong(attr);
9352 }
9353 attr = parser.getAttributeValue(null, "end");
9354 if (attr != null) {
9355 dit.mEndTime = Long.parseLong(attr);
9356 }
9357 int outerDepth = parser.getDepth();
9358 int type;
9359 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
9360 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
9361 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
9362 continue;
9363 }
9364
9365 String tagName = parser.getName();
9366 if (tagName.equals("dis")) {
9367 readDailyItemTagDetailsLocked(parser, dit, false, "dis");
9368 } else if (tagName.equals("chg")) {
9369 readDailyItemTagDetailsLocked(parser, dit, true, "chg");
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009370 } else if (tagName.equals("upd")) {
9371 if (dit.mPackageChanges == null) {
9372 dit.mPackageChanges = new ArrayList<>();
9373 }
9374 PackageChange pc = new PackageChange();
9375 pc.mUpdate = true;
9376 pc.mPackageName = parser.getAttributeValue(null, "pkg");
9377 String verStr = parser.getAttributeValue(null, "ver");
9378 pc.mVersionCode = verStr != null ? Integer.parseInt(verStr) : 0;
9379 dit.mPackageChanges.add(pc);
9380 XmlUtils.skipCurrentTag(parser);
9381 } else if (tagName.equals("rem")) {
9382 if (dit.mPackageChanges == null) {
9383 dit.mPackageChanges = new ArrayList<>();
9384 }
9385 PackageChange pc = new PackageChange();
9386 pc.mUpdate = false;
9387 pc.mPackageName = parser.getAttributeValue(null, "pkg");
9388 dit.mPackageChanges.add(pc);
9389 XmlUtils.skipCurrentTag(parser);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009390 } else {
9391 Slog.w(TAG, "Unknown element under <item>: "
9392 + parser.getName());
9393 XmlUtils.skipCurrentTag(parser);
9394 }
9395 }
9396 mDailyItems.add(dit);
9397 }
9398
9399 void readDailyItemTagDetailsLocked(XmlPullParser parser, DailyItem dit, boolean isCharge,
9400 String tag)
9401 throws NumberFormatException, XmlPullParserException, IOException {
9402 final String numAttr = parser.getAttributeValue(null, "n");
9403 if (numAttr == null) {
9404 Slog.w(TAG, "Missing 'n' attribute at " + parser.getPositionDescription());
9405 XmlUtils.skipCurrentTag(parser);
9406 return;
9407 }
9408 final int num = Integer.parseInt(numAttr);
9409 LevelStepTracker steps = new LevelStepTracker(num);
9410 if (isCharge) {
9411 dit.mChargeSteps = steps;
9412 } else {
9413 dit.mDischargeSteps = steps;
9414 }
9415 int i = 0;
9416 int outerDepth = parser.getDepth();
9417 int type;
9418 while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
9419 && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
9420 if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
9421 continue;
9422 }
9423
9424 String tagName = parser.getName();
9425 if ("s".equals(tagName)) {
9426 if (i < num) {
9427 String valueAttr = parser.getAttributeValue(null, "v");
9428 if (valueAttr != null) {
9429 steps.decodeEntryAt(i, valueAttr);
9430 i++;
9431 }
9432 }
9433 } else {
9434 Slog.w(TAG, "Unknown element under <" + tag + ">: "
9435 + parser.getName());
9436 XmlUtils.skipCurrentTag(parser);
9437 }
9438 }
9439 steps.mNumStepDurations = i;
9440 }
9441
9442 @Override
9443 public DailyItem getDailyItemLocked(int daysAgo) {
9444 int index = mDailyItems.size()-1-daysAgo;
9445 return index >= 0 ? mDailyItems.get(index) : null;
9446 }
9447
9448 @Override
9449 public long getCurrentDailyStartTime() {
9450 return mDailyStartTime;
9451 }
9452
9453 @Override
9454 public long getNextMinDailyDeadline() {
9455 return mNextMinDailyDeadline;
9456 }
9457
9458 @Override
9459 public long getNextMaxDailyDeadline() {
9460 return mNextMaxDailyDeadline;
9461 }
9462
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009463 @Override
9464 public boolean startIteratingOldHistoryLocked() {
9465 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
9466 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009467 if ((mHistoryIterator = mHistory) == null) {
9468 return false;
9469 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009470 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07009471 mHistoryReadTmp.clear();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009472 mReadOverflow = false;
9473 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009474 return true;
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009475 }
9476
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009477 @Override
9478 public boolean getNextOldHistoryLocked(HistoryItem out) {
9479 boolean end = mHistoryBuffer.dataPosition() >= mHistoryBuffer.dataSize();
9480 if (!end) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009481 readHistoryDelta(mHistoryBuffer, mHistoryReadTmp);
Dianne Hackborn1fadab52011-04-14 17:57:33 -07009482 mReadOverflow |= mHistoryReadTmp.cmd == HistoryItem.CMD_OVERFLOW;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009483 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009484 HistoryItem cur = mHistoryIterator;
9485 if (cur == null) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009486 if (!mReadOverflow && !end) {
9487 Slog.w(TAG, "Old history ends before new history!");
9488 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009489 return false;
9490 }
9491 out.setTo(cur);
9492 mHistoryIterator = cur.next;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009493 if (!mReadOverflow) {
9494 if (end) {
9495 Slog.w(TAG, "New history ends before old history!");
Dianne Hackborn1fadab52011-04-14 17:57:33 -07009496 } else if (!out.same(mHistoryReadTmp)) {
Dianne Hackborn8c841092013-06-24 13:46:13 -07009497 PrintWriter pw = new FastPrintWriter(new LogWriter(android.util.Log.WARN, TAG));
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009498 pw.println("Histories differ!");
9499 pw.println("Old history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07009500 (new HistoryPrinter()).printNextItem(pw, out, 0, false, true);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009501 pw.println("New history:");
Dianne Hackborn99009ea2014-04-18 16:23:42 -07009502 (new HistoryPrinter()).printNextItem(pw, mHistoryReadTmp, 0, false,
9503 true);
Dianne Hackborn8c841092013-06-24 13:46:13 -07009504 pw.flush();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009505 }
9506 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -07009507 return true;
9508 }
9509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009510 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009511 public void finishIteratingOldHistoryLocked() {
9512 mIteratingHistory = false;
9513 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009514 mHistoryIterator = null;
9515 }
9516
9517 public int getHistoryTotalSize() {
9518 return MAX_HISTORY_BUFFER;
9519 }
9520
9521 public int getHistoryUsedSize() {
9522 return mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009523 }
9524
9525 @Override
9526 public boolean startIteratingHistoryLocked() {
9527 if (DEBUG_HISTORY) Slog.i(TAG, "ITERATING: buff size=" + mHistoryBuffer.dataSize()
9528 + " pos=" + mHistoryBuffer.dataPosition());
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009529 if (mHistoryBuffer.dataSize() <= 0) {
9530 return false;
9531 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009532 mHistoryBuffer.setDataPosition(0);
9533 mReadOverflow = false;
9534 mIteratingHistory = true;
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009535 mReadHistoryStrings = new String[mHistoryTagPool.size()];
9536 mReadHistoryUids = new int[mHistoryTagPool.size()];
9537 mReadHistoryChars = 0;
9538 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
9539 final HistoryTag tag = ent.getKey();
9540 final int idx = ent.getValue();
9541 mReadHistoryStrings[idx] = tag.string;
9542 mReadHistoryUids[idx] = tag.uid;
9543 mReadHistoryChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -08009544 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009545 return true;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009546 }
9547
9548 @Override
Dianne Hackborn099bc622014-01-22 13:39:16 -08009549 public int getHistoryStringPoolSize() {
9550 return mReadHistoryStrings.length;
9551 }
9552
9553 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009554 public int getHistoryStringPoolBytes() {
9555 // Each entry is a fixed 12 bytes: 4 for index, 4 for uid, 4 for string size
9556 // Each string character is 2 bytes.
9557 return (mReadHistoryStrings.length * 12) + (mReadHistoryChars * 2);
9558 }
9559
9560 @Override
9561 public String getHistoryTagPoolString(int index) {
Dianne Hackborn099bc622014-01-22 13:39:16 -08009562 return mReadHistoryStrings[index];
9563 }
9564
9565 @Override
Dianne Hackborn71fc13e2014-02-03 10:50:53 -08009566 public int getHistoryTagPoolUid(int index) {
9567 return mReadHistoryUids[index];
9568 }
9569
9570 @Override
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009571 public boolean getNextHistoryLocked(HistoryItem out) {
Dianne Hackborn1fadab52011-04-14 17:57:33 -07009572 final int pos = mHistoryBuffer.dataPosition();
9573 if (pos == 0) {
9574 out.clear();
9575 }
9576 boolean end = pos >= mHistoryBuffer.dataSize();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009577 if (end) {
9578 return false;
9579 }
9580
Dianne Hackborn99009ea2014-04-18 16:23:42 -07009581 final long lastRealtime = out.time;
9582 final long lastWalltime = out.currentTime;
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009583 readHistoryDelta(mHistoryBuffer, out);
Dianne Hackborn37de0982014-05-09 09:32:18 -07009584 if (out.cmd != HistoryItem.CMD_CURRENT_TIME
9585 && out.cmd != HistoryItem.CMD_RESET && lastWalltime != 0) {
Dianne Hackborn99009ea2014-04-18 16:23:42 -07009586 out.currentTime = lastWalltime + (out.time - lastRealtime);
9587 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07009588 return true;
9589 }
9590
9591 @Override
9592 public void finishIteratingHistoryLocked() {
9593 mIteratingHistory = false;
9594 mHistoryBuffer.setDataPosition(mHistoryBuffer.dataSize());
Dianne Hackborn099bc622014-01-22 13:39:16 -08009595 mReadHistoryStrings = null;
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009596 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009597
Dianne Hackborn32907cf2010-06-10 17:50:20 -07009598 @Override
Dianne Hackbornb5e31652010-09-07 12:13:55 -07009599 public long getHistoryBaseTime() {
9600 return mHistoryBaseTime;
9601 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009602
Dianne Hackbornb5e31652010-09-07 12:13:55 -07009603 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08009604 public int getStartCount() {
9605 return mStartCount;
9606 }
9607
9608 public boolean isOnBattery() {
9609 return mOnBattery;
9610 }
9611
Dianne Hackborn4870e9d2015-04-08 16:55:47 -07009612 public boolean isCharging() {
9613 return mCharging;
9614 }
9615
Mike Mac2f518a2017-09-19 16:06:03 -07009616 public boolean isScreenOn(int state) {
Chris Phoenix10a4a642017-09-25 13:21:00 -07009617 return state == Display.STATE_ON || state == Display.STATE_VR
9618 || state == Display.STATE_ON_SUSPEND;
Mike Mac2f518a2017-09-19 16:06:03 -07009619 }
9620
9621 public boolean isScreenOff(int state) {
9622 return state == Display.STATE_OFF;
9623 }
9624
9625 public boolean isScreenDoze(int state) {
9626 return state == Display.STATE_DOZE || state == Display.STATE_DOZE_SUSPEND;
Dianne Hackborn9adb9c32010-08-13 14:09:56 -07009627 }
9628
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009629 void initTimes(long uptime, long realtime) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -08009630 mStartClockTime = System.currentTimeMillis();
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009631 mOnBatteryTimeBase.init(uptime, realtime);
9632 mOnBatteryScreenOffTimeBase.init(uptime, realtime);
Dianne Hackborn4590e522014-03-24 13:36:46 -07009633 mRealtime = 0;
9634 mUptime = 0;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009635 mRealtimeStart = realtime;
Dianne Hackborn4590e522014-03-24 13:36:46 -07009636 mUptimeStart = uptime;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009637 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009638
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009639 void initDischarge() {
9640 mLowDischargeAmountSinceCharge = 0;
9641 mHighDischargeAmountSinceCharge = 0;
9642 mDischargeAmountScreenOn = 0;
9643 mDischargeAmountScreenOnSinceCharge = 0;
9644 mDischargeAmountScreenOff = 0;
9645 mDischargeAmountScreenOffSinceCharge = 0;
Mike Mac2f518a2017-09-19 16:06:03 -07009646 mDischargeAmountScreenDoze = 0;
9647 mDischargeAmountScreenDozeSinceCharge = 0;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08009648 mDischargeStepTracker.init();
9649 mChargeStepTracker.init();
Adam Lesinski3ee3f632016-06-08 13:55:55 -07009650 mDischargeScreenOffCounter.reset(false);
Mike Mac2f518a2017-09-19 16:06:03 -07009651 mDischargeScreenDozeCounter.reset(false);
Adam Lesinski3ee3f632016-06-08 13:55:55 -07009652 mDischargeCounter.reset(false);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009653 }
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009654
9655 public void resetAllStatsCmdLocked() {
9656 resetAllStatsLocked();
Joe Onoratoabded112016-02-08 16:49:39 -08009657 final long mSecUptime = mClocks.uptimeMillis();
Dianne Hackborn40c87252014-03-19 16:55:40 -07009658 long uptime = mSecUptime * 1000;
Joe Onoratoabded112016-02-08 16:49:39 -08009659 long mSecRealtime = mClocks.elapsedRealtime();
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009660 long realtime = mSecRealtime * 1000;
9661 mDischargeStartLevel = mHistoryCur.batteryLevel;
9662 pullPendingStateUpdatesLocked();
Dianne Hackborn40c87252014-03-19 16:55:40 -07009663 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -07009664 mDischargeCurrentLevel = mDischargeUnplugLevel = mDischargePlugLevel
9665 = mCurrentBatteryLevel = mHistoryCur.batteryLevel;
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009666 mOnBatteryTimeBase.reset(uptime, realtime);
9667 mOnBatteryScreenOffTimeBase.reset(uptime, realtime);
9668 if ((mHistoryCur.states&HistoryItem.STATE_BATTERY_PLUGGED_FLAG) == 0) {
Mike Mac2f518a2017-09-19 16:06:03 -07009669 if (isScreenOn(mScreenState)) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009670 mDischargeScreenOnUnplugLevel = mHistoryCur.batteryLevel;
Mike Mac2f518a2017-09-19 16:06:03 -07009671 mDischargeScreenDozeUnplugLevel = 0;
9672 mDischargeScreenOffUnplugLevel = 0;
9673 } else if (isScreenDoze(mScreenState)) {
9674 mDischargeScreenOnUnplugLevel = 0;
9675 mDischargeScreenDozeUnplugLevel = mHistoryCur.batteryLevel;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009676 mDischargeScreenOffUnplugLevel = 0;
9677 } else {
9678 mDischargeScreenOnUnplugLevel = 0;
Mike Mac2f518a2017-09-19 16:06:03 -07009679 mDischargeScreenDozeUnplugLevel = 0;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009680 mDischargeScreenOffUnplugLevel = mHistoryCur.batteryLevel;
9681 }
9682 mDischargeAmountScreenOn = 0;
9683 mDischargeAmountScreenOff = 0;
Mike Mac2f518a2017-09-19 16:06:03 -07009684 mDischargeAmountScreenDoze = 0;
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009685 }
Dianne Hackborn40c87252014-03-19 16:55:40 -07009686 initActiveHistoryEventsLocked(mSecRealtime, mSecUptime);
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08009687 }
9688
9689 private void resetAllStatsLocked() {
Adam Lesinski8ce36942016-05-26 16:05:35 -07009690 final long uptimeMillis = mClocks.uptimeMillis();
9691 final long elapsedRealtimeMillis = mClocks.elapsedRealtime();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009692 mStartCount = 0;
Adam Lesinski8ce36942016-05-26 16:05:35 -07009693 initTimes(uptimeMillis * 1000, elapsedRealtimeMillis * 1000);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009694 mScreenOnTimer.reset(false);
Mike Mac2f518a2017-09-19 16:06:03 -07009695 mScreenDozeTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009696 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009697 mScreenBrightnessTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009698 }
Adam Lesinski1a76a622016-06-22 10:28:47 -07009699
9700 if (mPowerProfile != null) {
9701 mEstimatedBatteryCapacity = (int) mPowerProfile.getBatteryCapacity();
9702 } else {
9703 mEstimatedBatteryCapacity = -1;
9704 }
Jocelyn Dangc627d102017-04-14 13:15:14 -07009705 mMinLearnedBatteryCapacity = -1;
9706 mMaxLearnedBatteryCapacity = -1;
Jeff Browne95c3cd2014-05-02 16:59:26 -07009707 mInteractiveTimer.reset(false);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07009708 mPowerSaveModeEnabledTimer.reset(false);
Adam Lesinski8ce36942016-05-26 16:05:35 -07009709 mLastIdleTimeStart = elapsedRealtimeMillis;
Dianne Hackborn08c47a52015-10-15 12:38:14 -07009710 mLongestLightIdleTime = 0;
9711 mLongestFullIdleTime = 0;
9712 mDeviceIdleModeLightTimer.reset(false);
9713 mDeviceIdleModeFullTimer.reset(false);
9714 mDeviceLightIdlingTimer.reset(false);
Dianne Hackborn88e98df2015-03-23 13:29:14 -07009715 mDeviceIdlingTimer.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009716 mPhoneOnTimer.reset(false);
9717 mAudioOnTimer.reset(false);
9718 mVideoOnTimer.reset(false);
Dianne Hackbornabc7c492014-06-30 16:57:46 -07009719 mFlashlightOnTimer.reset(false);
Ruben Brunk6d2c3632015-05-26 17:32:16 -07009720 mCameraOnTimer.reset(false);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08009721 mBluetoothScanTimer.reset(false);
Wink Saville52840902011-02-18 12:40:47 -08009722 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009723 mPhoneSignalStrengthsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009724 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009725 mPhoneSignalScanningTimer.reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009726 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009727 mPhoneDataConnectionsTimer[i].reset(false);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009728 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009729 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -08009730 mNetworkByteActivityCounters[i].reset(false);
9731 mNetworkPacketActivityCounters[i].reset(false);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07009732 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009733 mMobileRadioActiveTimer.reset(false);
9734 mMobileRadioActivePerAppTimer.reset(false);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009735 mMobileRadioActiveAdjustedTime.reset(false);
Dianne Hackbornd45665b2014-02-26 12:35:32 -08009736 mMobileRadioActiveUnknownTime.reset(false);
9737 mMobileRadioActiveUnknownCount.reset(false);
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009738 mWifiOnTimer.reset(false);
9739 mGlobalWifiRunningTimer.reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009740 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009741 mWifiStateTimer[i].reset(false);
Dianne Hackbornca1bf212014-02-14 14:18:36 -08009742 }
Dianne Hackborn3251b902014-06-20 14:40:53 -07009743 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
9744 mWifiSupplStateTimer[i].reset(false);
9745 }
9746 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
9747 mWifiSignalStrengthsTimer[i].reset(false);
9748 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -08009749 mWifiActivity.reset(false);
9750 mBluetoothActivity.reset(false);
9751 mModemActivity.reset(false);
Dianne Hackborn1e01d162014-12-04 17:46:42 -08009752 mNumConnectivityChange = mLoadedNumConnectivityChange = mUnpluggedNumConnectivityChange = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009753
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009754 for (int i=0; i<mUidStats.size(); i++) {
Bookatz993a0be2017-07-21 09:03:23 -07009755 if (mUidStats.valueAt(i).reset(uptimeMillis * 1000, elapsedRealtimeMillis * 1000)) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009756 mUidStats.remove(mUidStats.keyAt(i));
9757 i--;
9758 }
9759 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009760
Bookatz50df7112017-08-04 14:53:26 -07009761 if (mRpmStats.size() > 0) {
9762 for (SamplingTimer timer : mRpmStats.values()) {
9763 mOnBatteryTimeBase.remove(timer);
9764 }
9765 mRpmStats.clear();
9766 }
9767 if (mScreenOffRpmStats.size() > 0) {
9768 for (SamplingTimer timer : mScreenOffRpmStats.values()) {
9769 mOnBatteryScreenOffTimeBase.remove(timer);
9770 }
9771 mScreenOffRpmStats.clear();
9772 }
9773
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009774 if (mKernelWakelockStats.size() > 0) {
9775 for (SamplingTimer timer : mKernelWakelockStats.values()) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -08009776 mOnBatteryScreenOffTimeBase.remove(timer);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009777 }
9778 mKernelWakelockStats.clear();
9779 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009780
James Carr3a226052016-07-01 14:49:52 -07009781 if (mKernelMemoryStats.size() > 0) {
9782 for (int i = 0; i < mKernelMemoryStats.size(); i++) {
9783 mOnBatteryTimeBase.remove(mKernelMemoryStats.valueAt(i));
9784 }
9785 mKernelMemoryStats.clear();
9786 }
9787
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009788 if (mWakeupReasonStats.size() > 0) {
Dianne Hackbornc3940bc2014-09-05 15:50:25 -07009789 for (SamplingTimer timer : mWakeupReasonStats.values()) {
9790 mOnBatteryTimeBase.remove(timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -07009791 }
9792 mWakeupReasonStats.clear();
9793 }
9794
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -08009795 mLastHistoryStepDetails = null;
9796 mLastStepCpuUserTime = mLastStepCpuSystemTime = 0;
9797 mCurStepCpuUserTime = mCurStepCpuSystemTime = 0;
9798 mLastStepCpuUserTime = mCurStepCpuUserTime = 0;
9799 mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0;
9800 mLastStepStatUserTime = mCurStepStatUserTime = 0;
9801 mLastStepStatSystemTime = mCurStepStatSystemTime = 0;
9802 mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0;
9803 mLastStepStatIrqTime = mCurStepStatIrqTime = 0;
9804 mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0;
9805 mLastStepStatIdleTime = mCurStepStatIdleTime = 0;
9806
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009807 initDischarge();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009808
Dianne Hackborn6b7b4842010-06-14 17:17:44 -07009809 clearHistoryLocked();
9810 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -07009811
Dianne Hackborn40c87252014-03-19 16:55:40 -07009812 private void initActiveHistoryEventsLocked(long elapsedRealtimeMs, long uptimeMs) {
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08009813 for (int i=0; i<HistoryItem.EVENT_COUNT; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07009814 if (!mRecordAllHistory && i == HistoryItem.EVENT_PROC) {
9815 // Not recording process starts/stops.
9816 continue;
9817 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07009818 HashMap<String, SparseIntArray> active = mActiveEvents.getStateForEvent(i);
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08009819 if (active == null) {
9820 continue;
9821 }
Dianne Hackborn37de0982014-05-09 09:32:18 -07009822 for (HashMap.Entry<String, SparseIntArray> ent : active.entrySet()) {
9823 SparseIntArray uids = ent.getValue();
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08009824 for (int j=0; j<uids.size(); j++) {
Dianne Hackborn37de0982014-05-09 09:32:18 -07009825 addHistoryEventLocked(elapsedRealtimeMs, uptimeMs, i, ent.getKey(),
9826 uids.keyAt(j));
Dianne Hackborneaf2ac42014-02-07 13:01:07 -08009827 }
9828 }
9829 }
9830 }
9831
Mike Mac2f518a2017-09-19 16:06:03 -07009832 void updateDischargeScreenLevelsLocked(int oldState, int newState) {
9833 updateOldDischargeScreenLevelLocked(oldState);
9834 updateNewDischargeScreenLevelLocked(newState);
9835 }
9836
9837 private void updateOldDischargeScreenLevelLocked(int state) {
9838 if (isScreenOn(state)) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009839 int diff = mDischargeScreenOnUnplugLevel - mDischargeCurrentLevel;
9840 if (diff > 0) {
9841 mDischargeAmountScreenOn += diff;
9842 mDischargeAmountScreenOnSinceCharge += diff;
9843 }
Mike Mac2f518a2017-09-19 16:06:03 -07009844 } else if (isScreenDoze(state)) {
9845 int diff = mDischargeScreenDozeUnplugLevel - mDischargeCurrentLevel;
9846 if (diff > 0) {
9847 mDischargeAmountScreenDoze += diff;
9848 mDischargeAmountScreenDozeSinceCharge += diff;
9849 }
9850 } else if (isScreenOff(state)){
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009851 int diff = mDischargeScreenOffUnplugLevel - mDischargeCurrentLevel;
9852 if (diff > 0) {
9853 mDischargeAmountScreenOff += diff;
9854 mDischargeAmountScreenOffSinceCharge += diff;
9855 }
9856 }
Mike Mac2f518a2017-09-19 16:06:03 -07009857 }
9858
9859 private void updateNewDischargeScreenLevelLocked(int state) {
9860 if (isScreenOn(state)) {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009861 mDischargeScreenOnUnplugLevel = mDischargeCurrentLevel;
9862 mDischargeScreenOffUnplugLevel = 0;
Mike Mac2f518a2017-09-19 16:06:03 -07009863 mDischargeScreenDozeUnplugLevel = 0;
9864 } else if (isScreenDoze(state)){
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009865 mDischargeScreenOnUnplugLevel = 0;
Mike Mac2f518a2017-09-19 16:06:03 -07009866 mDischargeScreenDozeUnplugLevel = mDischargeCurrentLevel;
9867 mDischargeScreenOffUnplugLevel = 0;
9868 } else if (isScreenOff(state)) {
9869 mDischargeScreenOnUnplugLevel = 0;
9870 mDischargeScreenDozeUnplugLevel = 0;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -08009871 mDischargeScreenOffUnplugLevel = mDischargeCurrentLevel;
9872 }
9873 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009874
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009875 public void pullPendingStateUpdatesLocked() {
Dianne Hackborn77b987f2014-02-26 16:20:52 -08009876 if (mOnBatteryInternal) {
Mike Mac2f518a2017-09-19 16:06:03 -07009877 updateDischargeScreenLevelsLocked(mScreenState, mScreenState);
Dianne Hackborn77b987f2014-02-26 16:20:52 -08009878 }
Dianne Hackborna7c837f2014-01-15 16:20:44 -08009879 }
9880
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009881 private final NetworkStatsFactory mNetworkStatsFactory = new NetworkStatsFactory();
9882 private final Pools.Pool<NetworkStats> mNetworkStatsPool = new Pools.SynchronizedPool<>(6);
9883
9884 private final Object mWifiNetworkLock = new Object();
9885
9886 @GuardedBy("mWifiNetworkLock")
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009887 private String[] mWifiIfaces = EmptyArray.STRING;
9888
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009889 @GuardedBy("mWifiNetworkLock")
9890 private NetworkStats mLastWifiNetworkStats = new NetworkStats(0, -1);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009891
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009892 private final Object mModemNetworkLock = new Object();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009893
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009894 @GuardedBy("mModemNetworkLock")
9895 private String[] mModemIfaces = EmptyArray.STRING;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009896
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009897 @GuardedBy("mModemNetworkLock")
9898 private NetworkStats mLastModemNetworkStats = new NetworkStats(0, -1);
9899
9900 private NetworkStats readNetworkStatsLocked(String[] ifaces) {
9901 try {
9902 if (!ArrayUtils.isEmpty(ifaces)) {
9903 return mNetworkStatsFactory.readNetworkStatsDetail(NetworkStats.UID_ALL, ifaces,
9904 NetworkStats.TAG_NONE, mNetworkStatsPool.acquire());
9905 }
9906 } catch (IOException e) {
9907 Slog.e(TAG, "failed to read network stats for ifaces: " + Arrays.toString(ifaces));
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009908 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009909 return null;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009910 }
9911
9912 /**
9913 * Distribute WiFi energy info and network traffic to apps.
9914 * @param info The energy information from the WiFi controller.
9915 */
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009916 public void updateWifiState(@Nullable final WifiActivityEnergyInfo info) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -07009917 if (DEBUG_ENERGY) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009918 Slog.d(TAG, "Updating wifi stats: " + Arrays.toString(mWifiIfaces));
Adam Lesinskia7c90c82015-06-18 14:52:24 -07009919 }
9920
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009921 // Grab a separate lock to acquire the network stats, which may do I/O.
Adam Lesinskie08af192015-03-25 16:42:59 -07009922 NetworkStats delta = null;
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009923 synchronized (mWifiNetworkLock) {
9924 final NetworkStats latestStats = readNetworkStatsLocked(mWifiIfaces);
9925 if (latestStats != null) {
9926 delta = NetworkStats.subtract(latestStats, mLastWifiNetworkStats, null, null,
9927 mNetworkStatsPool.acquire());
9928 mNetworkStatsPool.release(mLastWifiNetworkStats);
9929 mLastWifiNetworkStats = latestStats;
Adam Lesinskie08af192015-03-25 16:42:59 -07009930 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009931 }
9932
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009933 synchronized (this) {
9934 if (!mOnBatteryInternal) {
9935 if (delta != null) {
9936 mNetworkStatsPool.release(delta);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009937 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009938 return;
9939 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009940
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009941 final long elapsedRealtimeMs = mClocks.elapsedRealtime();
9942 SparseLongArray rxPackets = new SparseLongArray();
9943 SparseLongArray txPackets = new SparseLongArray();
9944 long totalTxPackets = 0;
9945 long totalRxPackets = 0;
9946 if (delta != null) {
9947 NetworkStats.Entry entry = new NetworkStats.Entry();
9948 final int size = delta.size();
9949 for (int i = 0; i < size; i++) {
9950 entry = delta.getValues(i, entry);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07009951
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009952 if (DEBUG_ENERGY) {
9953 Slog.d(TAG, "Wifi uid " + entry.uid + ": delta rx=" + entry.rxBytes
9954 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
9955 + " txPackets=" + entry.txPackets);
9956 }
9957
9958 if (entry.rxBytes == 0 && entry.txBytes == 0) {
9959 // Skip the lookup below since there is no work to do.
9960 continue;
9961 }
9962
9963 final Uid u = getUidStatsLocked(mapUid(entry.uid));
9964 if (entry.rxBytes != 0) {
9965 u.noteNetworkActivityLocked(NETWORK_WIFI_RX_DATA, entry.rxBytes,
Amith Yamasani59fe8412017-03-03 16:28:52 -08009966 entry.rxPackets);
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009967 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
9968 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_RX_DATA, entry.rxBytes,
9969 entry.rxPackets);
9970 }
9971 mNetworkByteActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
9972 entry.rxBytes);
9973 mNetworkPacketActivityCounters[NETWORK_WIFI_RX_DATA].addCountLocked(
9974 entry.rxPackets);
9975
9976 rxPackets.put(u.getUid(), entry.rxPackets);
9977
9978 // Sum the total number of packets so that the Rx Power can
9979 // be evenly distributed amongst the apps.
9980 totalRxPackets += entry.rxPackets;
Amith Yamasani59fe8412017-03-03 16:28:52 -08009981 }
Adam Lesinskie08af192015-03-25 16:42:59 -07009982
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009983 if (entry.txBytes != 0) {
9984 u.noteNetworkActivityLocked(NETWORK_WIFI_TX_DATA, entry.txBytes,
Amith Yamasani59fe8412017-03-03 16:28:52 -08009985 entry.txPackets);
Adam Lesinski14ae39a2017-05-26 11:50:40 -07009986 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
9987 u.noteNetworkActivityLocked(NETWORK_WIFI_BG_TX_DATA, entry.txBytes,
9988 entry.txPackets);
9989 }
9990 mNetworkByteActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
9991 entry.txBytes);
9992 mNetworkPacketActivityCounters[NETWORK_WIFI_TX_DATA].addCountLocked(
9993 entry.txPackets);
9994
9995 txPackets.put(u.getUid(), entry.txPackets);
9996
9997 // Sum the total number of packets so that the Tx Power can
9998 // be evenly distributed amongst the apps.
9999 totalTxPackets += entry.txPackets;
Amith Yamasani59fe8412017-03-03 16:28:52 -080010000 }
Adam Lesinskiba88e682015-12-08 12:06:55 -080010001 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010002 mNetworkStatsPool.release(delta);
10003 delta = null;
Adam Lesinskie08af192015-03-25 16:42:59 -070010004 }
10005
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010006 if (info != null) {
10007 mHasWifiReporting = true;
Adam Lesinskie08af192015-03-25 16:42:59 -070010008
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010009 // Measured in mAms
10010 final long txTimeMs = info.getControllerTxTimeMillis();
10011 final long rxTimeMs = info.getControllerRxTimeMillis();
10012 final long idleTimeMs = info.getControllerIdleTimeMillis();
10013 final long totalTimeMs = txTimeMs + rxTimeMs + idleTimeMs;
Adam Lesinskie08af192015-03-25 16:42:59 -070010014
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010015 long leftOverRxTimeMs = rxTimeMs;
10016 long leftOverTxTimeMs = txTimeMs;
Adam Lesinskie08af192015-03-25 16:42:59 -070010017
Adam Lesinskie08af192015-03-25 16:42:59 -070010018 if (DEBUG_ENERGY) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010019 Slog.d(TAG, "------ BEGIN WiFi power blaming ------");
10020 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
10021 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
10022 Slog.d(TAG, " Idle Time: " + idleTimeMs + " ms");
10023 Slog.d(TAG, " Total Time: " + totalTimeMs + " ms");
Adam Lesinskie08af192015-03-25 16:42:59 -070010024 }
Adam Lesinskie08af192015-03-25 16:42:59 -070010025
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010026 long totalWifiLockTimeMs = 0;
10027 long totalScanTimeMs = 0;
10028
10029 // On the first pass, collect some totals so that we can normalize power
10030 // calculations if we need to.
10031 final int uidStatsSize = mUidStats.size();
10032 for (int i = 0; i < uidStatsSize; i++) {
10033 final Uid uid = mUidStats.valueAt(i);
10034
10035 // Sum the total scan power for all apps.
10036 totalScanTimeMs += uid.mWifiScanTimer.getTimeSinceMarkLocked(
10037 elapsedRealtimeMs * 1000) / 1000;
10038
10039 // Sum the total time holding wifi lock for all apps.
10040 totalWifiLockTimeMs += uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
10041 elapsedRealtimeMs * 1000) / 1000;
10042 }
10043
10044 if (DEBUG_ENERGY && totalScanTimeMs > rxTimeMs) {
10045 Slog.d(TAG,
10046 " !Estimated scan time > Actual rx time (" + totalScanTimeMs + " ms > "
10047 + rxTimeMs + " ms). Normalizing scan time.");
10048 }
10049 if (DEBUG_ENERGY && totalScanTimeMs > txTimeMs) {
10050 Slog.d(TAG,
10051 " !Estimated scan time > Actual tx time (" + totalScanTimeMs + " ms > "
10052 + txTimeMs + " ms). Normalizing scan time.");
10053 }
10054
10055 // Actually assign and distribute power usage to apps.
10056 for (int i = 0; i < uidStatsSize; i++) {
10057 final Uid uid = mUidStats.valueAt(i);
10058
10059 long scanTimeSinceMarkMs = uid.mWifiScanTimer.getTimeSinceMarkLocked(
10060 elapsedRealtimeMs * 1000) / 1000;
10061 if (scanTimeSinceMarkMs > 0) {
10062 // Set the new mark so that next time we get new data since this point.
10063 uid.mWifiScanTimer.setMark(elapsedRealtimeMs);
10064
10065 long scanRxTimeSinceMarkMs = scanTimeSinceMarkMs;
10066 long scanTxTimeSinceMarkMs = scanTimeSinceMarkMs;
10067
10068 // Our total scan time is more than the reported Tx/Rx time.
10069 // This is possible because the cost of a scan is approximate.
10070 // Let's normalize the result so that we evenly blame each app
10071 // scanning.
10072 //
10073 // This means that we may have apps that transmitted/received packets not be
10074 // blamed for this, but this is fine as scans are relatively more expensive.
10075 if (totalScanTimeMs > rxTimeMs) {
10076 scanRxTimeSinceMarkMs = (rxTimeMs * scanRxTimeSinceMarkMs) /
10077 totalScanTimeMs;
10078 }
10079 if (totalScanTimeMs > txTimeMs) {
10080 scanTxTimeSinceMarkMs = (txTimeMs * scanTxTimeSinceMarkMs) /
10081 totalScanTimeMs;
10082 }
10083
10084 if (DEBUG_ENERGY) {
10085 Slog.d(TAG, " ScanTime for UID " + uid.getUid() + ": Rx:"
10086 + scanRxTimeSinceMarkMs + " ms Tx:"
10087 + scanTxTimeSinceMarkMs + " ms)");
10088 }
10089
10090 ControllerActivityCounterImpl activityCounter =
10091 uid.getOrCreateWifiControllerActivityLocked();
10092 activityCounter.getRxTimeCounter().addCountLocked(scanRxTimeSinceMarkMs);
10093 activityCounter.getTxTimeCounters()[0].addCountLocked(
10094 scanTxTimeSinceMarkMs);
10095 leftOverRxTimeMs -= scanRxTimeSinceMarkMs;
10096 leftOverTxTimeMs -= scanTxTimeSinceMarkMs;
10097 }
10098
10099 // Distribute evenly the power consumed while Idle to each app holding a WiFi
10100 // lock.
10101 final long wifiLockTimeSinceMarkMs =
10102 uid.mFullWifiLockTimer.getTimeSinceMarkLocked(
10103 elapsedRealtimeMs * 1000) / 1000;
10104 if (wifiLockTimeSinceMarkMs > 0) {
10105 // Set the new mark so that next time we get new data since this point.
10106 uid.mFullWifiLockTimer.setMark(elapsedRealtimeMs);
10107
10108 final long myIdleTimeMs = (wifiLockTimeSinceMarkMs * idleTimeMs)
10109 / totalWifiLockTimeMs;
10110 if (DEBUG_ENERGY) {
10111 Slog.d(TAG, " IdleTime for UID " + uid.getUid() + ": "
10112 + myIdleTimeMs + " ms");
10113 }
10114 uid.getOrCreateWifiControllerActivityLocked().getIdleTimeCounter()
10115 .addCountLocked(myIdleTimeMs);
10116 }
10117 }
10118
Adam Lesinskie08af192015-03-25 16:42:59 -070010119 if (DEBUG_ENERGY) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010120 Slog.d(TAG, " New RxPower: " + leftOverRxTimeMs + " ms");
10121 Slog.d(TAG, " New TxPower: " + leftOverTxTimeMs + " ms");
Adam Lesinskie08af192015-03-25 16:42:59 -070010122 }
Adam Lesinskie08af192015-03-25 16:42:59 -070010123
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010124 // Distribute the remaining Tx power appropriately between all apps that transmitted
10125 // packets.
10126 for (int i = 0; i < txPackets.size(); i++) {
10127 final Uid uid = getUidStatsLocked(txPackets.keyAt(i));
10128 final long myTxTimeMs = (txPackets.valueAt(i) * leftOverTxTimeMs)
10129 / totalTxPackets;
10130 if (DEBUG_ENERGY) {
10131 Slog.d(TAG, " TxTime for UID " + uid.getUid() + ": " + myTxTimeMs + " ms");
10132 }
10133 uid.getOrCreateWifiControllerActivityLocked().getTxTimeCounters()[0]
10134 .addCountLocked(myTxTimeMs);
10135 }
Adam Lesinskie08af192015-03-25 16:42:59 -070010136
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010137 // Distribute the remaining Rx power appropriately between all apps that received
10138 // packets.
10139 for (int i = 0; i < rxPackets.size(); i++) {
10140 final Uid uid = getUidStatsLocked(rxPackets.keyAt(i));
10141 final long myRxTimeMs = (rxPackets.valueAt(i) * leftOverRxTimeMs)
10142 / totalRxPackets;
10143 if (DEBUG_ENERGY) {
10144 Slog.d(TAG, " RxTime for UID " + uid.getUid() + ": " + myRxTimeMs + " ms");
10145 }
10146 uid.getOrCreateWifiControllerActivityLocked().getRxTimeCounter()
10147 .addCountLocked(myRxTimeMs);
10148 }
Adam Lesinskie08af192015-03-25 16:42:59 -070010149
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010150 // Any left over power use will be picked up by the WiFi category in BatteryStatsHelper.
10151
10152
10153 // Update WiFi controller stats.
10154 mWifiActivity.getRxTimeCounter().addCountLocked(info.getControllerRxTimeMillis());
10155 mWifiActivity.getTxTimeCounters()[0].addCountLocked(
10156 info.getControllerTxTimeMillis());
10157 mWifiActivity.getIdleTimeCounter().addCountLocked(
10158 info.getControllerIdleTimeMillis());
10159
10160 // POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
10161 final double opVolt = mPowerProfile.getAveragePower(
10162 PowerProfile.POWER_WIFI_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
10163 if (opVolt != 0) {
10164 // We store the power drain as mAms.
10165 mWifiActivity.getPowerCounter().addCountLocked(
10166 (long) (info.getControllerEnergyUsed() / opVolt));
10167 }
Adam Lesinskie08af192015-03-25 16:42:59 -070010168 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010169 }
10170 }
10171
10172 /**
10173 * Distribute Cell radio energy info and network traffic to apps.
10174 */
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010175 public void updateMobileRadioState(@Nullable final ModemActivityInfo activityInfo) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -070010176 if (DEBUG_ENERGY) {
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010177 Slog.d(TAG, "Updating mobile radio stats with " + activityInfo);
Adam Lesinskia7c90c82015-06-18 14:52:24 -070010178 }
10179
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010180 // Grab a separate lock to acquire the network stats, which may do I/O.
Adam Lesinskie08af192015-03-25 16:42:59 -070010181 NetworkStats delta = null;
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010182 synchronized (mModemNetworkLock) {
10183 final NetworkStats latestStats = readNetworkStatsLocked(mModemIfaces);
10184 if (latestStats != null) {
10185 delta = NetworkStats.subtract(latestStats, mLastModemNetworkStats, null, null,
10186 mNetworkStatsPool.acquire());
10187 mNetworkStatsPool.release(mLastModemNetworkStats);
10188 mLastModemNetworkStats = latestStats;
Adam Lesinskie08af192015-03-25 16:42:59 -070010189 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010190 }
10191
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010192 synchronized (this) {
10193 if (!mOnBatteryInternal) {
10194 if (delta != null) {
10195 mNetworkStatsPool.release(delta);
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010196 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010197 return;
Adam Lesinskie08af192015-03-25 16:42:59 -070010198 }
10199
Adam Lesinskib3a1bad2017-05-26 11:50:40 -070010200 final long elapsedRealtimeMs = mClocks.elapsedRealtime();
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010201 long radioTime = mMobileRadioActivePerAppTimer.getTimeSinceMarkLocked(
10202 elapsedRealtimeMs * 1000);
10203 mMobileRadioActivePerAppTimer.setMark(elapsedRealtimeMs);
10204
10205 long totalRxPackets = 0;
10206 long totalTxPackets = 0;
10207 if (delta != null) {
10208 NetworkStats.Entry entry = new NetworkStats.Entry();
10209 final int size = delta.size();
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010210 for (int i = 0; i < size; i++) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010211 entry = delta.getValues(i, entry);
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010212 if (entry.rxPackets == 0 && entry.txPackets == 0) {
10213 continue;
10214 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010215
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010216 if (DEBUG_ENERGY) {
10217 Slog.d(TAG, "Mobile uid " + entry.uid + ": delta rx=" + entry.rxBytes
10218 + " tx=" + entry.txBytes + " rxPackets=" + entry.rxPackets
10219 + " txPackets=" + entry.txPackets);
10220 }
10221
10222 totalRxPackets += entry.rxPackets;
10223 totalTxPackets += entry.txPackets;
10224
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010225 final Uid u = getUidStatsLocked(mapUid(entry.uid));
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010226 u.noteNetworkActivityLocked(NETWORK_MOBILE_RX_DATA, entry.rxBytes,
10227 entry.rxPackets);
10228 u.noteNetworkActivityLocked(NETWORK_MOBILE_TX_DATA, entry.txBytes,
10229 entry.txPackets);
10230 if (entry.set == NetworkStats.SET_DEFAULT) { // Background transfers
10231 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_RX_DATA,
10232 entry.rxBytes, entry.rxPackets);
10233 u.noteNetworkActivityLocked(NETWORK_MOBILE_BG_TX_DATA,
10234 entry.txBytes, entry.txPackets);
10235 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010236
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010237 mNetworkByteActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
10238 entry.rxBytes);
10239 mNetworkByteActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
10240 entry.txBytes);
10241 mNetworkPacketActivityCounters[NETWORK_MOBILE_RX_DATA].addCountLocked(
10242 entry.rxPackets);
10243 mNetworkPacketActivityCounters[NETWORK_MOBILE_TX_DATA].addCountLocked(
10244 entry.txPackets);
10245 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010246
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010247 // Now distribute proportional blame to the apps that did networking.
10248 long totalPackets = totalRxPackets + totalTxPackets;
10249 if (totalPackets > 0) {
10250 for (int i = 0; i < size; i++) {
10251 entry = delta.getValues(i, entry);
10252 if (entry.rxPackets == 0 && entry.txPackets == 0) {
10253 continue;
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010254 }
10255
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010256 final Uid u = getUidStatsLocked(mapUid(entry.uid));
10257
10258 // Distribute total radio active time in to this app.
10259 final long appPackets = entry.rxPackets + entry.txPackets;
10260 final long appRadioTime = (radioTime * appPackets) / totalPackets;
10261 u.noteMobileRadioActiveTimeLocked(appRadioTime);
10262
10263 // Remove this app from the totals, so that we don't lose any time
10264 // due to rounding.
10265 radioTime -= appRadioTime;
10266 totalPackets -= appPackets;
10267
10268 if (activityInfo != null) {
10269 ControllerActivityCounterImpl activityCounter =
10270 u.getOrCreateModemControllerActivityLocked();
10271 if (totalRxPackets > 0 && entry.rxPackets > 0) {
10272 final long rxMs = (entry.rxPackets * activityInfo.getRxTimeMillis())
10273 / totalRxPackets;
10274 activityCounter.getRxTimeCounter().addCountLocked(rxMs);
10275 }
10276
10277 if (totalTxPackets > 0 && entry.txPackets > 0) {
10278 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
10279 long txMs =
10280 entry.txPackets * activityInfo.getTxTimeMillis()[lvl];
10281 txMs /= totalTxPackets;
10282 activityCounter.getTxTimeCounters()[lvl].addCountLocked(txMs);
10283 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010284 }
10285 }
10286 }
10287 }
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010288
10289 if (radioTime > 0) {
10290 // Whoops, there is some radio time we can't blame on an app!
10291 mMobileRadioActiveUnknownTime.addCountLocked(radioTime);
10292 mMobileRadioActiveUnknownCount.addCountLocked(1);
10293 }
10294
10295 mNetworkStatsPool.release(delta);
10296 delta = null;
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010297 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010298
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010299 if (activityInfo != null) {
10300 mHasModemReporting = true;
10301 mModemActivity.getIdleTimeCounter().addCountLocked(
10302 activityInfo.getIdleTimeMillis());
10303 mModemActivity.getRxTimeCounter().addCountLocked(activityInfo.getRxTimeMillis());
10304 for (int lvl = 0; lvl < ModemActivityInfo.TX_POWER_LEVELS; lvl++) {
10305 mModemActivity.getTxTimeCounters()[lvl]
10306 .addCountLocked(activityInfo.getTxTimeMillis()[lvl]);
10307 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010308
Adam Lesinski14ae39a2017-05-26 11:50:40 -070010309 // POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
10310 final double opVolt = mPowerProfile.getAveragePower(
10311 PowerProfile.POWER_MODEM_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
10312 if (opVolt != 0) {
10313 // We store the power drain as mAms.
10314 mModemActivity.getPowerCounter().addCountLocked(
10315 (long) (activityInfo.getEnergyUsed() / opVolt));
10316 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080010317 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010318 }
10319 }
10320
10321 /**
10322 * Distribute Bluetooth energy info and network traffic to apps.
10323 * @param info The energy information from the bluetooth controller.
10324 */
10325 public void updateBluetoothStateLocked(@Nullable final BluetoothActivityEnergyInfo info) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -070010326 if (DEBUG_ENERGY) {
Adam Lesinski50e47602015-12-04 17:04:54 -080010327 Slog.d(TAG, "Updating bluetooth stats: " + info);
Adam Lesinskia7c90c82015-06-18 14:52:24 -070010328 }
10329
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010330 if (info == null || !mOnBatteryInternal) {
10331 return;
10332 }
Adam Lesinskie283d332015-04-16 12:29:25 -070010333
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010334 mHasBluetoothReporting = true;
10335
Bookatz867c0d72017-03-07 18:23:42 -080010336 final long elapsedRealtimeMs = mClocks.elapsedRealtime();
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010337 final long rxTimeMs = info.getControllerRxTimeMillis();
10338 final long txTimeMs = info.getControllerTxTimeMillis();
10339
10340 if (DEBUG_ENERGY) {
10341 Slog.d(TAG, "------ BEGIN BLE power blaming ------");
10342 Slog.d(TAG, " Tx Time: " + txTimeMs + " ms");
10343 Slog.d(TAG, " Rx Time: " + rxTimeMs + " ms");
10344 Slog.d(TAG, " Idle Time: " + info.getControllerIdleTimeMillis() + " ms");
10345 }
10346
10347 long totalScanTimeMs = 0;
10348
10349 final int uidCount = mUidStats.size();
10350 for (int i = 0; i < uidCount; i++) {
10351 final Uid u = mUidStats.valueAt(i);
10352 if (u.mBluetoothScanTimer == null) {
10353 continue;
Adam Lesinskie283d332015-04-16 12:29:25 -070010354 }
Adam Lesinski50e47602015-12-04 17:04:54 -080010355
Bookatzaa4594a2017-03-24 12:39:56 -070010356 totalScanTimeMs += u.mBluetoothScanTimer.getTimeSinceMarkLocked(
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010357 elapsedRealtimeMs * 1000) / 1000;
10358 }
10359
10360 final boolean normalizeScanRxTime = (totalScanTimeMs > rxTimeMs);
10361 final boolean normalizeScanTxTime = (totalScanTimeMs > txTimeMs);
10362
10363 if (DEBUG_ENERGY) {
10364 Slog.d(TAG, "Normalizing scan power for RX=" + normalizeScanRxTime
10365 + " TX=" + normalizeScanTxTime);
10366 }
10367
10368 long leftOverRxTimeMs = rxTimeMs;
10369 long leftOverTxTimeMs = txTimeMs;
10370
10371 for (int i = 0; i < uidCount; i++) {
10372 final Uid u = mUidStats.valueAt(i);
10373 if (u.mBluetoothScanTimer == null) {
10374 continue;
10375 }
10376
Bookatzaa4594a2017-03-24 12:39:56 -070010377 long scanTimeSinceMarkMs = u.mBluetoothScanTimer.getTimeSinceMarkLocked(
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010378 elapsedRealtimeMs * 1000) / 1000;
10379 if (scanTimeSinceMarkMs > 0) {
10380 // Set the new mark so that next time we get new data since this point.
10381 u.mBluetoothScanTimer.setMark(elapsedRealtimeMs);
10382
10383 long scanTimeRxSinceMarkMs = scanTimeSinceMarkMs;
10384 long scanTimeTxSinceMarkMs = scanTimeSinceMarkMs;
10385
10386 if (normalizeScanRxTime) {
10387 // Scan time is longer than the total rx time in the controller,
10388 // so distribute the scan time proportionately. This means regular traffic
10389 // will not blamed, but scans are more expensive anyways.
10390 scanTimeRxSinceMarkMs = (rxTimeMs * scanTimeRxSinceMarkMs) / totalScanTimeMs;
10391 }
10392
10393 if (normalizeScanTxTime) {
10394 // Scan time is longer than the total tx time in the controller,
10395 // so distribute the scan time proportionately. This means regular traffic
10396 // will not blamed, but scans are more expensive anyways.
10397 scanTimeTxSinceMarkMs = (txTimeMs * scanTimeTxSinceMarkMs) / totalScanTimeMs;
10398 }
10399
10400 final ControllerActivityCounterImpl counter =
10401 u.getOrCreateBluetoothControllerActivityLocked();
10402 counter.getRxTimeCounter().addCountLocked(scanTimeRxSinceMarkMs);
10403 counter.getTxTimeCounters()[0].addCountLocked(scanTimeTxSinceMarkMs);
10404
10405 leftOverRxTimeMs -= scanTimeRxSinceMarkMs;
10406 leftOverTxTimeMs -= scanTimeTxSinceMarkMs;
10407 }
10408 }
10409
10410 if (DEBUG_ENERGY) {
10411 Slog.d(TAG, "Left over time for traffic RX=" + leftOverRxTimeMs
10412 + " TX=" + leftOverTxTimeMs);
10413 }
10414
10415 //
10416 // Now distribute blame to apps that did bluetooth traffic.
10417 //
10418
10419 long totalTxBytes = 0;
10420 long totalRxBytes = 0;
10421
10422 final UidTraffic[] uidTraffic = info.getUidTraffic();
10423 final int numUids = uidTraffic != null ? uidTraffic.length : 0;
10424 for (int i = 0; i < numUids; i++) {
10425 final UidTraffic traffic = uidTraffic[i];
10426
10427 // Add to the global counters.
10428 mNetworkByteActivityCounters[NETWORK_BT_RX_DATA].addCountLocked(
10429 traffic.getRxBytes());
10430 mNetworkByteActivityCounters[NETWORK_BT_TX_DATA].addCountLocked(
10431 traffic.getTxBytes());
10432
10433 // Add to the UID counters.
10434 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()));
10435 u.noteNetworkActivityLocked(NETWORK_BT_RX_DATA, traffic.getRxBytes(), 0);
10436 u.noteNetworkActivityLocked(NETWORK_BT_TX_DATA, traffic.getTxBytes(), 0);
10437
10438 // Calculate the total traffic.
10439 totalTxBytes += traffic.getTxBytes();
10440 totalRxBytes += traffic.getRxBytes();
10441 }
10442
10443 if ((totalTxBytes != 0 || totalRxBytes != 0) &&
10444 (leftOverRxTimeMs != 0 || leftOverTxTimeMs != 0)) {
Adam Lesinski50e47602015-12-04 17:04:54 -080010445 for (int i = 0; i < numUids; i++) {
10446 final UidTraffic traffic = uidTraffic[i];
10447
Adam Lesinski50e47602015-12-04 17:04:54 -080010448 final Uid u = getUidStatsLocked(mapUid(traffic.getUid()));
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010449 final ControllerActivityCounterImpl counter =
10450 u.getOrCreateBluetoothControllerActivityLocked();
10451
10452 if (totalRxBytes > 0 && traffic.getRxBytes() > 0) {
10453 final long timeRxMs = (leftOverRxTimeMs * traffic.getRxBytes()) / totalRxBytes;
10454
10455 if (DEBUG_ENERGY) {
10456 Slog.d(TAG, "UID=" + traffic.getUid() + " rx_bytes=" + traffic.getRxBytes()
10457 + " rx_time=" + timeRxMs);
10458 }
10459 counter.getRxTimeCounter().addCountLocked(timeRxMs);
10460 leftOverRxTimeMs -= timeRxMs;
10461 }
10462
10463 if (totalTxBytes > 0 && traffic.getTxBytes() > 0) {
10464 final long timeTxMs = (leftOverTxTimeMs * traffic.getTxBytes()) / totalTxBytes;
10465
10466 if (DEBUG_ENERGY) {
10467 Slog.d(TAG, "UID=" + traffic.getUid() + " tx_bytes=" + traffic.getTxBytes()
10468 + " tx_time=" + timeTxMs);
10469 }
10470
10471 counter.getTxTimeCounters()[0].addCountLocked(timeTxMs);
10472 leftOverTxTimeMs -= timeTxMs;
10473 }
Adam Lesinski50e47602015-12-04 17:04:54 -080010474 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010475 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -080010476
10477 mBluetoothActivity.getRxTimeCounter().addCountLocked(
10478 info.getControllerRxTimeMillis());
10479 mBluetoothActivity.getTxTimeCounters()[0].addCountLocked(
10480 info.getControllerTxTimeMillis());
10481 mBluetoothActivity.getIdleTimeCounter().addCountLocked(
10482 info.getControllerIdleTimeMillis());
10483
10484 // POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE is measured in mV, so convert to V.
10485 final double opVolt = mPowerProfile.getAveragePower(
10486 PowerProfile.POWER_BLUETOOTH_CONTROLLER_OPERATING_VOLTAGE) / 1000.0;
10487 if (opVolt != 0) {
10488 // We store the power drain as mAms.
10489 mBluetoothActivity.getPowerCounter().addCountLocked(
10490 (long) (info.getControllerEnergyUsed() / opVolt));
10491 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010492 }
10493
10494 /**
Bookatz0b8a0502017-09-13 11:51:52 -070010495 * Read and record Resource Power Manager (RPM) state and voter times.
10496 * If RPM stats were fetched more recently than RPM_STATS_UPDATE_FREQ_MS ago, uses the old data
10497 * instead of fetching it anew.
Bookatz50df7112017-08-04 14:53:26 -070010498 */
10499 public void updateRpmStatsLocked() {
10500 if (mPlatformIdleStateCallback == null) return;
Bookatz0b8a0502017-09-13 11:51:52 -070010501 long now = SystemClock.elapsedRealtime();
10502 if (now - mLastRpmStatsUpdateTimeMs >= RPM_STATS_UPDATE_FREQ_MS) {
10503 mPlatformIdleStateCallback.fillLowPowerStats(mTmpRpmStats);
10504 mLastRpmStatsUpdateTimeMs = now;
10505 }
Bookatz50df7112017-08-04 14:53:26 -070010506
10507 for (Map.Entry<String, RpmStats.PowerStatePlatformSleepState> pstate
10508 : mTmpRpmStats.mPlatformLowPowerStats.entrySet()) {
10509
10510 // Update values for this platform state.
10511 final String pName = pstate.getKey();
10512 final long pTimeUs = pstate.getValue().mTimeMs * 1000;
10513 final int pCount = pstate.getValue().mCount;
10514 getRpmTimerLocked(pName).update(pTimeUs, pCount);
Bookatz82b341172017-09-07 19:06:08 -070010515 if (SCREEN_OFF_RPM_STATS_ENABLED) {
10516 getScreenOffRpmTimerLocked(pName).update(pTimeUs, pCount);
10517 }
Bookatz50df7112017-08-04 14:53:26 -070010518
10519 // Update values for each voter of this platform state.
10520 for (Map.Entry<String, RpmStats.PowerStateElement> voter
10521 : pstate.getValue().mVoters.entrySet()) {
10522 final String vName = pName + "." + voter.getKey();
10523 final long vTimeUs = voter.getValue().mTimeMs * 1000;
10524 final int vCount = voter.getValue().mCount;
10525 getRpmTimerLocked(vName).update(vTimeUs, vCount);
Bookatz82b341172017-09-07 19:06:08 -070010526 if (SCREEN_OFF_RPM_STATS_ENABLED) {
10527 getScreenOffRpmTimerLocked(vName).update(vTimeUs, vCount);
10528 }
Bookatz50df7112017-08-04 14:53:26 -070010529 }
10530 }
10531
10532 for (Map.Entry<String, RpmStats.PowerStateSubsystem> subsys
10533 : mTmpRpmStats.mSubsystemLowPowerStats.entrySet()) {
10534
10535 final String subsysName = subsys.getKey();
10536 for (Map.Entry<String, RpmStats.PowerStateElement> sstate
10537 : subsys.getValue().mStates.entrySet()) {
10538 final String name = subsysName + "." + sstate.getKey();
10539 final long timeUs = sstate.getValue().mTimeMs * 1000;
10540 final int count = sstate.getValue().mCount;
10541 getRpmTimerLocked(name).update(timeUs, count);
Bookatz82b341172017-09-07 19:06:08 -070010542 if (SCREEN_OFF_RPM_STATS_ENABLED) {
10543 getScreenOffRpmTimerLocked(name).update(timeUs, count);
10544 }
Bookatz50df7112017-08-04 14:53:26 -070010545 }
10546 }
10547 }
10548
10549 /**
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010550 * Read and distribute kernel wake lock use across apps.
10551 */
10552 public void updateKernelWakelocksLocked() {
10553 final KernelWakelockStats wakelockStats = mKernelWakelockReader.readKernelWakelockStats(
10554 mTmpWakelockStats);
10555 if (wakelockStats == null) {
10556 // Not crashing might make board bringup easier.
10557 Slog.w(TAG, "Couldn't get kernel wake lock stats");
10558 return;
10559 }
10560
10561 for (Map.Entry<String, KernelWakelockStats.Entry> ent : wakelockStats.entrySet()) {
10562 String name = ent.getKey();
10563 KernelWakelockStats.Entry kws = ent.getValue();
10564
10565 SamplingTimer kwlt = mKernelWakelockStats.get(name);
10566 if (kwlt == null) {
Adam Lesinski757c6ea2016-04-21 09:55:41 -070010567 kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010568 mKernelWakelockStats.put(name, kwlt);
10569 }
Adam Lesinskid84ad302016-05-17 18:31:02 -070010570
Adam Lesinski757c6ea2016-04-21 09:55:41 -070010571 kwlt.update(kws.mTotalTime, kws.mCount);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010572 kwlt.setUpdateVersion(kws.mVersion);
10573 }
10574
Adam Lesinskifbabe7d2015-08-03 14:37:38 -070010575 int numWakelocksSetStale = 0;
Adam Lesinskid84ad302016-05-17 18:31:02 -070010576 // Set timers to stale if they didn't appear in /d/wakeup_sources (or /proc/wakelocks)
10577 // this time.
10578 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
10579 SamplingTimer st = ent.getValue();
10580 if (st.getUpdateVersion() != wakelockStats.kernelWakelockVersion) {
10581 st.endSample();
10582 numWakelocksSetStale++;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010583 }
10584 }
Adam Lesinskifbabe7d2015-08-03 14:37:38 -070010585
Adam Lesinskid84ad302016-05-17 18:31:02 -070010586 // Record whether we've seen a non-zero time (for debugging b/22716723).
10587 if (wakelockStats.isEmpty()) {
Adam Lesinskifbabe7d2015-08-03 14:37:38 -070010588 Slog.wtf(TAG, "All kernel wakelocks had time of zero");
10589 }
10590
10591 if (numWakelocksSetStale == mKernelWakelockStats.size()) {
10592 Slog.wtf(TAG, "All kernel wakelocks were set stale. new version=" +
10593 wakelockStats.kernelWakelockVersion);
10594 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070010595 }
10596
Adam Lesinski72478f02015-06-17 15:39:43 -070010597 // We use an anonymous class to access these variables,
10598 // so they can't live on the stack or they'd have to be
10599 // final MutableLong objects (more allocations).
10600 // Used in updateCpuTimeLocked().
10601 long mTempTotalCpuUserTimeUs;
10602 long mTempTotalCpuSystemTimeUs;
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010603 long[][] mWakeLockAllocationsUs;
Adam Lesinski72478f02015-06-17 15:39:43 -070010604
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010605 /**
James Carr3a226052016-07-01 14:49:52 -070010606 * Reads the newest memory stats from the kernel.
10607 */
10608 public void updateKernelMemoryBandwidthLocked() {
10609 mKernelMemoryBandwidthStats.updateStats();
10610 LongSparseLongArray bandwidthEntries = mKernelMemoryBandwidthStats.getBandwidthEntries();
10611 final int bandwidthEntryCount = bandwidthEntries.size();
10612 int index;
10613 for (int i = 0; i < bandwidthEntryCount; i++) {
10614 SamplingTimer timer;
10615 if ((index = mKernelMemoryStats.indexOfKey(bandwidthEntries.keyAt(i))) >= 0) {
10616 timer = mKernelMemoryStats.valueAt(index);
10617 } else {
10618 timer = new SamplingTimer(mClocks, mOnBatteryTimeBase);
10619 mKernelMemoryStats.put(bandwidthEntries.keyAt(i), timer);
10620 }
10621 timer.update(bandwidthEntries.valueAt(i), 1);
10622 if (DEBUG_MEMORY) {
10623 Slog.d(TAG, String.format("Added entry %d and updated timer to: "
10624 + "mUnpluggedReportedTotalTime %d size %d", bandwidthEntries.keyAt(i),
10625 mKernelMemoryStats.get(
10626 bandwidthEntries.keyAt(i)).mUnpluggedReportedTotalTime,
10627 mKernelMemoryStats.size()));
10628 }
10629 }
10630 }
10631
10632 /**
Adam Lesinski72478f02015-06-17 15:39:43 -070010633 * Read and distribute CPU usage across apps. If their are partial wakelocks being held
10634 * and we are on battery with screen off, we give more of the cpu time to those apps holding
10635 * wakelocks. If the screen is on, we just assign the actual cpu time an app used.
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010636 */
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010637 public void updateCpuTimeLocked() {
Adam Lesinski52290c9c2015-09-21 16:54:52 -070010638 if (mPowerProfile == null) {
10639 return;
10640 }
10641
Adam Lesinski72478f02015-06-17 15:39:43 -070010642 if (DEBUG_ENERGY_CPU) {
10643 Slog.d(TAG, "!Cpu updating!");
10644 }
10645
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010646 if (mCpuFreqs == null) {
10647 mCpuFreqs = mKernelUidCpuFreqTimeReader.readFreqs(mPowerProfile);
10648 }
10649
Sudheer Shanka38383232017-07-25 09:55:03 -070010650 // Calculate the wakelocks we have to distribute amongst. The system is excluded as it is
10651 // usually holding the wakelock on behalf of an app.
10652 // And Only distribute cpu power to wakelocks if the screen is off and we're on battery.
10653 ArrayList<StopwatchTimer> partialTimersToConsider = null;
Adam Lesinski72478f02015-06-17 15:39:43 -070010654 if (mOnBatteryScreenOffTimeBase.isRunning()) {
Sudheer Shanka38383232017-07-25 09:55:03 -070010655 partialTimersToConsider = new ArrayList<>();
10656 for (int i = mPartialTimers.size() - 1; i >= 0; --i) {
Adam Lesinski72478f02015-06-17 15:39:43 -070010657 final StopwatchTimer timer = mPartialTimers.get(i);
Sudheer Shanka38383232017-07-25 09:55:03 -070010658 // Since the collection and blaming of wakelocks can be scheduled to run after
10659 // some delay, the mPartialTimers list may have new entries. We can't blame
10660 // the newly added timer for past cpu time, so we only consider timers that
10661 // were present for one round of collection. Once a timer has gone through
10662 // a round of collection, its mInList field is set to true.
Adam Lesinski72478f02015-06-17 15:39:43 -070010663 if (timer.mInList && timer.mUid != null && timer.mUid.mUid != Process.SYSTEM_UID) {
Sudheer Shanka38383232017-07-25 09:55:03 -070010664 partialTimersToConsider.add(timer);
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010665 }
Adam Lesinski72478f02015-06-17 15:39:43 -070010666 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010667 }
Sudheer Shanka38383232017-07-25 09:55:03 -070010668 markPartialTimersAsEligible();
Adam Lesinski72478f02015-06-17 15:39:43 -070010669
Sudheer Shanka38383232017-07-25 09:55:03 -070010670 // When the battery is not on, we don't attribute the cpu times to any timers but we still
10671 // need to take the snapshots.
10672 if (!mOnBatteryInternal) {
10673 mKernelUidCpuTimeReader.readDelta(null);
10674 mKernelUidCpuFreqTimeReader.readDelta(null);
10675 for (int cluster = mKernelCpuSpeedReaders.length - 1; cluster >= 0; --cluster) {
10676 mKernelCpuSpeedReaders[cluster].readDelta();
10677 }
10678 return;
10679 }
Adam Lesinski72478f02015-06-17 15:39:43 -070010680
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070010681 mUserInfoProvider.refreshUserIds();
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010682 final SparseLongArray updatedUids = mKernelUidCpuFreqTimeReader.perClusterTimesAvailable()
10683 ? null : new SparseLongArray();
Sudheer Shanka38383232017-07-25 09:55:03 -070010684 readKernelUidCpuTimesLocked(partialTimersToConsider, updatedUids);
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010685 // updatedUids=null means /proc/uid_time_in_state provides snapshots of per-cluster cpu
10686 // freqs, so no need to approximate these values.
10687 if (updatedUids != null) {
10688 updateClusterSpeedTimes(updatedUids);
Sudheer Shanka671985f2017-05-19 11:33:42 -070010689 }
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010690 readKernelUidCpuFreqTimesLocked(partialTimersToConsider);
Sudheer Shanka38383232017-07-25 09:55:03 -070010691 }
Sudheer Shanka9b735c52017-05-09 18:26:18 -070010692
Sudheer Shanka38383232017-07-25 09:55:03 -070010693 /**
10694 * Mark the current partial timers as gone through a collection so that they will be
10695 * considered in the next cpu times distribution to wakelock holders.
10696 */
10697 @VisibleForTesting
10698 public void markPartialTimersAsEligible() {
10699 if (ArrayUtils.referenceEquals(mPartialTimers, mLastPartialTimers)) {
10700 // No difference, so each timer is now considered for the next collection.
10701 for (int i = mPartialTimers.size() - 1; i >= 0; --i) {
10702 mPartialTimers.get(i).mInList = true;
10703 }
10704 } else {
10705 // The lists are different, meaning we added (or removed a timer) since the last
10706 // collection.
10707 for (int i = mLastPartialTimers.size() - 1; i >= 0; --i) {
10708 mLastPartialTimers.get(i).mInList = false;
10709 }
10710 mLastPartialTimers.clear();
Adam Lesinski72478f02015-06-17 15:39:43 -070010711
Sudheer Shanka38383232017-07-25 09:55:03 -070010712 // Mark the current timers as gone through a collection.
10713 final int numPartialTimers = mPartialTimers.size();
10714 for (int i = 0; i < numPartialTimers; ++i) {
Adam Lesinski72478f02015-06-17 15:39:43 -070010715 final StopwatchTimer timer = mPartialTimers.get(i);
Sudheer Shanka38383232017-07-25 09:55:03 -070010716 timer.mInList = true;
10717 mLastPartialTimers.add(timer);
Adam Lesinski72478f02015-06-17 15:39:43 -070010718 }
10719 }
Sudheer Shanka38383232017-07-25 09:55:03 -070010720 }
Adam Lesinski72478f02015-06-17 15:39:43 -070010721
Sudheer Shanka38383232017-07-25 09:55:03 -070010722 /**
10723 * Take snapshot of cpu times (aggregated over all uids) at different frequencies and
10724 * calculate cpu times spent by each uid at different frequencies.
10725 *
10726 * @param updatedUids The uids for which times spent at different frequencies are calculated.
10727 */
10728 @VisibleForTesting
10729 public void updateClusterSpeedTimes(@NonNull SparseLongArray updatedUids) {
Sudheer Shankaaf857412017-07-21 00:14:24 -070010730 long totalCpuClustersTimeMs = 0;
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010731 // Read the time spent for each cluster at various cpu frequencies.
Sudheer Shankaaf857412017-07-21 00:14:24 -070010732 final long[][] clusterSpeedTimesMs = new long[mKernelCpuSpeedReaders.length][];
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010733 for (int cluster = 0; cluster < mKernelCpuSpeedReaders.length; cluster++) {
Sudheer Shankaaf857412017-07-21 00:14:24 -070010734 clusterSpeedTimesMs[cluster] = mKernelCpuSpeedReaders[cluster].readDelta();
10735 if (clusterSpeedTimesMs[cluster] != null) {
10736 for (int speed = clusterSpeedTimesMs[cluster].length - 1; speed >= 0; --speed) {
10737 totalCpuClustersTimeMs += clusterSpeedTimesMs[cluster][speed];
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010738 }
10739 }
10740 }
Sudheer Shankaaf857412017-07-21 00:14:24 -070010741 if (totalCpuClustersTimeMs != 0) {
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010742 // We have cpu times per freq aggregated over all uids but we need the times per uid.
10743 // So, we distribute total time spent by an uid to different cpu freqs based on the
10744 // amount of time cpu was running at that freq.
10745 final int updatedUidsCount = updatedUids.size();
10746 for (int i = 0; i < updatedUidsCount; ++i) {
10747 final Uid u = getUidStatsLocked(updatedUids.keyAt(i));
Sudheer Shankaaf857412017-07-21 00:14:24 -070010748 final long appCpuTimeUs = updatedUids.valueAt(i);
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010749 // Add the cpu speeds to this UID.
10750 final int numClusters = mPowerProfile.getNumCpuClusters();
Sudheer Shanka38383232017-07-25 09:55:03 -070010751 if (u.mCpuClusterSpeedTimesUs == null ||
10752 u.mCpuClusterSpeedTimesUs.length != numClusters) {
Sudheer Shankaaf857412017-07-21 00:14:24 -070010753 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010754 }
10755
Sudheer Shankaaf857412017-07-21 00:14:24 -070010756 for (int cluster = 0; cluster < clusterSpeedTimesMs.length; cluster++) {
10757 final int speedsInCluster = clusterSpeedTimesMs[cluster].length;
10758 if (u.mCpuClusterSpeedTimesUs[cluster] == null || speedsInCluster !=
10759 u.mCpuClusterSpeedTimesUs[cluster].length) {
10760 u.mCpuClusterSpeedTimesUs[cluster]
10761 = new LongSamplingCounter[speedsInCluster];
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010762 }
10763
Sudheer Shankaaf857412017-07-21 00:14:24 -070010764 final LongSamplingCounter[] cpuSpeeds = u.mCpuClusterSpeedTimesUs[cluster];
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010765 for (int speed = 0; speed < speedsInCluster; speed++) {
10766 if (cpuSpeeds[speed] == null) {
10767 cpuSpeeds[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
10768 }
Sudheer Shankaaf857412017-07-21 00:14:24 -070010769 cpuSpeeds[speed].addCountLocked(appCpuTimeUs
10770 * clusterSpeedTimesMs[cluster][speed]
10771 / totalCpuClustersTimeMs);
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010772 }
10773 }
10774 }
10775 }
Sudheer Shanka38383232017-07-25 09:55:03 -070010776 }
Sudheer Shanka2fc52d42017-06-16 17:29:19 -070010777
Sudheer Shanka38383232017-07-25 09:55:03 -070010778 /**
10779 * Take a snapshot of the cpu times spent by each uid and update the corresponding counters.
10780 * If {@param partialTimers} is not null and empty, then we assign a portion of cpu times to
10781 * wakelock holders.
10782 *
10783 * @param partialTimers The wakelock holders among which the cpu times will be distributed.
10784 * @param updatedUids If not null, then the uids found in the snapshot will be added to this.
10785 */
10786 @VisibleForTesting
10787 public void readKernelUidCpuTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers,
10788 @Nullable SparseLongArray updatedUids) {
10789 mTempTotalCpuUserTimeUs = mTempTotalCpuSystemTimeUs = 0;
10790 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size();
10791 final long startTimeMs = mClocks.uptimeMillis();
Adam Lesinski72478f02015-06-17 15:39:43 -070010792
Sudheer Shanka38383232017-07-25 09:55:03 -070010793 mKernelUidCpuTimeReader.readDelta((uid, userTimeUs, systemTimeUs) -> {
10794 uid = mapUid(uid);
10795 if (Process.isIsolated(uid)) {
10796 // This could happen if the isolated uid mapping was removed before that process
10797 // was actually killed.
10798 mKernelUidCpuTimeReader.removeUid(uid);
10799 Slog.d(TAG, "Got readings for an isolated uid with no mapping: " + uid);
10800 return;
10801 }
10802 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
10803 Slog.d(TAG, "Got readings for an invalid user's uid " + uid);
10804 mKernelUidCpuTimeReader.removeUid(uid);
10805 return;
10806 }
10807 final Uid u = getUidStatsLocked(uid);
10808
10809 // Accumulate the total system and user time.
10810 mTempTotalCpuUserTimeUs += userTimeUs;
10811 mTempTotalCpuSystemTimeUs += systemTimeUs;
10812
10813 StringBuilder sb = null;
10814 if (DEBUG_ENERGY_CPU) {
10815 sb = new StringBuilder();
10816 sb.append(" got time for uid=").append(u.mUid).append(": u=");
10817 TimeUtils.formatDuration(userTimeUs / 1000, sb);
10818 sb.append(" s=");
10819 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
10820 sb.append("\n");
10821 }
10822
10823 if (numWakelocks > 0) {
10824 // We have wakelocks being held, so only give a portion of the
10825 // time to the process. The rest will be distributed among wakelock
10826 // holders.
10827 userTimeUs = (userTimeUs * WAKE_LOCK_WEIGHT) / 100;
10828 systemTimeUs = (systemTimeUs * WAKE_LOCK_WEIGHT) / 100;
10829 }
10830
10831 if (sb != null) {
10832 sb.append(" adding to uid=").append(u.mUid).append(": u=");
10833 TimeUtils.formatDuration(userTimeUs / 1000, sb);
10834 sb.append(" s=");
10835 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
10836 Slog.d(TAG, sb.toString());
10837 }
10838
10839 u.mUserCpuTime.addCountLocked(userTimeUs);
10840 u.mSystemCpuTime.addCountLocked(systemTimeUs);
10841 if (updatedUids != null) {
10842 updatedUids.put(u.getUid(), userTimeUs + systemTimeUs);
10843 }
10844 });
10845
10846 final long elapsedTimeMs = mClocks.uptimeMillis() - startTimeMs;
10847 if (DEBUG_ENERGY_CPU || elapsedTimeMs >= 100) {
10848 Slog.d(TAG, "Reading cpu stats took " + elapsedTimeMs + "ms");
10849 }
10850
10851 if (numWakelocks > 0) {
10852 // Distribute a portion of the total cpu time to wakelock holders.
10853 mTempTotalCpuUserTimeUs = (mTempTotalCpuUserTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100;
10854 mTempTotalCpuSystemTimeUs =
10855 (mTempTotalCpuSystemTimeUs * (100 - WAKE_LOCK_WEIGHT)) / 100;
10856
10857 for (int i = 0; i < numWakelocks; ++i) {
10858 final StopwatchTimer timer = partialTimers.get(i);
10859 final int userTimeUs = (int) (mTempTotalCpuUserTimeUs / (numWakelocks - i));
10860 final int systemTimeUs = (int) (mTempTotalCpuSystemTimeUs / (numWakelocks - i));
10861
10862 if (DEBUG_ENERGY_CPU) {
10863 final StringBuilder sb = new StringBuilder();
10864 sb.append(" Distributing wakelock uid=").append(timer.mUid.mUid)
10865 .append(": u=");
10866 TimeUtils.formatDuration(userTimeUs / 1000, sb);
10867 sb.append(" s=");
10868 TimeUtils.formatDuration(systemTimeUs / 1000, sb);
10869 Slog.d(TAG, sb.toString());
10870 }
10871
10872 timer.mUid.mUserCpuTime.addCountLocked(userTimeUs);
10873 timer.mUid.mSystemCpuTime.addCountLocked(systemTimeUs);
10874 if (updatedUids != null) {
10875 final int uid = timer.mUid.getUid();
10876 updatedUids.put(uid, updatedUids.get(uid, 0) + userTimeUs + systemTimeUs);
10877 }
10878
10879 final Uid.Proc proc = timer.mUid.getProcessStatsLocked("*wakelock*");
10880 proc.addCpuTimeLocked(userTimeUs / 1000, systemTimeUs / 1000);
10881
10882 mTempTotalCpuUserTimeUs -= userTimeUs;
10883 mTempTotalCpuSystemTimeUs -= systemTimeUs;
Adam Lesinski72478f02015-06-17 15:39:43 -070010884 }
10885 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -070010886 }
10887
Sudheer Shanka38383232017-07-25 09:55:03 -070010888 /**
10889 * Take a snapshot of the cpu times spent by each uid in each freq and update the
10890 * corresponding counters.
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010891 *
10892 * @param partialTimers The wakelock holders among which the cpu freq times will be distributed.
Sudheer Shanka38383232017-07-25 09:55:03 -070010893 */
10894 @VisibleForTesting
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010895 public void readKernelUidCpuFreqTimesLocked(@Nullable ArrayList<StopwatchTimer> partialTimers) {
10896 final boolean perClusterTimesAvailable =
10897 mKernelUidCpuFreqTimeReader.perClusterTimesAvailable();
10898 final int numWakelocks = partialTimers == null ? 0 : partialTimers.size();
10899 final int numClusters = mPowerProfile.getNumCpuClusters();
10900 mWakeLockAllocationsUs = null;
10901 mKernelUidCpuFreqTimeReader.readDelta((uid, cpuFreqTimeMs) -> {
10902 uid = mapUid(uid);
10903 if (Process.isIsolated(uid)) {
10904 mKernelUidCpuFreqTimeReader.removeUid(uid);
10905 Slog.d(TAG, "Got freq readings for an isolated uid with no mapping: " + uid);
10906 return;
Sudheer Shanka38383232017-07-25 09:55:03 -070010907 }
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010908 if (!mUserInfoProvider.exists(UserHandle.getUserId(uid))) {
10909 Slog.d(TAG, "Got freq readings for an invalid user's uid " + uid);
10910 mKernelUidCpuFreqTimeReader.removeUid(uid);
10911 return;
10912 }
10913 final Uid u = getUidStatsLocked(uid);
10914 if (u.mCpuFreqTimeMs == null || u.mCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) {
10915 u.mCpuFreqTimeMs = new LongSamplingCounterArray(mOnBatteryTimeBase);
10916 }
10917 u.mCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs);
10918 if (u.mScreenOffCpuFreqTimeMs == null ||
10919 u.mScreenOffCpuFreqTimeMs.getSize() != cpuFreqTimeMs.length) {
10920 u.mScreenOffCpuFreqTimeMs = new LongSamplingCounterArray(
10921 mOnBatteryScreenOffTimeBase);
10922 }
10923 u.mScreenOffCpuFreqTimeMs.addCountLocked(cpuFreqTimeMs);
Sudheer Shanka9b735c52017-05-09 18:26:18 -070010924
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010925 if (perClusterTimesAvailable) {
10926 if (u.mCpuClusterSpeedTimesUs == null ||
10927 u.mCpuClusterSpeedTimesUs.length != numClusters) {
10928 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
Sudheer Shanka38383232017-07-25 09:55:03 -070010929 }
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010930 if (numWakelocks > 0 && mWakeLockAllocationsUs == null) {
10931 mWakeLockAllocationsUs = new long[numClusters][];
Sudheer Shanka38383232017-07-25 09:55:03 -070010932 }
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010933
10934 int freqIndex = 0;
10935 for (int cluster = 0; cluster < numClusters; ++cluster) {
10936 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster);
10937 if (u.mCpuClusterSpeedTimesUs[cluster] == null ||
10938 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) {
10939 u.mCpuClusterSpeedTimesUs[cluster]
10940 = new LongSamplingCounter[speedsInCluster];
10941 }
10942 if (numWakelocks > 0 && mWakeLockAllocationsUs[cluster] == null) {
10943 mWakeLockAllocationsUs[cluster] = new long[speedsInCluster];
10944 }
10945 final LongSamplingCounter[] cpuTimesUs = u.mCpuClusterSpeedTimesUs[cluster];
10946 for (int speed = 0; speed < speedsInCluster; ++speed) {
10947 if (cpuTimesUs[speed] == null) {
10948 cpuTimesUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
10949 }
10950 final long appAllocationUs;
10951 if (mWakeLockAllocationsUs != null) {
10952 appAllocationUs =
10953 (cpuFreqTimeMs[freqIndex] * 1000 * WAKE_LOCK_WEIGHT) / 100;
10954 mWakeLockAllocationsUs[cluster][speed] +=
10955 (cpuFreqTimeMs[freqIndex] * 1000 - appAllocationUs);
10956 } else {
10957 appAllocationUs = cpuFreqTimeMs[freqIndex] * 1000;
10958 }
10959 cpuTimesUs[speed].addCountLocked(appAllocationUs);
10960 freqIndex++;
10961 }
Sudheer Shanka38383232017-07-25 09:55:03 -070010962 }
Sudheer Shanka38383232017-07-25 09:55:03 -070010963 }
10964 });
Sudheer Shankab8ad5942017-08-08 12:16:09 -070010965
10966 if (mWakeLockAllocationsUs != null) {
10967 for (int i = 0; i < numWakelocks; ++i) {
10968 final Uid u = partialTimers.get(i).mUid;
10969 if (u.mCpuClusterSpeedTimesUs == null ||
10970 u.mCpuClusterSpeedTimesUs.length != numClusters) {
10971 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
10972 }
10973
10974 for (int cluster = 0; cluster < numClusters; ++cluster) {
10975 final int speedsInCluster = mPowerProfile.getNumSpeedStepsInCpuCluster(cluster);
10976 if (u.mCpuClusterSpeedTimesUs[cluster] == null ||
10977 u.mCpuClusterSpeedTimesUs[cluster].length != speedsInCluster) {
10978 u.mCpuClusterSpeedTimesUs[cluster]
10979 = new LongSamplingCounter[speedsInCluster];
10980 }
10981 final LongSamplingCounter[] cpuTimeUs = u.mCpuClusterSpeedTimesUs[cluster];
10982 for (int speed = 0; speed < speedsInCluster; ++speed) {
10983 if (cpuTimeUs[speed] == null) {
10984 cpuTimeUs[speed] = new LongSamplingCounter(mOnBatteryTimeBase);
10985 }
10986 final long allocationUs =
10987 mWakeLockAllocationsUs[cluster][speed] / (numWakelocks - i);
10988 cpuTimeUs[speed].addCountLocked(allocationUs);
10989 mWakeLockAllocationsUs[cluster][speed] -= allocationUs;
10990 }
10991 }
10992 }
10993 }
Sudheer Shanka9b735c52017-05-09 18:26:18 -070010994 }
10995
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070010996 boolean setChargingLocked(boolean charging) {
10997 if (mCharging != charging) {
10998 mCharging = charging;
10999 if (charging) {
Dianne Hackborn0c820db2015-04-14 17:47:34 -070011000 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070011001 } else {
Dianne Hackborn0c820db2015-04-14 17:47:34 -070011002 mHistoryCur.states2 &= ~HistoryItem.STATE2_CHARGING_FLAG;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070011003 }
11004 mHandler.sendEmptyMessage(MSG_REPORT_CHARGING);
11005 return true;
11006 }
11007 return false;
11008 }
11009
Mike Mac2f518a2017-09-19 16:06:03 -070011010 protected void setOnBatteryLocked(final long mSecRealtime, final long mSecUptime,
11011 final boolean onBattery, final int oldStatus, final int level, final int chargeUAh) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011012 boolean doWrite = false;
11013 Message m = mHandler.obtainMessage(MSG_REPORT_POWER_CHANGE);
11014 m.arg1 = onBattery ? 1 : 0;
11015 mHandler.sendMessage(m);
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011016
Dianne Hackborn40c87252014-03-19 16:55:40 -070011017 final long uptime = mSecUptime * 1000;
11018 final long realtime = mSecRealtime * 1000;
Mike Mac2f518a2017-09-19 16:06:03 -070011019 final int screenState = mScreenState;
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011020 if (onBattery) {
11021 // We will reset our status if we are unplugging after the
11022 // battery was last full, or the level is at 100, or
11023 // we have gone through a significant charge (from a very low
11024 // level to a now very high level).
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080011025 boolean reset = false;
Dianne Hackborn9a755432014-05-15 17:05:22 -070011026 if (!mNoAutoReset && (oldStatus == BatteryManager.BATTERY_STATUS_FULL
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011027 || level >= 90
Dianne Hackbornfb3809c2014-09-29 18:31:22 -070011028 || (mDischargeCurrentLevel < 20 && level >= 80)
11029 || (getHighDischargeAmountSinceCharge() >= 200
11030 && mHistoryBuffer.dataSize() >= MAX_HISTORY_BUFFER))) {
Dianne Hackborn73d6a822014-09-29 10:52:47 -070011031 Slog.i(TAG, "Resetting battery stats: level=" + level + " status=" + oldStatus
Dianne Hackbornfb3809c2014-09-29 18:31:22 -070011032 + " dischargeLevel=" + mDischargeCurrentLevel
Dianne Hackborn73d6a822014-09-29 10:52:47 -070011033 + " lowAmount=" + getLowDischargeAmountSinceCharge()
11034 + " highAmount=" + getHighDischargeAmountSinceCharge());
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011035 // Before we write, collect a snapshot of the final aggregated
11036 // stats to be reported in the next checkin. Only do this if we have
11037 // a sufficient amount of data to make it interesting.
11038 if (getLowDischargeAmountSinceCharge() >= 20) {
11039 final Parcel parcel = Parcel.obtain();
11040 writeSummaryToParcel(parcel, true);
11041 BackgroundThread.getHandler().post(new Runnable() {
11042 @Override public void run() {
11043 synchronized (mCheckinFile) {
11044 FileOutputStream stream = null;
11045 try {
11046 stream = mCheckinFile.startWrite();
11047 stream.write(parcel.marshall());
11048 stream.flush();
11049 FileUtils.sync(stream);
11050 stream.close();
11051 mCheckinFile.finishWrite(stream);
11052 } catch (IOException e) {
11053 Slog.w("BatteryStats",
11054 "Error writing checkin battery statistics", e);
11055 mCheckinFile.failWrite(stream);
11056 } finally {
11057 parcel.recycle();
11058 }
11059 }
11060 }
11061 });
11062 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011063 doWrite = true;
11064 resetAllStatsLocked();
Ying Wai (Daniel) Fan442ab762017-01-31 22:00:10 -080011065 if (chargeUAh > 0 && level > 0) {
Adam Lesinskif9b20a92016-06-17 17:30:01 -070011066 // Only use the reported coulomb charge value if it is supported and reported.
Ying Wai (Daniel) Fan9238b612017-01-18 15:50:19 -080011067 mEstimatedBatteryCapacity = (int) ((chargeUAh / 1000) / (level / 100.0));
Adam Lesinskif9b20a92016-06-17 17:30:01 -070011068 }
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011069 mDischargeStartLevel = level;
Dianne Hackborneaf2ac42014-02-07 13:01:07 -080011070 reset = true;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011071 mDischargeStepTracker.init();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011072 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070011073 if (mCharging) {
11074 setChargingLocked(false);
11075 }
11076 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -080011077 mOnBattery = mOnBatteryInternal = true;
Dianne Hackborn260c5022014-04-29 11:23:16 -070011078 mLastDischargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -070011079 mMinDischargeStepLevel = level;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011080 mDischargeStepTracker.clearTime();
11081 mDailyDischargeStepTracker.clearTime();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011082 mInitStepMode = mCurStepMode;
11083 mModStepMode = 0;
Dianne Hackborna7c837f2014-01-15 16:20:44 -080011084 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011085 mHistoryCur.batteryLevel = (byte)level;
11086 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
11087 if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: "
11088 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011089 if (reset) {
11090 mRecordingHistory = true;
11091 startRecordingHistory(mSecRealtime, mSecUptime, reset);
11092 }
Dianne Hackborn40c87252014-03-19 16:55:40 -070011093 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011094 mDischargeCurrentLevel = mDischargeUnplugLevel = level;
Mike Mac2f518a2017-09-19 16:06:03 -070011095 if (isScreenOn(screenState)) {
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011096 mDischargeScreenOnUnplugLevel = level;
Mike Mac2f518a2017-09-19 16:06:03 -070011097 mDischargeScreenDozeUnplugLevel = 0;
11098 mDischargeScreenOffUnplugLevel = 0;
11099 } else if (isScreenDoze(screenState)) {
11100 mDischargeScreenOnUnplugLevel = 0;
11101 mDischargeScreenDozeUnplugLevel = level;
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011102 mDischargeScreenOffUnplugLevel = 0;
11103 } else {
11104 mDischargeScreenOnUnplugLevel = 0;
Mike Mac2f518a2017-09-19 16:06:03 -070011105 mDischargeScreenDozeUnplugLevel = 0;
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011106 mDischargeScreenOffUnplugLevel = level;
11107 }
11108 mDischargeAmountScreenOn = 0;
Mike Mac2f518a2017-09-19 16:06:03 -070011109 mDischargeAmountScreenDoze = 0;
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011110 mDischargeAmountScreenOff = 0;
Mike Mac2f518a2017-09-19 16:06:03 -070011111 updateTimeBasesLocked(true, screenState, uptime, realtime);
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011112 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070011113 mLastChargingStateLevel = level;
Dianne Hackbornd1eccbe2015-02-18 14:02:14 -080011114 mOnBattery = mOnBatteryInternal = false;
Dianne Hackborna7c837f2014-01-15 16:20:44 -080011115 pullPendingStateUpdatesLocked();
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011116 mHistoryCur.batteryLevel = (byte)level;
11117 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
11118 if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: "
11119 + Integer.toHexString(mHistoryCur.states));
Dianne Hackborn40c87252014-03-19 16:55:40 -070011120 addHistoryRecordLocked(mSecRealtime, mSecUptime);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011121 mDischargeCurrentLevel = mDischargePlugLevel = level;
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011122 if (level < mDischargeUnplugLevel) {
11123 mLowDischargeAmountSinceCharge += mDischargeUnplugLevel-level-1;
11124 mHighDischargeAmountSinceCharge += mDischargeUnplugLevel-level;
11125 }
Mike Mac2f518a2017-09-19 16:06:03 -070011126 updateDischargeScreenLevelsLocked(screenState, screenState);
11127 updateTimeBasesLocked(false, screenState, uptime, realtime);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011128 mChargeStepTracker.init();
Dianne Hackborn260c5022014-04-29 11:23:16 -070011129 mLastChargeStepLevel = level;
Dianne Hackborn29325132014-05-21 15:01:03 -070011130 mMaxChargeStepLevel = level;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011131 mInitStepMode = mCurStepMode;
11132 mModStepMode = 0;
Dianne Hackborn32de2f62011-03-09 14:03:35 -080011133 }
11134 if (doWrite || (mLastWriteTime + (60 * 1000)) < mSecRealtime) {
11135 if (mFile != null) {
11136 writeAsyncLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011137 }
11138 }
11139 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011140
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011141 private void startRecordingHistory(final long elapsedRealtimeMs, final long uptimeMs,
11142 boolean reset) {
11143 mRecordingHistory = true;
11144 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn37de0982014-05-09 09:32:18 -070011145 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs,
11146 reset ? HistoryItem.CMD_RESET : HistoryItem.CMD_CURRENT_TIME,
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011147 mHistoryCur);
11148 mHistoryCur.currentTime = 0;
11149 if (reset) {
11150 initActiveHistoryEventsLocked(elapsedRealtimeMs, uptimeMs);
11151 }
11152 }
11153
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070011154 private void recordCurrentTimeChangeLocked(final long currentTime, final long elapsedRealtimeMs,
11155 final long uptimeMs) {
11156 if (mRecordingHistory) {
11157 mHistoryCur.currentTime = currentTime;
11158 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_CURRENT_TIME,
11159 mHistoryCur);
11160 mHistoryCur.currentTime = 0;
11161 }
11162 }
11163
Dianne Hackborn29cd7f12015-01-08 10:37:05 -080011164 private void recordShutdownLocked(final long elapsedRealtimeMs, final long uptimeMs) {
11165 if (mRecordingHistory) {
11166 mHistoryCur.currentTime = System.currentTimeMillis();
Dianne Hackborn29cd7f12015-01-08 10:37:05 -080011167 addHistoryBufferLocked(elapsedRealtimeMs, uptimeMs, HistoryItem.CMD_SHUTDOWN,
11168 mHistoryCur);
11169 mHistoryCur.currentTime = 0;
11170 }
11171 }
11172
Adam Lesinski9f55cc72016-01-27 20:42:14 -080011173 private void scheduleSyncExternalStatsLocked(String reason, int updateFlags) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011174 if (mExternalSync != null) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -080011175 mExternalSync.scheduleSync(reason, updateFlags);
Adam Lesinskia7c90c82015-06-18 14:52:24 -070011176 }
11177 }
11178
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011179 // This should probably be exposed in the API, though it's not critical
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011180 public static final int BATTERY_PLUGGED_NONE = 0;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011181
Bookatz8c6571b2017-10-24 15:04:41 -070011182 public void setBatteryStateLocked(final int status, final int health, final int plugType,
11183 final int level, /* not final */ int temp, final int volt, final int chargeUAh,
11184 final int chargeFullUAh) {
Adam Lesinski29ddfe52017-03-29 19:29:00 -070011185 // Temperature is encoded without the signed bit, so clamp any negative temperatures to 0.
11186 temp = Math.max(0, temp);
11187
Bookatz8c6571b2017-10-24 15:04:41 -070011188 reportChangesToStatsLog(mHaveBatteryLevel ? mHistoryCur : null,
11189 status, plugType, level, temp);
11190
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011191 final boolean onBattery = plugType == BATTERY_PLUGGED_NONE;
Joe Onoratoabded112016-02-08 16:49:39 -080011192 final long uptime = mClocks.uptimeMillis();
11193 final long elapsedRealtime = mClocks.elapsedRealtime();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011194 if (!mHaveBatteryLevel) {
11195 mHaveBatteryLevel = true;
11196 // We start out assuming that the device is plugged in (not
11197 // on battery). If our first report is now that we are indeed
11198 // plugged in, then twiddle our state to correctly reflect that
11199 // since we won't be going through the full setOnBattery().
11200 if (onBattery == mOnBattery) {
Dianne Hackborn260c5022014-04-29 11:23:16 -070011201 if (onBattery) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011202 mHistoryCur.states &= ~HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -070011203 } else {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011204 mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG;
Dianne Hackborn260c5022014-04-29 11:23:16 -070011205 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011206 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070011207 // Always start out assuming charging, that will be updated later.
Dianne Hackborn0c820db2015-04-14 17:47:34 -070011208 mHistoryCur.states2 |= HistoryItem.STATE2_CHARGING_FLAG;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011209 mHistoryCur.batteryStatus = (byte)status;
11210 mHistoryCur.batteryLevel = (byte)level;
Adam Lesinski3ee3f632016-06-08 13:55:55 -070011211 mHistoryCur.batteryChargeUAh = chargeUAh;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011212 mMaxChargeStepLevel = mMinDischargeStepLevel =
11213 mLastChargeStepLevel = mLastDischargeStepLevel = level;
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070011214 mLastChargingStateLevel = level;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011215 } else if (mCurrentBatteryLevel != level || mOnBattery != onBattery) {
11216 recordDailyStatsIfNeededLocked(level >= 100 && onBattery);
11217 }
11218 int oldStatus = mHistoryCur.batteryStatus;
11219 if (onBattery) {
11220 mDischargeCurrentLevel = level;
11221 if (!mRecordingHistory) {
11222 mRecordingHistory = true;
11223 startRecordingHistory(elapsedRealtime, uptime, true);
11224 }
11225 } else if (level < 96) {
11226 if (!mRecordingHistory) {
11227 mRecordingHistory = true;
11228 startRecordingHistory(elapsedRealtime, uptime, true);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011229 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011230 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011231 mCurrentBatteryLevel = level;
11232 if (mDischargePlugLevel < 0) {
11233 mDischargePlugLevel = level;
Marco Nelissend8593312009-04-30 14:45:06 -070011234 }
Adam Lesinski926969b2016-04-28 17:31:12 -070011235
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011236 if (onBattery != mOnBattery) {
11237 mHistoryCur.batteryLevel = (byte)level;
11238 mHistoryCur.batteryStatus = (byte)status;
11239 mHistoryCur.batteryHealth = (byte)health;
11240 mHistoryCur.batteryPlugType = (byte)plugType;
11241 mHistoryCur.batteryTemperature = (short)temp;
11242 mHistoryCur.batteryVoltage = (char)volt;
Adam Lesinski3ee3f632016-06-08 13:55:55 -070011243 if (chargeUAh < mHistoryCur.batteryChargeUAh) {
11244 // Only record discharges
11245 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh;
11246 mDischargeCounter.addCountLocked(chargeDiff);
11247 mDischargeScreenOffCounter.addCountLocked(chargeDiff);
Mike Mac2f518a2017-09-19 16:06:03 -070011248 if (isScreenDoze(mScreenState)) {
11249 mDischargeScreenDozeCounter.addCountLocked(chargeDiff);
11250 }
Adam Lesinski3ee3f632016-06-08 13:55:55 -070011251 }
Adam Lesinskia8018ac2016-05-03 10:18:10 -070011252 mHistoryCur.batteryChargeUAh = chargeUAh;
Adam Lesinskif9b20a92016-06-17 17:30:01 -070011253 setOnBatteryLocked(elapsedRealtime, uptime, onBattery, oldStatus, level, chargeUAh);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011254 } else {
11255 boolean changed = false;
11256 if (mHistoryCur.batteryLevel != level) {
11257 mHistoryCur.batteryLevel = (byte)level;
11258 changed = true;
Marco Nelissend8593312009-04-30 14:45:06 -070011259
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011260 // TODO(adamlesinski): Schedule the creation of a HistoryStepDetails record
11261 // which will pull external stats.
Adam Lesinski9f55cc72016-01-27 20:42:14 -080011262 scheduleSyncExternalStatsLocked("battery-level", ExternalStatsSync.UPDATE_ALL);
Evan Millarc64edde2009-04-18 12:26:32 -070011263 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011264 if (mHistoryCur.batteryStatus != status) {
11265 mHistoryCur.batteryStatus = (byte)status;
11266 changed = true;
11267 }
11268 if (mHistoryCur.batteryHealth != health) {
11269 mHistoryCur.batteryHealth = (byte)health;
11270 changed = true;
11271 }
11272 if (mHistoryCur.batteryPlugType != plugType) {
11273 mHistoryCur.batteryPlugType = (byte)plugType;
11274 changed = true;
11275 }
11276 if (temp >= (mHistoryCur.batteryTemperature+10)
11277 || temp <= (mHistoryCur.batteryTemperature-10)) {
11278 mHistoryCur.batteryTemperature = (short)temp;
11279 changed = true;
11280 }
11281 if (volt > (mHistoryCur.batteryVoltage+20)
11282 || volt < (mHistoryCur.batteryVoltage-20)) {
11283 mHistoryCur.batteryVoltage = (char)volt;
11284 changed = true;
11285 }
Adam Lesinskia8018ac2016-05-03 10:18:10 -070011286 if (chargeUAh >= (mHistoryCur.batteryChargeUAh+10)
11287 || chargeUAh <= (mHistoryCur.batteryChargeUAh-10)) {
Adam Lesinski3ee3f632016-06-08 13:55:55 -070011288 if (chargeUAh < mHistoryCur.batteryChargeUAh) {
11289 // Only record discharges
11290 final long chargeDiff = mHistoryCur.batteryChargeUAh - chargeUAh;
11291 mDischargeCounter.addCountLocked(chargeDiff);
11292 mDischargeScreenOffCounter.addCountLocked(chargeDiff);
Mike Mac2f518a2017-09-19 16:06:03 -070011293 if (isScreenDoze(mScreenState)) {
11294 mDischargeScreenDozeCounter.addCountLocked(chargeDiff);
11295 }
Adam Lesinski3ee3f632016-06-08 13:55:55 -070011296 }
Adam Lesinskia8018ac2016-05-03 10:18:10 -070011297 mHistoryCur.batteryChargeUAh = chargeUAh;
Adam Lesinski926969b2016-04-28 17:31:12 -070011298 changed = true;
11299 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011300 long modeBits = (((long)mInitStepMode) << STEP_LEVEL_INITIAL_MODE_SHIFT)
11301 | (((long)mModStepMode) << STEP_LEVEL_MODIFIED_MODE_SHIFT)
11302 | (((long)(level&0xff)) << STEP_LEVEL_LEVEL_SHIFT);
11303 if (onBattery) {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070011304 changed |= setChargingLocked(false);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011305 if (mLastDischargeStepLevel != level && mMinDischargeStepLevel > level) {
11306 mDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
11307 modeBits, elapsedRealtime);
11308 mDailyDischargeStepTracker.addLevelSteps(mLastDischargeStepLevel - level,
11309 modeBits, elapsedRealtime);
11310 mLastDischargeStepLevel = level;
11311 mMinDischargeStepLevel = level;
11312 mInitStepMode = mCurStepMode;
11313 mModStepMode = 0;
11314 }
11315 } else {
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070011316 if (level >= 90) {
11317 // If the battery level is at least 90%, always consider the device to be
11318 // charging even if it happens to go down a level.
11319 changed |= setChargingLocked(true);
11320 mLastChargeStepLevel = level;
11321 } if (!mCharging) {
11322 if (mLastChargeStepLevel < level) {
11323 // We have not reporting that we are charging, but the level has now
11324 // gone up, so consider the state to be charging.
11325 changed |= setChargingLocked(true);
11326 mLastChargeStepLevel = level;
11327 }
11328 } else {
11329 if (mLastChargeStepLevel > level) {
11330 // We had reported that the device was charging, but here we are with
11331 // power connected and the level going down. Looks like the current
11332 // power supplied isn't enough, so consider the device to now be
11333 // discharging.
11334 changed |= setChargingLocked(false);
11335 mLastChargeStepLevel = level;
11336 }
11337 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011338 if (mLastChargeStepLevel != level && mMaxChargeStepLevel < level) {
11339 mChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
11340 modeBits, elapsedRealtime);
11341 mDailyChargeStepTracker.addLevelSteps(level - mLastChargeStepLevel,
11342 modeBits, elapsedRealtime);
11343 mLastChargeStepLevel = level;
11344 mMaxChargeStepLevel = level;
11345 mInitStepMode = mCurStepMode;
11346 mModStepMode = 0;
Evan Millarc64edde2009-04-18 12:26:32 -070011347 }
11348 }
Dianne Hackborn4870e9d2015-04-08 16:55:47 -070011349 if (changed) {
11350 addHistoryRecordLocked(elapsedRealtime, uptime);
11351 }
Evan Millarc64edde2009-04-18 12:26:32 -070011352 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070011353 if (!onBattery && status == BatteryManager.BATTERY_STATUS_FULL) {
11354 // We don't record history while we are plugged in and fully charged.
11355 // The next time we are unplugged, history will be cleared.
11356 mRecordingHistory = DEBUG;
Dianne Hackbornd0c5b9a2014-02-21 16:19:05 -080011357 }
Adam Lesinski041d9172016-12-12 12:03:56 -080011358
Jocelyn Dangc627d102017-04-14 13:15:14 -070011359 if (mMinLearnedBatteryCapacity == -1) {
11360 mMinLearnedBatteryCapacity = chargeFullUAh;
11361 } else {
11362 Math.min(mMinLearnedBatteryCapacity, chargeFullUAh);
Adam Lesinski041d9172016-12-12 12:03:56 -080011363 }
Jocelyn Dangc627d102017-04-14 13:15:14 -070011364 mMaxLearnedBatteryCapacity = Math.max(mMaxLearnedBatteryCapacity, chargeFullUAh);
Adam Lesinski33dac552015-03-09 15:24:48 -070011365 }
11366
Bookatz8c6571b2017-10-24 15:04:41 -070011367 // Inform StatsLog of setBatteryState changes.
11368 // If this is the first reporting, pass in recentPast == null.
11369 private void reportChangesToStatsLog(HistoryItem recentPast,
11370 final int status, final int plugType, final int level, final int temp) {
11371
11372 if (recentPast == null || recentPast.batteryStatus != status) {
11373 StatsLog.write(StatsLog.CHARGING_STATE_CHANGED, status);
11374 }
11375 if (recentPast == null || recentPast.batteryPlugType != plugType) {
11376 StatsLog.write(StatsLog.PLUGGED_STATE_CHANGED, plugType);
11377 }
11378 if (recentPast == null || recentPast.batteryLevel != level) {
11379 StatsLog.write(StatsLog.BATTERY_LEVEL_CHANGED, level);
11380 }
11381 // Let's just always print the temperature, regardless of whether it changed.
11382 StatsLog.write(StatsLog.DEVICE_TEMPERATURE_REPORTED, temp);
11383 }
11384
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011385 public long getAwakeTimeBattery() {
11386 return computeBatteryUptime(getBatteryUptimeLocked(), STATS_CURRENT);
11387 }
11388
11389 public long getAwakeTimePlugged() {
Joe Onoratoabded112016-02-08 16:49:39 -080011390 return (mClocks.uptimeMillis() * 1000) - getAwakeTimeBattery();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011391 }
11392
11393 @Override
11394 public long computeUptime(long curTime, int which) {
11395 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011396 case STATS_SINCE_CHARGED: return mUptime + (curTime-mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011397 case STATS_CURRENT: return (curTime-mUptimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -070011398 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getUptimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011399 }
11400 return 0;
11401 }
11402
11403 @Override
11404 public long computeRealtime(long curTime, int which) {
11405 switch (which) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011406 case STATS_SINCE_CHARGED: return mRealtime + (curTime-mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011407 case STATS_CURRENT: return (curTime-mRealtimeStart);
Dianne Hackborn4590e522014-03-24 13:36:46 -070011408 case STATS_SINCE_UNPLUGGED: return (curTime-mOnBatteryTimeBase.getRealtimeStart());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011409 }
11410 return 0;
11411 }
11412
11413 @Override
11414 public long computeBatteryUptime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011415 return mOnBatteryTimeBase.computeUptime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011416 }
11417
11418 @Override
11419 public long computeBatteryRealtime(long curTime, int which) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011420 return mOnBatteryTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011421 }
11422
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011423 @Override
11424 public long computeBatteryScreenOffUptime(long curTime, int which) {
11425 return mOnBatteryScreenOffTimeBase.computeUptime(curTime, which);
11426 }
11427
11428 @Override
11429 public long computeBatteryScreenOffRealtime(long curTime, int which) {
11430 return mOnBatteryScreenOffTimeBase.computeRealtime(curTime, which);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011431 }
11432
Dianne Hackborn260c5022014-04-29 11:23:16 -070011433 private long computeTimePerLevel(long[] steps, int numSteps) {
11434 // For now we'll do a simple average across all steps.
11435 if (numSteps <= 0) {
11436 return -1;
11437 }
11438 long total = 0;
11439 for (int i=0; i<numSteps; i++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011440 total += steps[i] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -070011441 }
11442 return total / numSteps;
11443 /*
11444 long[] buckets = new long[numSteps];
11445 int numBuckets = 0;
11446 int numToAverage = 4;
11447 int i = 0;
11448 while (i < numSteps) {
11449 long totalTime = 0;
11450 int num = 0;
11451 for (int j=0; j<numToAverage && (i+j)<numSteps; j++) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011452 totalTime += steps[i+j] & STEP_LEVEL_TIME_MASK;
Dianne Hackborn260c5022014-04-29 11:23:16 -070011453 num++;
11454 }
11455 buckets[numBuckets] = totalTime / num;
11456 numBuckets++;
11457 numToAverage *= 2;
11458 i += num;
11459 }
11460 if (numBuckets < 1) {
11461 return -1;
11462 }
11463 long averageTime = buckets[numBuckets-1];
11464 for (i=numBuckets-2; i>=0; i--) {
11465 averageTime = (averageTime + buckets[i]) / 2;
11466 }
11467 return averageTime;
11468 */
11469 }
11470
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011471 @Override
11472 public long computeBatteryTimeRemaining(long curTime) {
11473 if (!mOnBattery) {
11474 return -1;
11475 }
Dianne Hackborn260c5022014-04-29 11:23:16 -070011476 /* Simple implementation just looks at the average discharge per level across the
11477 entire sample period.
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011478 int discharge = (getLowDischargeAmountSinceCharge()+getHighDischargeAmountSinceCharge())/2;
11479 if (discharge < 2) {
11480 return -1;
11481 }
11482 long duration = computeBatteryRealtime(curTime, STATS_SINCE_CHARGED);
11483 if (duration < 1000*1000) {
11484 return -1;
11485 }
11486 long usPerLevel = duration/discharge;
11487 return usPerLevel * mCurrentBatteryLevel;
Dianne Hackborn260c5022014-04-29 11:23:16 -070011488 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011489 if (mDischargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -070011490 return -1;
11491 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011492 long msPerLevel = mDischargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -070011493 if (msPerLevel <= 0) {
11494 return -1;
11495 }
11496 return (msPerLevel * mCurrentBatteryLevel) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011497 }
11498
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011499 @Override
11500 public LevelStepTracker getDischargeLevelStepTracker() {
11501 return mDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -070011502 }
11503
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011504 @Override
11505 public LevelStepTracker getDailyDischargeLevelStepTracker() {
11506 return mDailyDischargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -070011507 }
11508
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011509 @Override
11510 public long computeChargeTimeRemaining(long curTime) {
Dianne Hackborn260c5022014-04-29 11:23:16 -070011511 if (mOnBattery) {
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011512 // Not yet working.
11513 return -1;
11514 }
Dianne Hackborn260c5022014-04-29 11:23:16 -070011515 /* Broken
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011516 int curLevel = mCurrentBatteryLevel;
11517 int plugLevel = mDischargePlugLevel;
11518 if (plugLevel < 0 || curLevel < (plugLevel+1)) {
11519 return -1;
11520 }
11521 long duration = computeBatteryRealtime(curTime, STATS_SINCE_UNPLUGGED);
11522 if (duration < 1000*1000) {
11523 return -1;
11524 }
11525 long usPerLevel = duration/(curLevel-plugLevel);
11526 return usPerLevel * (100-curLevel);
Dianne Hackborn260c5022014-04-29 11:23:16 -070011527 */
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011528 if (mChargeStepTracker.mNumStepDurations < 1) {
Dianne Hackborn260c5022014-04-29 11:23:16 -070011529 return -1;
11530 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011531 long msPerLevel = mChargeStepTracker.computeTimePerLevel();
Dianne Hackborn260c5022014-04-29 11:23:16 -070011532 if (msPerLevel <= 0) {
11533 return -1;
11534 }
11535 return (msPerLevel * (100-mCurrentBatteryLevel)) * 1000;
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070011536 }
11537
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011538 @Override
11539 public LevelStepTracker getChargeLevelStepTracker() {
11540 return mChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -070011541 }
11542
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011543 @Override
11544 public LevelStepTracker getDailyChargeLevelStepTracker() {
11545 return mDailyChargeStepTracker;
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -070011546 }
11547
Dianne Hackborn88e98df2015-03-23 13:29:14 -070011548 @Override
11549 public ArrayList<PackageChange> getDailyPackageChanges() {
11550 return mDailyPackageChanges;
11551 }
11552
Joe Onoratoe1acd632016-02-23 13:25:10 -080011553 protected long getBatteryUptimeLocked() {
Joe Onoratoabded112016-02-08 16:49:39 -080011554 return mOnBatteryTimeBase.getUptime(mClocks.uptimeMillis() * 1000);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011555 }
11556
11557 @Override
11558 public long getBatteryUptime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011559 return mOnBatteryTimeBase.getUptime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011560 }
11561
11562 @Override
11563 public long getBatteryRealtime(long curTime) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080011564 return mOnBatteryTimeBase.getRealtime(curTime);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011565 }
Amith Yamasani3718aaa2009-06-09 06:32:35 -070011566
The Android Open Source Project10592532009-03-18 17:39:46 -070011567 @Override
Evan Millar633a1742009-04-02 16:36:33 -070011568 public int getDischargeStartLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -070011569 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -070011570 return getDischargeStartLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -070011571 }
11572 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011573
Evan Millar633a1742009-04-02 16:36:33 -070011574 public int getDischargeStartLevelLocked() {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011575 return mDischargeUnplugLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -070011576 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011577
The Android Open Source Project10592532009-03-18 17:39:46 -070011578 @Override
Evan Millar633a1742009-04-02 16:36:33 -070011579 public int getDischargeCurrentLevel() {
The Android Open Source Project10592532009-03-18 17:39:46 -070011580 synchronized(this) {
Evan Millar633a1742009-04-02 16:36:33 -070011581 return getDischargeCurrentLevelLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -070011582 }
11583 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011584
Evan Millar633a1742009-04-02 16:36:33 -070011585 public int getDischargeCurrentLevelLocked() {
Dianne Hackborne4a59512010-12-07 11:08:07 -080011586 return mDischargeCurrentLevel;
The Android Open Source Project10592532009-03-18 17:39:46 -070011587 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011588
Amith Yamasanie43530a2009-08-21 13:11:37 -070011589 @Override
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070011590 public int getLowDischargeAmountSinceCharge() {
11591 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -080011592 int val = mLowDischargeAmountSinceCharge;
11593 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
11594 val += mDischargeUnplugLevel-mDischargeCurrentLevel-1;
11595 }
11596 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070011597 }
11598 }
11599
11600 @Override
11601 public int getHighDischargeAmountSinceCharge() {
11602 synchronized(this) {
Dianne Hackborne4a59512010-12-07 11:08:07 -080011603 int val = mHighDischargeAmountSinceCharge;
11604 if (mOnBattery && mDischargeCurrentLevel < mDischargeUnplugLevel) {
11605 val += mDischargeUnplugLevel-mDischargeCurrentLevel;
11606 }
11607 return val;
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070011608 }
11609 }
Dianne Hackborn40c87252014-03-19 16:55:40 -070011610
11611 @Override
11612 public int getDischargeAmount(int which) {
11613 int dischargeAmount = which == STATS_SINCE_CHARGED
11614 ? getHighDischargeAmountSinceCharge()
11615 : (getDischargeStartLevel() - getDischargeCurrentLevel());
11616 if (dischargeAmount < 0) {
11617 dischargeAmount = 0;
11618 }
11619 return dischargeAmount;
11620 }
11621
Mike Mac2f518a2017-09-19 16:06:03 -070011622 @Override
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011623 public int getDischargeAmountScreenOn() {
11624 synchronized(this) {
11625 int val = mDischargeAmountScreenOn;
Mike Mac2f518a2017-09-19 16:06:03 -070011626 if (mOnBattery && isScreenOn(mScreenState)
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011627 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
11628 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
11629 }
11630 return val;
11631 }
11632 }
11633
Mike Mac2f518a2017-09-19 16:06:03 -070011634 @Override
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011635 public int getDischargeAmountScreenOnSinceCharge() {
11636 synchronized(this) {
11637 int val = mDischargeAmountScreenOnSinceCharge;
Mike Mac2f518a2017-09-19 16:06:03 -070011638 if (mOnBattery && isScreenOn(mScreenState)
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011639 && mDischargeCurrentLevel < mDischargeScreenOnUnplugLevel) {
11640 val += mDischargeScreenOnUnplugLevel-mDischargeCurrentLevel;
11641 }
11642 return val;
11643 }
11644 }
11645
Mike Mac2f518a2017-09-19 16:06:03 -070011646 @Override
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011647 public int getDischargeAmountScreenOff() {
11648 synchronized(this) {
11649 int val = mDischargeAmountScreenOff;
Mike Mac2f518a2017-09-19 16:06:03 -070011650 if (mOnBattery && isScreenOff(mScreenState)
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011651 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
11652 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
11653 }
Mike Mac2f518a2017-09-19 16:06:03 -070011654 // For backward compatibility, doze discharge is counted into screen off.
11655 return val + getDischargeAmountScreenDoze();
11656 }
11657 }
11658
11659 @Override
11660 public int getDischargeAmountScreenOffSinceCharge() {
11661 synchronized(this) {
11662 int val = mDischargeAmountScreenOffSinceCharge;
11663 if (mOnBattery && isScreenOff(mScreenState)
11664 && mDischargeCurrentLevel < mDischargeScreenOffUnplugLevel) {
11665 val += mDischargeScreenOffUnplugLevel-mDischargeCurrentLevel;
11666 }
11667 // For backward compatibility, doze discharge is counted into screen off.
11668 return val + getDischargeAmountScreenDozeSinceCharge();
11669 }
11670 }
11671
11672 @Override
11673 public int getDischargeAmountScreenDoze() {
11674 synchronized(this) {
11675 int val = mDischargeAmountScreenDoze;
11676 if (mOnBattery && isScreenDoze(mScreenState)
11677 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) {
11678 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel;
11679 }
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011680 return val;
11681 }
11682 }
11683
Mike Mac2f518a2017-09-19 16:06:03 -070011684 @Override
11685 public int getDischargeAmountScreenDozeSinceCharge() {
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011686 synchronized(this) {
Mike Mac2f518a2017-09-19 16:06:03 -070011687 int val = mDischargeAmountScreenDozeSinceCharge;
11688 if (mOnBattery && isScreenDoze(mScreenState)
11689 && mDischargeCurrentLevel < mDischargeScreenDozeUnplugLevel) {
11690 val += mDischargeScreenDozeUnplugLevel-mDischargeCurrentLevel;
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080011691 }
11692 return val;
11693 }
11694 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070011695
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011696 /**
11697 * Retrieve the statistics object for a particular uid, creating if needed.
11698 */
11699 public Uid getUidStatsLocked(int uid) {
11700 Uid u = mUidStats.get(uid);
11701 if (u == null) {
Joe Onoratoabded112016-02-08 16:49:39 -080011702 u = new Uid(this, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011703 mUidStats.put(uid, u);
11704 }
11705 return u;
11706 }
11707
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070011708 public void onCleanupUserLocked(int userId) {
11709 final int firstUidForUser = UserHandle.getUid(userId, 0);
11710 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1);
11711 mKernelUidCpuFreqTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
11712 mKernelUidCpuTimeReader.removeUidsInRange(firstUidForUser, lastUidForUser);
11713 }
11714
11715 public void onUserRemovedLocked(int userId) {
11716 final int firstUidForUser = UserHandle.getUid(userId, 0);
11717 final int lastUidForUser = UserHandle.getUid(userId, UserHandle.PER_USER_RANGE - 1);
11718 mUidStats.put(firstUidForUser, null);
11719 mUidStats.put(lastUidForUser, null);
11720 final int firstIndex = mUidStats.indexOfKey(firstUidForUser);
11721 final int lastIndex = mUidStats.indexOfKey(lastUidForUser);
11722 mUidStats.removeAtRange(firstIndex, lastIndex - firstIndex + 1);
11723 }
11724
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011725 /**
11726 * Remove the statistics object for a particular uid.
11727 */
11728 public void removeUidStatsLocked(int uid) {
Adam Lesinskib83ffee2015-05-12 14:43:47 -070011729 mKernelUidCpuTimeReader.removeUid(uid);
Sudheer Shanka6d8dcec2017-06-01 12:09:03 -070011730 mKernelUidCpuFreqTimeReader.removeUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011731 mUidStats.remove(uid);
11732 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -070011733
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011734 /**
11735 * Retrieve the statistics object for a particular process, creating
11736 * if needed.
11737 */
11738 public Uid.Proc getProcessStatsLocked(int uid, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -070011739 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011740 Uid u = getUidStatsLocked(uid);
11741 return u.getProcessStatsLocked(name);
11742 }
11743
11744 /**
11745 * Retrieve the statistics object for a particular process, creating
11746 * if needed.
11747 */
11748 public Uid.Pkg getPackageStatsLocked(int uid, String pkg) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -070011749 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011750 Uid u = getUidStatsLocked(uid);
11751 return u.getPackageStatsLocked(pkg);
11752 }
11753
11754 /**
11755 * Retrieve the statistics object for a particular service, creating
11756 * if needed.
11757 */
11758 public Uid.Pkg.Serv getServiceStatsLocked(int uid, String pkg, String name) {
Dianne Hackbornbbb74722014-03-13 09:50:24 -070011759 uid = mapUid(uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011760 Uid u = getUidStatsLocked(uid);
11761 return u.getServiceStatsLocked(pkg, name);
11762 }
11763
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011764 public void shutdownLocked() {
Joe Onoratoabded112016-02-08 16:49:39 -080011765 recordShutdownLocked(mClocks.elapsedRealtime(), mClocks.uptimeMillis());
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011766 writeSyncLocked();
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011767 mShuttingDown = true;
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011768 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011769
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011770 Parcel mPendingWrite = null;
11771 final ReentrantLock mWriteLock = new ReentrantLock();
11772
11773 public void writeAsyncLocked() {
11774 writeLocked(false);
11775 }
11776
11777 public void writeSyncLocked() {
11778 writeLocked(true);
11779 }
11780
11781 void writeLocked(boolean sync) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011782 if (mFile == null) {
11783 Slog.w("BatteryStats", "writeLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011784 return;
11785 }
11786
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070011787 if (mShuttingDown) {
11788 return;
11789 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011790
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011791 Parcel out = Parcel.obtain();
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011792 writeSummaryToParcel(out, true);
Joe Onoratoabded112016-02-08 16:49:39 -080011793 mLastWriteTime = mClocks.elapsedRealtime();
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011794
11795 if (mPendingWrite != null) {
11796 mPendingWrite.recycle();
11797 }
11798 mPendingWrite = out;
11799
11800 if (sync) {
11801 commitPendingDataToDisk();
11802 } else {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011803 BackgroundThread.getHandler().post(new Runnable() {
11804 @Override public void run() {
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011805 commitPendingDataToDisk();
11806 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011807 });
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011808 }
11809 }
11810
11811 public void commitPendingDataToDisk() {
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070011812 final Parcel next;
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011813 synchronized (this) {
11814 next = mPendingWrite;
11815 mPendingWrite = null;
Dianne Hackbornf47d8f22010-10-08 10:46:55 -070011816 if (next == null) {
11817 return;
11818 }
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011819 }
11820
Amith Yamasanid2450862017-02-07 15:58:24 -080011821 mWriteLock.lock();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011822 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011823 FileOutputStream stream = new FileOutputStream(mFile.chooseForWrite());
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011824 stream.write(next.marshall());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011825 stream.flush();
Dianne Hackborn8bdf5932010-10-15 12:54:40 -070011826 FileUtils.sync(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011827 stream.close();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011828 mFile.commit();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011829 } catch (IOException e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011830 Slog.w("BatteryStats", "Error writing battery statistics", e);
Dianne Hackbornce2ef762010-09-20 11:39:14 -070011831 mFile.rollback();
11832 } finally {
11833 next.recycle();
11834 mWriteLock.unlock();
Suchi Amalapurapu8550f252009-09-29 15:20:32 -070011835 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011836 }
11837
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011838 public void readLocked() {
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011839 if (mDailyFile != null) {
11840 readDailyStatsLocked();
11841 }
11842
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011843 if (mFile == null) {
11844 Slog.w("BatteryStats", "readLocked: no file associated with this instance");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011845 return;
11846 }
11847
11848 mUidStats.clear();
11849
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011850 try {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011851 File file = mFile.chooseForRead();
11852 if (!file.exists()) {
11853 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011854 }
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011855 FileInputStream stream = new FileInputStream(file);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011856
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011857 byte[] raw = BatteryStatsHelper.readFully(stream);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011858 Parcel in = Parcel.obtain();
11859 in.unmarshall(raw, 0, raw.length);
11860 in.setDataPosition(0);
11861 stream.close();
11862
11863 readSummaryFromParcel(in);
Dianne Hackborn00e25212014-02-19 10:49:24 -080011864 } catch(Exception e) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070011865 Slog.e("BatteryStats", "Error reading battery statistics", e);
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011866 resetAllStatsLocked();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011867 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011868
Dianne Hackborncd0e3352014-08-07 17:08:09 -070011869 mEndPlatformVersion = Build.ID;
11870
Dianne Hackborne5167ca2014-03-08 14:39:10 -080011871 if (mHistoryBuffer.dataPosition() > 0) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011872 mRecordingHistory = true;
Joe Onoratoabded112016-02-08 16:49:39 -080011873 final long elapsedRealtime = mClocks.elapsedRealtime();
11874 final long uptime = mClocks.uptimeMillis();
Dianne Hackborne5167ca2014-03-08 14:39:10 -080011875 if (USE_OLD_HISTORY) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011876 addHistoryRecordLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
Dianne Hackborne5167ca2014-03-08 14:39:10 -080011877 }
Dianne Hackborna1bd7922014-03-21 11:07:11 -070011878 addHistoryBufferLocked(elapsedRealtime, uptime, HistoryItem.CMD_START, mHistoryCur);
11879 startRecordingHistory(elapsedRealtime, uptime, false);
Dianne Hackborne8c88e62011-08-17 19:09:09 -070011880 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080011881
11882 recordDailyStatsIfNeededLocked(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080011883 }
11884
11885 public int describeContents() {
11886 return 0;
11887 }
11888
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011889 void readHistory(Parcel in, boolean andOldHistory) throws ParcelFormatException {
Dianne Hackbornae384452011-06-28 12:33:48 -070011890 final long historyBaseTime = in.readLong();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011891
11892 mHistoryBuffer.setDataSize(0);
11893 mHistoryBuffer.setDataPosition(0);
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011894 mHistoryTagPool.clear();
11895 mNextHistoryTagIdx = 0;
11896 mNumHistoryTagChars = 0;
Dianne Hackborn099bc622014-01-22 13:39:16 -080011897
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011898 int numTags = in.readInt();
11899 for (int i=0; i<numTags; i++) {
Dianne Hackborn099bc622014-01-22 13:39:16 -080011900 int idx = in.readInt();
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011901 String str = in.readString();
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011902 if (str == null) {
11903 throw new ParcelFormatException("null history tag string");
11904 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011905 int uid = in.readInt();
11906 HistoryTag tag = new HistoryTag();
11907 tag.string = str;
11908 tag.uid = uid;
11909 tag.poolIdx = idx;
11910 mHistoryTagPool.put(tag, idx);
11911 if (idx >= mNextHistoryTagIdx) {
11912 mNextHistoryTagIdx = idx+1;
Dianne Hackborn099bc622014-01-22 13:39:16 -080011913 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011914 mNumHistoryTagChars += tag.string.length() + 1;
Dianne Hackborn099bc622014-01-22 13:39:16 -080011915 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011916
11917 int bufSize = in.readInt();
11918 int curPos = in.dataPosition();
11919 if (bufSize >= (MAX_MAX_HISTORY_BUFFER*3)) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011920 throw new ParcelFormatException("File corrupt: history data buffer too large " +
11921 bufSize);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011922 } else if ((bufSize&~3) != bufSize) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070011923 throw new ParcelFormatException("File corrupt: history data buffer not aligned " +
11924 bufSize);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011925 } else {
11926 if (DEBUG_HISTORY) Slog.i(TAG, "***************** READING NEW HISTORY: " + bufSize
11927 + " bytes at " + curPos);
11928 mHistoryBuffer.appendFrom(in, curPos, bufSize);
11929 in.setDataPosition(curPos + bufSize);
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011930 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011931
Dianne Hackbornae384452011-06-28 12:33:48 -070011932 if (andOldHistory) {
11933 readOldHistory(in);
11934 }
11935
11936 if (DEBUG_HISTORY) {
11937 StringBuilder sb = new StringBuilder(128);
11938 sb.append("****************** OLD mHistoryBaseTime: ");
11939 TimeUtils.formatDuration(mHistoryBaseTime, sb);
11940 Slog.i(TAG, sb.toString());
11941 }
11942 mHistoryBaseTime = historyBaseTime;
11943 if (DEBUG_HISTORY) {
11944 StringBuilder sb = new StringBuilder(128);
11945 sb.append("****************** NEW mHistoryBaseTime: ");
11946 TimeUtils.formatDuration(mHistoryBaseTime, sb);
11947 Slog.i(TAG, sb.toString());
11948 }
11949
11950 // We are just arbitrarily going to insert 1 minute from the sample of
11951 // the last run until samples in this run.
11952 if (mHistoryBaseTime > 0) {
Joe Onoratoabded112016-02-08 16:49:39 -080011953 long oldnow = mClocks.elapsedRealtime();
Dianne Hackbornfdb19562014-07-11 16:03:36 -070011954 mHistoryBaseTime = mHistoryBaseTime - oldnow + 1;
Dianne Hackbornae384452011-06-28 12:33:48 -070011955 if (DEBUG_HISTORY) {
11956 StringBuilder sb = new StringBuilder(128);
11957 sb.append("****************** ADJUSTED mHistoryBaseTime: ");
11958 TimeUtils.formatDuration(mHistoryBaseTime, sb);
11959 Slog.i(TAG, sb.toString());
11960 }
Dianne Hackborn1e4b9f32010-06-23 14:10:57 -070011961 }
Dianne Hackborn32907cf2010-06-10 17:50:20 -070011962 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070011963
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011964 void readOldHistory(Parcel in) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -070011965 if (!USE_OLD_HISTORY) {
11966 return;
11967 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011968 mHistory = mHistoryEnd = mHistoryCache = null;
11969 long time;
Conley Owens5e3357f2011-05-02 09:59:30 -070011970 while (in.dataAvail() > 0 && (time=in.readLong()) >= 0) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011971 HistoryItem rec = new HistoryItem(time, in);
11972 addHistoryRecordLocked(rec);
11973 }
11974 }
11975
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011976 void writeHistory(Parcel out, boolean inclData, boolean andOldHistory) {
Dianne Hackbornae384452011-06-28 12:33:48 -070011977 if (DEBUG_HISTORY) {
11978 StringBuilder sb = new StringBuilder(128);
11979 sb.append("****************** WRITING mHistoryBaseTime: ");
11980 TimeUtils.formatDuration(mHistoryBaseTime, sb);
Dianne Hackborn40c87252014-03-19 16:55:40 -070011981 sb.append(" mLastHistoryElapsedRealtime: ");
11982 TimeUtils.formatDuration(mLastHistoryElapsedRealtime, sb);
Dianne Hackbornae384452011-06-28 12:33:48 -070011983 Slog.i(TAG, sb.toString());
11984 }
Dianne Hackborn40c87252014-03-19 16:55:40 -070011985 out.writeLong(mHistoryBaseTime + mLastHistoryElapsedRealtime);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070011986 if (!inclData) {
11987 out.writeInt(0);
11988 out.writeInt(0);
11989 return;
11990 }
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011991 out.writeInt(mHistoryTagPool.size());
11992 for (HashMap.Entry<HistoryTag, Integer> ent : mHistoryTagPool.entrySet()) {
11993 HistoryTag tag = ent.getKey();
Dianne Hackborn099bc622014-01-22 13:39:16 -080011994 out.writeInt(ent.getValue());
Dianne Hackborn71fc13e2014-02-03 10:50:53 -080011995 out.writeString(tag.string);
11996 out.writeInt(tag.uid);
Dianne Hackborn099bc622014-01-22 13:39:16 -080011997 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070011998 out.writeInt(mHistoryBuffer.dataSize());
11999 if (DEBUG_HISTORY) Slog.i(TAG, "***************** WRITING HISTORY: "
12000 + mHistoryBuffer.dataSize() + " bytes at " + out.dataPosition());
12001 out.appendFrom(mHistoryBuffer, 0, mHistoryBuffer.dataSize());
Dianne Hackbornae384452011-06-28 12:33:48 -070012002
12003 if (andOldHistory) {
12004 writeOldHistory(out);
12005 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070012006 }
12007
12008 void writeOldHistory(Parcel out) {
Dianne Hackborne8c88e62011-08-17 19:09:09 -070012009 if (!USE_OLD_HISTORY) {
12010 return;
12011 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012012 HistoryItem rec = mHistory;
Dianne Hackborn32907cf2010-06-10 17:50:20 -070012013 while (rec != null) {
12014 if (rec.time >= 0) rec.writeToParcel(out, 0);
12015 rec = rec.next;
12016 }
12017 out.writeLong(-1);
12018 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012019
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012020 public void readSummaryFromParcel(Parcel in) throws ParcelFormatException {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012021 final int version = in.readInt();
12022 if (version != VERSION) {
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012023 Slog.w("BatteryStats", "readFromParcel: version got " + version
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012024 + ", expected " + VERSION + "; erasing old stats");
12025 return;
12026 }
12027
Dianne Hackbornae384452011-06-28 12:33:48 -070012028 readHistory(in, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012029
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012030 mStartCount = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012031 mUptime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012032 mRealtime = in.readLong();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -080012033 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -070012034 mStartPlatformVersion = in.readString();
12035 mEndPlatformVersion = in.readString();
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012036 mOnBatteryTimeBase.readSummaryFromParcel(in);
12037 mOnBatteryScreenOffTimeBase.readSummaryFromParcel(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012038 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012039 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -070012040 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012041 mCurrentBatteryLevel = in.readInt();
Adam Lesinskif9b20a92016-06-17 17:30:01 -070012042 mEstimatedBatteryCapacity = in.readInt();
Jocelyn Dangc627d102017-04-14 13:15:14 -070012043 mMinLearnedBatteryCapacity = in.readInt();
12044 mMaxLearnedBatteryCapacity = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070012045 mLowDischargeAmountSinceCharge = in.readInt();
12046 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080012047 mDischargeAmountScreenOnSinceCharge = in.readInt();
12048 mDischargeAmountScreenOffSinceCharge = in.readInt();
Mike Mac2f518a2017-09-19 16:06:03 -070012049 mDischargeAmountScreenDozeSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080012050 mDischargeStepTracker.readFromParcel(in);
12051 mChargeStepTracker.readFromParcel(in);
12052 mDailyDischargeStepTracker.readFromParcel(in);
12053 mDailyChargeStepTracker.readFromParcel(in);
Adam Lesinski3ee3f632016-06-08 13:55:55 -070012054 mDischargeCounter.readSummaryFromParcelLocked(in);
12055 mDischargeScreenOffCounter.readSummaryFromParcelLocked(in);
Mike Mac2f518a2017-09-19 16:06:03 -070012056 mDischargeScreenDozeCounter.readSummaryFromParcelLocked(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070012057 int NPKG = in.readInt();
12058 if (NPKG > 0) {
12059 mDailyPackageChanges = new ArrayList<>(NPKG);
12060 while (NPKG > 0) {
12061 NPKG--;
12062 PackageChange pc = new PackageChange();
12063 pc.mPackageName = in.readString();
12064 pc.mUpdate = in.readInt() != 0;
12065 pc.mVersionCode = in.readInt();
12066 mDailyPackageChanges.add(pc);
12067 }
12068 } else {
12069 mDailyPackageChanges = null;
12070 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080012071 mDailyStartTime = in.readLong();
12072 mNextMinDailyDeadline = in.readLong();
12073 mNextMaxDailyDeadline = in.readLong();
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012074
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012075 mStartCount++;
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012076
Jeff Browne95c3cd2014-05-02 16:59:26 -070012077 mScreenState = Display.STATE_UNKNOWN;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012078 mScreenOnTimer.readSummaryFromParcelLocked(in);
Mike Mac2f518a2017-09-19 16:06:03 -070012079 mScreenDozeTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn617f8772009-03-31 15:04:46 -070012080 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
12081 mScreenBrightnessTimer[i].readSummaryFromParcelLocked(in);
12082 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070012083 mInteractive = false;
12084 mInteractiveTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012085 mPhoneOn = false;
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070012086 mPowerSaveModeEnabledTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn08c47a52015-10-15 12:38:14 -070012087 mLongestLightIdleTime = in.readLong();
12088 mLongestFullIdleTime = in.readLong();
12089 mDeviceIdleModeLightTimer.readSummaryFromParcelLocked(in);
12090 mDeviceIdleModeFullTimer.readSummaryFromParcelLocked(in);
12091 mDeviceLightIdlingTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070012092 mDeviceIdlingTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012093 mPhoneOnTimer.readSummaryFromParcelLocked(in);
Wink Saville52840902011-02-18 12:40:47 -080012094 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn627bba72009-03-24 22:32:56 -070012095 mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
12096 }
Amith Yamasanif37447b2009-10-08 18:28:01 -070012097 mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn627bba72009-03-24 22:32:56 -070012098 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
12099 mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
12100 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012101 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080012102 mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
12103 mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012104 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012105 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborne13c4c02014-02-11 17:18:35 -080012106 mMobileRadioActiveTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn77b987f2014-02-26 16:20:52 -080012107 mMobileRadioActivePerAppTimer.readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012108 mMobileRadioActiveAdjustedTime.readSummaryFromParcelLocked(in);
Dianne Hackbornd45665b2014-02-26 12:35:32 -080012109 mMobileRadioActiveUnknownTime.readSummaryFromParcelLocked(in);
12110 mMobileRadioActiveUnknownCount.readSummaryFromParcelLocked(in);
Dianne Hackborn0c820db2015-04-14 17:47:34 -070012111 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
The Android Open Source Project10592532009-03-18 17:39:46 -070012112 mWifiOn = false;
12113 mWifiOnTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070012114 mGlobalWifiRunning = false;
12115 mGlobalWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackbornca1bf212014-02-14 14:18:36 -080012116 for (int i=0; i<NUM_WIFI_STATES; i++) {
12117 mWifiStateTimer[i].readSummaryFromParcelLocked(in);
12118 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070012119 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
12120 mWifiSupplStateTimer[i].readSummaryFromParcelLocked(in);
12121 }
12122 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
12123 mWifiSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
12124 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080012125 mWifiActivity.readSummaryFromParcel(in);
12126 mBluetoothActivity.readSummaryFromParcel(in);
12127 mModemActivity.readSummaryFromParcel(in);
12128 mHasWifiReporting = in.readInt() != 0;
12129 mHasBluetoothReporting = in.readInt() != 0;
12130 mHasModemReporting = in.readInt() != 0;
Adam Lesinski33dac552015-03-09 15:24:48 -070012131
Dianne Hackborn1e01d162014-12-04 17:46:42 -080012132 mNumConnectivityChange = mLoadedNumConnectivityChange = in.readInt();
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012133 mFlashlightOnNesting = 0;
Dianne Hackbornabc7c492014-06-30 16:57:46 -070012134 mFlashlightOnTimer.readSummaryFromParcelLocked(in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012135 mCameraOnNesting = 0;
12136 mCameraOnTimer.readSummaryFromParcelLocked(in);
Adam Lesinski9f55cc72016-01-27 20:42:14 -080012137 mBluetoothScanNesting = 0;
12138 mBluetoothScanTimer.readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012139
Bookatz50df7112017-08-04 14:53:26 -070012140 int NRPMS = in.readInt();
12141 if (NRPMS > 10000) {
12142 throw new ParcelFormatException("File corrupt: too many rpm stats " + NRPMS);
12143 }
12144 for (int irpm = 0; irpm < NRPMS; irpm++) {
12145 if (in.readInt() != 0) {
12146 String rpmName = in.readString();
12147 getRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in);
12148 }
12149 }
12150 int NSORPMS = in.readInt();
12151 if (NSORPMS > 10000) {
12152 throw new ParcelFormatException("File corrupt: too many screen-off rpm stats " + NSORPMS);
12153 }
12154 for (int irpm = 0; irpm < NSORPMS; irpm++) {
12155 if (in.readInt() != 0) {
12156 String rpmName = in.readString();
12157 getScreenOffRpmTimerLocked(rpmName).readSummaryFromParcelLocked(in);
12158 }
12159 }
12160
Evan Millarc64edde2009-04-18 12:26:32 -070012161 int NKW = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012162 if (NKW > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012163 throw new ParcelFormatException("File corrupt: too many kernel wake locks " + NKW);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012164 }
Evan Millarc64edde2009-04-18 12:26:32 -070012165 for (int ikw = 0; ikw < NKW; ikw++) {
12166 if (in.readInt() != 0) {
12167 String kwltName = in.readString();
12168 getKernelWakelockTimerLocked(kwltName).readSummaryFromParcelLocked(in);
12169 }
12170 }
Amith Yamasanie43530a2009-08-21 13:11:37 -070012171
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012172 int NWR = in.readInt();
12173 if (NWR > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012174 throw new ParcelFormatException("File corrupt: too many wakeup reasons " + NWR);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012175 }
12176 for (int iwr = 0; iwr < NWR; iwr++) {
12177 if (in.readInt() != 0) {
12178 String reasonName = in.readString();
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070012179 getWakeupReasonTimerLocked(reasonName).readSummaryFromParcelLocked(in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012180 }
12181 }
12182
James Carr3a226052016-07-01 14:49:52 -070012183 int NMS = in.readInt();
12184 for (int ims = 0; ims < NMS; ims++) {
12185 if (in.readInt() != 0) {
12186 long kmstName = in.readLong();
12187 getKernelMemoryTimerLocked(kmstName).readSummaryFromParcelLocked(in);
12188 }
12189 }
12190
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012191 final int NU = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012192 if (NU > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012193 throw new ParcelFormatException("File corrupt: too many uids " + NU);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012194 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012195 for (int iu = 0; iu < NU; iu++) {
12196 int uid = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -080012197 Uid u = new Uid(this, uid);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012198 mUidStats.put(uid, u);
12199
Bookatz867c0d72017-03-07 18:23:42 -080012200 u.mOnBatteryBackgroundTimeBase.readSummaryFromParcel(in);
Bookatzc8c44962017-05-11 12:12:54 -070012201 u.mOnBatteryScreenOffBackgroundTimeBase.readSummaryFromParcel(in);
Bookatz867c0d72017-03-07 18:23:42 -080012202
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070012203 u.mWifiRunning = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012204 if (in.readInt() != 0) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070012205 u.mWifiRunningTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012206 }
The Android Open Source Project10592532009-03-18 17:39:46 -070012207 u.mFullWifiLockOut = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012208 if (in.readInt() != 0) {
12209 u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
12210 }
Nick Pelly6ccaa542012-06-15 15:22:47 -070012211 u.mWifiScanStarted = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012212 if (in.readInt() != 0) {
Nick Pelly6ccaa542012-06-15 15:22:47 -070012213 u.mWifiScanTimer.readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012214 }
Robert Greenwalta029ea12013-09-25 16:38:12 -070012215 u.mWifiBatchedScanBinStarted = Uid.NO_BATCHED_SCAN_STARTED;
12216 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
12217 if (in.readInt() != 0) {
12218 u.makeWifiBatchedScanBin(i, null);
12219 u.mWifiBatchedScanTimer[i].readSummaryFromParcelLocked(in);
12220 }
12221 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -070012222 u.mWifiMulticastEnabled = false;
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012223 if (in.readInt() != 0) {
12224 u.mWifiMulticastTimer.readSummaryFromParcelLocked(in);
12225 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012226 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -080012227 u.createAudioTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012228 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012229 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -080012230 u.createVideoTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
12231 }
12232 if (in.readInt() != 0) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012233 u.createFlashlightTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
12234 }
12235 if (in.readInt() != 0) {
12236 u.createCameraTurnedOnTimerLocked().readSummaryFromParcelLocked(in);
12237 }
12238 if (in.readInt() != 0) {
Jeff Sharkey3e013e82013-04-25 14:48:19 -070012239 u.createForegroundActivityTimerLocked().readSummaryFromParcelLocked(in);
12240 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -080012241 if (in.readInt() != 0) {
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -070012242 u.createForegroundServiceTimerLocked().readSummaryFromParcelLocked(in);
12243 }
12244 if (in.readInt() != 0) {
Bookatzc8c44962017-05-11 12:12:54 -070012245 u.createAggregatedPartialWakelockTimerLocked().readSummaryFromParcelLocked(in);
12246 }
12247 if (in.readInt() != 0) {
Adam Lesinski9f55cc72016-01-27 20:42:14 -080012248 u.createBluetoothScanTimerLocked().readSummaryFromParcelLocked(in);
12249 }
Bookatz956f36bf2017-04-28 09:48:17 -070012250 if (in.readInt() != 0) {
Bookatzb1f04f32017-05-19 13:57:32 -070012251 u.createBluetoothUnoptimizedScanTimerLocked().readSummaryFromParcelLocked(in);
12252 }
12253 if (in.readInt() != 0) {
Bookatz956f36bf2017-04-28 09:48:17 -070012254 u.createBluetoothScanResultCounterLocked().readSummaryFromParcelLocked(in);
12255 }
Bookatzb1f04f32017-05-19 13:57:32 -070012256 if (in.readInt() != 0) {
12257 u.createBluetoothScanResultBgCounterLocked().readSummaryFromParcelLocked(in);
12258 }
Dianne Hackborna8d10942015-11-19 17:55:19 -080012259 u.mProcessState = ActivityManager.PROCESS_STATE_NONEXISTENT;
Dianne Hackborn61659e52014-07-09 16:13:01 -070012260 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
12261 if (in.readInt() != 0) {
12262 u.makeProcessState(i, null);
12263 u.mProcessStateTimer[i].readSummaryFromParcelLocked(in);
12264 }
12265 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -070012266 if (in.readInt() != 0) {
Dianne Hackborna06de0f2012-12-11 16:34:47 -080012267 u.createVibratorOnTimerLocked().readSummaryFromParcelLocked(in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012268 }
Robert Greenwalt5347bd42009-05-13 15:10:16 -070012269
Dianne Hackborn617f8772009-03-31 15:04:46 -070012270 if (in.readInt() != 0) {
12271 if (u.mUserActivityCounters == null) {
12272 u.initUserActivityLocked();
12273 }
12274 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
12275 u.mUserActivityCounters[i].readSummaryFromParcelLocked(in);
12276 }
12277 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012278
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012279 if (in.readInt() != 0) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080012280 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012281 u.initNetworkActivityLocked();
12282 }
12283 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080012284 u.mNetworkByteActivityCounters[i].readSummaryFromParcelLocked(in);
12285 u.mNetworkPacketActivityCounters[i].readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012286 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -080012287 u.mMobileRadioActiveTime.readSummaryFromParcelLocked(in);
12288 u.mMobileRadioActiveCount.readSummaryFromParcelLocked(in);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012289 }
12290
Adam Lesinski06af1fa2015-05-05 17:35:35 -070012291 u.mUserCpuTime.readSummaryFromParcelLocked(in);
12292 u.mSystemCpuTime.readSummaryFromParcelLocked(in);
12293
Adam Lesinski6832f392015-09-05 18:05:40 -070012294 if (in.readInt() != 0) {
12295 final int numClusters = in.readInt();
12296 if (mPowerProfile != null && mPowerProfile.getNumCpuClusters() != numClusters) {
12297 throw new ParcelFormatException("Incompatible cpu cluster arrangement");
Adam Lesinski06af1fa2015-05-05 17:35:35 -070012298 }
Adam Lesinski6832f392015-09-05 18:05:40 -070012299
Sudheer Shankaaf857412017-07-21 00:14:24 -070012300 u.mCpuClusterSpeedTimesUs = new LongSamplingCounter[numClusters][];
Adam Lesinski6832f392015-09-05 18:05:40 -070012301 for (int cluster = 0; cluster < numClusters; cluster++) {
Adam Lesinski6832f392015-09-05 18:05:40 -070012302 if (in.readInt() != 0) {
Adam Lesinskia57a5402015-09-28 10:21:33 -070012303 final int NSB = in.readInt();
12304 if (mPowerProfile != null &&
12305 mPowerProfile.getNumSpeedStepsInCpuCluster(cluster) != NSB) {
12306 throw new ParcelFormatException("File corrupt: too many speed bins " +
12307 NSB);
12308 }
12309
Sudheer Shankaaf857412017-07-21 00:14:24 -070012310 u.mCpuClusterSpeedTimesUs[cluster] = new LongSamplingCounter[NSB];
Adam Lesinski6832f392015-09-05 18:05:40 -070012311 for (int speed = 0; speed < NSB; speed++) {
12312 if (in.readInt() != 0) {
Sudheer Shankaaf857412017-07-21 00:14:24 -070012313 u.mCpuClusterSpeedTimesUs[cluster][speed] = new LongSamplingCounter(
Adam Lesinski6832f392015-09-05 18:05:40 -070012314 mOnBatteryTimeBase);
Sudheer Shankaaf857412017-07-21 00:14:24 -070012315 u.mCpuClusterSpeedTimesUs[cluster][speed].readSummaryFromParcelLocked(in);
Adam Lesinski6832f392015-09-05 18:05:40 -070012316 }
12317 }
Adam Lesinskia57a5402015-09-28 10:21:33 -070012318 } else {
Sudheer Shankaaf857412017-07-21 00:14:24 -070012319 u.mCpuClusterSpeedTimesUs[cluster] = null;
Adam Lesinski6832f392015-09-05 18:05:40 -070012320 }
12321 }
12322 } else {
Sudheer Shankaaf857412017-07-21 00:14:24 -070012323 u.mCpuClusterSpeedTimesUs = null;
Adam Lesinski06af1fa2015-05-05 17:35:35 -070012324 }
12325
Sudheer Shanka59f5c002017-05-15 10:57:15 -070012326 u.mCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
12327 in, mOnBatteryTimeBase);
12328 u.mScreenOffCpuFreqTimeMs = LongSamplingCounterArray.readSummaryFromParcelLocked(
12329 in, mOnBatteryScreenOffTimeBase);
Sudheer Shanka9b735c52017-05-09 18:26:18 -070012330
12331 if (in.readInt() != 0) {
Adam Lesinski5f056f62016-07-14 16:56:08 -070012332 u.mMobileRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase);
12333 u.mMobileRadioApWakeupCount.readSummaryFromParcelLocked(in);
12334 } else {
12335 u.mMobileRadioApWakeupCount = null;
12336 }
12337
12338 if (in.readInt() != 0) {
12339 u.mWifiRadioApWakeupCount = new LongSamplingCounter(mOnBatteryTimeBase);
12340 u.mWifiRadioApWakeupCount.readSummaryFromParcelLocked(in);
12341 } else {
12342 u.mWifiRadioApWakeupCount = null;
12343 }
12344
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012345 int NW = in.readInt();
Dianne Hackborncb99a722016-10-03 17:00:02 -070012346 if (NW > (MAX_WAKELOCKS_PER_UID+1)) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012347 throw new ParcelFormatException("File corrupt: too many wake locks " + NW);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012348 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012349 for (int iw = 0; iw < NW; iw++) {
12350 String wlName = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -070012351 u.readWakeSummaryFromParcelLocked(wlName, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012352 }
12353
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012354 int NS = in.readInt();
Dianne Hackborncb99a722016-10-03 17:00:02 -070012355 if (NS > (MAX_WAKELOCKS_PER_UID+1)) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012356 throw new ParcelFormatException("File corrupt: too many syncs " + NS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012357 }
12358 for (int is = 0; is < NS; is++) {
12359 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -070012360 u.readSyncSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012361 }
12362
12363 int NJ = in.readInt();
Dianne Hackborncb99a722016-10-03 17:00:02 -070012364 if (NJ > (MAX_WAKELOCKS_PER_UID+1)) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012365 throw new ParcelFormatException("File corrupt: too many job timers " + NJ);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012366 }
12367 for (int ij = 0; ij < NJ; ij++) {
12368 String name = in.readString();
Dianne Hackbornd953c532014-08-16 18:17:38 -070012369 u.readJobSummaryFromParcelLocked(name, in);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012370 }
12371
Dianne Hackborn94326cb2017-06-28 16:17:20 -070012372 u.readJobCompletionsFromParcelLocked(in);
12373
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012374 int NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -080012375 if (NP > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012376 throw new ParcelFormatException("File corrupt: too many sensors " + NP);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012377 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012378 for (int is = 0; is < NP; is++) {
12379 int seNumber = in.readInt();
12380 if (in.readInt() != 0) {
Bookatz867c0d72017-03-07 18:23:42 -080012381 u.getSensorTimerLocked(seNumber, true).readSummaryFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012382 }
12383 }
12384
12385 NP = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -080012386 if (NP > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012387 throw new ParcelFormatException("File corrupt: too many processes " + NP);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012388 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012389 for (int ip = 0; ip < NP; ip++) {
12390 String procName = in.readString();
12391 Uid.Proc p = u.getProcessStatsLocked(procName);
12392 p.mUserTime = p.mLoadedUserTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012393 p.mSystemTime = p.mLoadedSystemTime = in.readLong();
Jeff Sharkey3e013e82013-04-25 14:48:19 -070012394 p.mForegroundTime = p.mLoadedForegroundTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012395 p.mStarts = p.mLoadedStarts = in.readInt();
Dianne Hackborn1e01d162014-12-04 17:46:42 -080012396 p.mNumCrashes = p.mLoadedNumCrashes = in.readInt();
12397 p.mNumAnrs = p.mLoadedNumAnrs = in.readInt();
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012398 p.readExcessivePowerFromParcelLocked(in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012399 }
12400
12401 NP = in.readInt();
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012402 if (NP > 10000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012403 throw new ParcelFormatException("File corrupt: too many packages " + NP);
Dianne Hackborn1afd1c92010-03-18 22:47:17 -070012404 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012405 for (int ip = 0; ip < NP; ip++) {
12406 String pkgName = in.readString();
12407 Uid.Pkg p = u.getPackageStatsLocked(pkgName);
Dianne Hackborn1e725a72015-03-24 18:23:19 -070012408 final int NWA = in.readInt();
12409 if (NWA > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012410 throw new ParcelFormatException("File corrupt: too many wakeup alarms " + NWA);
Dianne Hackborn1e725a72015-03-24 18:23:19 -070012411 }
12412 p.mWakeupAlarms.clear();
12413 for (int iwa=0; iwa<NWA; iwa++) {
12414 String tag = in.readString();
Bookatz98d4d5c2017-08-01 19:07:54 -070012415 Counter c = new Counter(mOnBatteryScreenOffTimeBase);
Dianne Hackborn1e725a72015-03-24 18:23:19 -070012416 c.readSummaryFromParcelLocked(in);
12417 p.mWakeupAlarms.put(tag, c);
12418 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012419 NS = in.readInt();
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -080012420 if (NS > 1000) {
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070012421 throw new ParcelFormatException("File corrupt: too many services " + NS);
Dianne Hackborn7b9c56f2010-12-07 11:14:53 -080012422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012423 for (int is = 0; is < NS; is++) {
12424 String servName = in.readString();
12425 Uid.Pkg.Serv s = u.getServiceStatsLocked(pkgName, servName);
12426 s.mStartTime = s.mLoadedStartTime = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012427 s.mStarts = s.mLoadedStarts = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012428 s.mLaunches = s.mLoadedLaunches = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012429 }
12430 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012431 }
12432 }
12433
12434 /**
12435 * Writes a summary of the statistics to a Parcel, in a format suitable to be written to
12436 * disk. This format does not allow a lossless round-trip.
12437 *
12438 * @param out the Parcel to be written to.
12439 */
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070012440 public void writeSummaryToParcel(Parcel out, boolean inclHistory) {
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -080012441 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070012442
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070012443 // Pull the clock time. This may update the time and make a new history entry
12444 // if we had originally pulled a time before the RTC was set.
12445 long startClockTime = getStartClockTime();
12446
Joe Onoratoabded112016-02-08 16:49:39 -080012447 final long NOW_SYS = mClocks.uptimeMillis() * 1000;
12448 final long NOWREAL_SYS = mClocks.elapsedRealtime() * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012449
12450 out.writeInt(VERSION);
12451
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070012452 writeHistory(out, inclHistory, true);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012453
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012454 out.writeInt(mStartCount);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012455 out.writeLong(computeUptime(NOW_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012456 out.writeLong(computeRealtime(NOWREAL_SYS, STATS_SINCE_CHARGED));
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070012457 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -070012458 out.writeString(mStartPlatformVersion);
12459 out.writeString(mEndPlatformVersion);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012460 mOnBatteryTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
12461 mOnBatteryScreenOffTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012462 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012463 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -070012464 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012465 out.writeInt(mCurrentBatteryLevel);
Adam Lesinskif9b20a92016-06-17 17:30:01 -070012466 out.writeInt(mEstimatedBatteryCapacity);
Jocelyn Dangc627d102017-04-14 13:15:14 -070012467 out.writeInt(mMinLearnedBatteryCapacity);
12468 out.writeInt(mMaxLearnedBatteryCapacity);
Dianne Hackborne4a59512010-12-07 11:08:07 -080012469 out.writeInt(getLowDischargeAmountSinceCharge());
12470 out.writeInt(getHighDischargeAmountSinceCharge());
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080012471 out.writeInt(getDischargeAmountScreenOnSinceCharge());
12472 out.writeInt(getDischargeAmountScreenOffSinceCharge());
Mike Mac2f518a2017-09-19 16:06:03 -070012473 out.writeInt(getDischargeAmountScreenDozeSinceCharge());
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080012474 mDischargeStepTracker.writeToParcel(out);
12475 mChargeStepTracker.writeToParcel(out);
12476 mDailyDischargeStepTracker.writeToParcel(out);
12477 mDailyChargeStepTracker.writeToParcel(out);
Adam Lesinski67c134f2016-06-10 15:15:08 -070012478 mDischargeCounter.writeSummaryFromParcelLocked(out);
12479 mDischargeScreenOffCounter.writeSummaryFromParcelLocked(out);
Mike Mac2f518a2017-09-19 16:06:03 -070012480 mDischargeScreenDozeCounter.writeSummaryFromParcelLocked(out);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070012481 if (mDailyPackageChanges != null) {
12482 final int NPKG = mDailyPackageChanges.size();
12483 out.writeInt(NPKG);
12484 for (int i=0; i<NPKG; i++) {
12485 PackageChange pc = mDailyPackageChanges.get(i);
12486 out.writeString(pc.mPackageName);
12487 out.writeInt(pc.mUpdate ? 1 : 0);
12488 out.writeInt(pc.mVersionCode);
12489 }
12490 } else {
12491 out.writeInt(0);
12492 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080012493 out.writeLong(mDailyStartTime);
12494 out.writeLong(mNextMinDailyDeadline);
12495 out.writeLong(mNextMaxDailyDeadline);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012496
12497 mScreenOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Mike Mac2f518a2017-09-19 16:06:03 -070012498 mScreenDozeTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -070012499 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012500 mScreenBrightnessTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn617f8772009-03-31 15:04:46 -070012501 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070012502 mInteractiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070012503 mPowerSaveModeEnabledTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn08c47a52015-10-15 12:38:14 -070012504 out.writeLong(mLongestLightIdleTime);
12505 out.writeLong(mLongestFullIdleTime);
12506 mDeviceIdleModeLightTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12507 mDeviceIdleModeFullTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12508 mDeviceLightIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070012509 mDeviceIdlingTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012510 mPhoneOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Wink Saville52840902011-02-18 12:40:47 -080012511 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012512 mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -070012513 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012514 mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -070012515 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012516 mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn627bba72009-03-24 22:32:56 -070012517 }
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012518 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080012519 mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
12520 mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012521 }
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012522 mMobileRadioActiveTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12523 mMobileRadioActivePerAppTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012524 mMobileRadioActiveAdjustedTime.writeSummaryFromParcelLocked(out);
Dianne Hackbornd45665b2014-02-26 12:35:32 -080012525 mMobileRadioActiveUnknownTime.writeSummaryFromParcelLocked(out);
12526 mMobileRadioActiveUnknownCount.writeSummaryFromParcelLocked(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012527 mWifiOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12528 mGlobalWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -080012529 for (int i=0; i<NUM_WIFI_STATES; i++) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012530 mWifiStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornca1bf212014-02-14 14:18:36 -080012531 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070012532 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
12533 mWifiSupplStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12534 }
12535 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
12536 mWifiSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12537 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080012538 mWifiActivity.writeSummaryToParcel(out);
12539 mBluetoothActivity.writeSummaryToParcel(out);
12540 mModemActivity.writeSummaryToParcel(out);
12541 out.writeInt(mHasWifiReporting ? 1 : 0);
12542 out.writeInt(mHasBluetoothReporting ? 1 : 0);
12543 out.writeInt(mHasModemReporting ? 1 : 0);
12544
Dianne Hackborn1e01d162014-12-04 17:46:42 -080012545 out.writeInt(mNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -070012546 mFlashlightOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012547 mCameraOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Adam Lesinski9f55cc72016-01-27 20:42:14 -080012548 mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012549
Bookatz50df7112017-08-04 14:53:26 -070012550 out.writeInt(mRpmStats.size());
12551 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) {
12552 Timer rpmt = ent.getValue();
12553 if (rpmt != null) {
12554 out.writeInt(1);
12555 out.writeString(ent.getKey());
12556 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12557 } else {
12558 out.writeInt(0);
12559 }
12560 }
12561 out.writeInt(mScreenOffRpmStats.size());
12562 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) {
12563 Timer rpmt = ent.getValue();
12564 if (rpmt != null) {
12565 out.writeInt(1);
12566 out.writeString(ent.getKey());
12567 rpmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12568 } else {
12569 out.writeInt(0);
12570 }
12571 }
12572
Evan Millarc64edde2009-04-18 12:26:32 -070012573 out.writeInt(mKernelWakelockStats.size());
12574 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
12575 Timer kwlt = ent.getValue();
12576 if (kwlt != null) {
12577 out.writeInt(1);
12578 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012579 kwlt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12580 } else {
12581 out.writeInt(0);
12582 }
12583 }
12584
12585 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070012586 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
12587 SamplingTimer timer = ent.getValue();
12588 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012589 out.writeInt(1);
12590 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070012591 timer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Evan Millarc64edde2009-04-18 12:26:32 -070012592 } else {
12593 out.writeInt(0);
12594 }
12595 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012596
James Carr3a226052016-07-01 14:49:52 -070012597 out.writeInt(mKernelMemoryStats.size());
12598 for (int i = 0; i < mKernelMemoryStats.size(); i++) {
12599 Timer kmt = mKernelMemoryStats.valueAt(i);
12600 if (kmt != null) {
12601 out.writeInt(1);
12602 out.writeLong(mKernelMemoryStats.keyAt(i));
12603 kmt.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12604 } else {
12605 out.writeInt(0);
12606 }
12607 }
12608
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012609 final int NU = mUidStats.size();
12610 out.writeInt(NU);
12611 for (int iu = 0; iu < NU; iu++) {
12612 out.writeInt(mUidStats.keyAt(iu));
12613 Uid u = mUidStats.valueAt(iu);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012614
Bookatz867c0d72017-03-07 18:23:42 -080012615 u.mOnBatteryBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Bookatzc8c44962017-05-11 12:12:54 -070012616 u.mOnBatteryScreenOffBackgroundTimeBase.writeSummaryToParcel(out, NOW_SYS, NOWREAL_SYS);
Bookatz867c0d72017-03-07 18:23:42 -080012617
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070012618 if (u.mWifiRunningTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012619 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012620 u.mWifiRunningTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012621 } else {
12622 out.writeInt(0);
12623 }
12624 if (u.mFullWifiLockTimer != null) {
12625 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012626 u.mFullWifiLockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012627 } else {
12628 out.writeInt(0);
12629 }
Nick Pelly6ccaa542012-06-15 15:22:47 -070012630 if (u.mWifiScanTimer != null) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012631 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012632 u.mWifiScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012633 } else {
12634 out.writeInt(0);
12635 }
Robert Greenwalta029ea12013-09-25 16:38:12 -070012636 for (int i = 0; i < Uid.NUM_WIFI_BATCHED_SCAN_BINS; i++) {
12637 if (u.mWifiBatchedScanTimer[i] != null) {
12638 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012639 u.mWifiBatchedScanTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Robert Greenwalta029ea12013-09-25 16:38:12 -070012640 } else {
12641 out.writeInt(0);
12642 }
12643 }
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012644 if (u.mWifiMulticastTimer != null) {
12645 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012646 u.mWifiMulticastTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012647 } else {
12648 out.writeInt(0);
12649 }
12650 if (u.mAudioTurnedOnTimer != null) {
12651 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012652 u.mAudioTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012653 } else {
12654 out.writeInt(0);
12655 }
12656 if (u.mVideoTurnedOnTimer != null) {
12657 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012658 u.mVideoTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070012659 } else {
12660 out.writeInt(0);
12661 }
Ruben Brunk6d2c3632015-05-26 17:32:16 -070012662 if (u.mFlashlightTurnedOnTimer != null) {
12663 out.writeInt(1);
12664 u.mFlashlightTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12665 } else {
12666 out.writeInt(0);
12667 }
12668 if (u.mCameraTurnedOnTimer != null) {
12669 out.writeInt(1);
12670 u.mCameraTurnedOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12671 } else {
12672 out.writeInt(0);
12673 }
Jeff Sharkey3e013e82013-04-25 14:48:19 -070012674 if (u.mForegroundActivityTimer != null) {
12675 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012676 u.mForegroundActivityTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Jeff Sharkey3e013e82013-04-25 14:48:19 -070012677 } else {
12678 out.writeInt(0);
12679 }
Michael Wachenschwanzb05a3c52017-07-07 17:47:04 -070012680 if (u.mForegroundServiceTimer != null) {
12681 out.writeInt(1);
12682 u.mForegroundServiceTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12683 } else {
12684 out.writeInt(0);
12685 }
Bookatzc8c44962017-05-11 12:12:54 -070012686 if (u.mAggregatedPartialWakelockTimer != null) {
12687 out.writeInt(1);
12688 u.mAggregatedPartialWakelockTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12689 } else {
12690 out.writeInt(0);
12691 }
Adam Lesinski9f55cc72016-01-27 20:42:14 -080012692 if (u.mBluetoothScanTimer != null) {
12693 out.writeInt(1);
12694 u.mBluetoothScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12695 } else {
12696 out.writeInt(0);
12697 }
Bookatzb1f04f32017-05-19 13:57:32 -070012698 if (u.mBluetoothUnoptimizedScanTimer != null) {
12699 out.writeInt(1);
12700 u.mBluetoothUnoptimizedScanTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12701 } else {
12702 out.writeInt(0);
12703 }
Bookatz956f36bf2017-04-28 09:48:17 -070012704 if (u.mBluetoothScanResultCounter != null) {
12705 out.writeInt(1);
12706 u.mBluetoothScanResultCounter.writeSummaryFromParcelLocked(out);
12707 } else {
12708 out.writeInt(0);
12709 }
Bookatzb1f04f32017-05-19 13:57:32 -070012710 if (u.mBluetoothScanResultBgCounter != null) {
12711 out.writeInt(1);
12712 u.mBluetoothScanResultBgCounter.writeSummaryFromParcelLocked(out);
12713 } else {
12714 out.writeInt(0);
12715 }
Dianne Hackborn61659e52014-07-09 16:13:01 -070012716 for (int i = 0; i < Uid.NUM_PROCESS_STATE; i++) {
12717 if (u.mProcessStateTimer[i] != null) {
12718 out.writeInt(1);
12719 u.mProcessStateTimer[i].writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12720 } else {
12721 out.writeInt(0);
12722 }
12723 }
Dianne Hackborna06de0f2012-12-11 16:34:47 -080012724 if (u.mVibratorOnTimer != null) {
12725 out.writeInt(1);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012726 u.mVibratorOnTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackborna06de0f2012-12-11 16:34:47 -080012727 } else {
12728 out.writeInt(0);
12729 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012730
Dianne Hackborn617f8772009-03-31 15:04:46 -070012731 if (u.mUserActivityCounters == null) {
12732 out.writeInt(0);
12733 } else {
12734 out.writeInt(1);
12735 for (int i=0; i<Uid.NUM_USER_ACTIVITY_TYPES; i++) {
12736 u.mUserActivityCounters[i].writeSummaryFromParcelLocked(out);
12737 }
12738 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012739
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080012740 if (u.mNetworkByteActivityCounters == null) {
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012741 out.writeInt(0);
12742 } else {
12743 out.writeInt(1);
12744 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
Dianne Hackborn57ed6a62013-12-09 18:15:56 -080012745 u.mNetworkByteActivityCounters[i].writeSummaryFromParcelLocked(out);
12746 u.mNetworkPacketActivityCounters[i].writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012747 }
Dianne Hackbornd45665b2014-02-26 12:35:32 -080012748 u.mMobileRadioActiveTime.writeSummaryFromParcelLocked(out);
12749 u.mMobileRadioActiveCount.writeSummaryFromParcelLocked(out);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -070012750 }
12751
Adam Lesinski06af1fa2015-05-05 17:35:35 -070012752 u.mUserCpuTime.writeSummaryFromParcelLocked(out);
12753 u.mSystemCpuTime.writeSummaryFromParcelLocked(out);
12754
Sudheer Shankaaf857412017-07-21 00:14:24 -070012755 if (u.mCpuClusterSpeedTimesUs != null) {
Adam Lesinski6832f392015-09-05 18:05:40 -070012756 out.writeInt(1);
Sudheer Shankaaf857412017-07-21 00:14:24 -070012757 out.writeInt(u.mCpuClusterSpeedTimesUs.length);
12758 for (LongSamplingCounter[] cpuSpeeds : u.mCpuClusterSpeedTimesUs) {
Adam Lesinski6832f392015-09-05 18:05:40 -070012759 if (cpuSpeeds != null) {
12760 out.writeInt(1);
12761 out.writeInt(cpuSpeeds.length);
12762 for (LongSamplingCounter c : cpuSpeeds) {
12763 if (c != null) {
12764 out.writeInt(1);
12765 c.writeSummaryFromParcelLocked(out);
12766 } else {
12767 out.writeInt(0);
12768 }
12769 }
12770 } else {
12771 out.writeInt(0);
12772 }
Adam Lesinski06af1fa2015-05-05 17:35:35 -070012773 }
Adam Lesinski6832f392015-09-05 18:05:40 -070012774 } else {
12775 out.writeInt(0);
Adam Lesinski06af1fa2015-05-05 17:35:35 -070012776 }
12777
Sudheer Shanka59f5c002017-05-15 10:57:15 -070012778 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mCpuFreqTimeMs);
12779 LongSamplingCounterArray.writeSummaryToParcelLocked(out, u.mScreenOffCpuFreqTimeMs);
Sudheer Shanka9b735c52017-05-09 18:26:18 -070012780
Adam Lesinski5f056f62016-07-14 16:56:08 -070012781 if (u.mMobileRadioApWakeupCount != null) {
12782 out.writeInt(1);
12783 u.mMobileRadioApWakeupCount.writeSummaryFromParcelLocked(out);
12784 } else {
12785 out.writeInt(0);
12786 }
12787
12788 if (u.mWifiRadioApWakeupCount != null) {
12789 out.writeInt(1);
12790 u.mWifiRadioApWakeupCount.writeSummaryFromParcelLocked(out);
12791 } else {
12792 out.writeInt(0);
12793 }
12794
Dianne Hackbornd953c532014-08-16 18:17:38 -070012795 final ArrayMap<String, Uid.Wakelock> wakeStats = u.mWakelockStats.getMap();
12796 int NW = wakeStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012797 out.writeInt(NW);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012798 for (int iw=0; iw<NW; iw++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -070012799 out.writeString(wakeStats.keyAt(iw));
12800 Uid.Wakelock wl = wakeStats.valueAt(iw);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012801 if (wl.mTimerFull != null) {
12802 out.writeInt(1);
12803 wl.mTimerFull.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12804 } else {
12805 out.writeInt(0);
12806 }
12807 if (wl.mTimerPartial != null) {
12808 out.writeInt(1);
12809 wl.mTimerPartial.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12810 } else {
12811 out.writeInt(0);
12812 }
12813 if (wl.mTimerWindow != null) {
12814 out.writeInt(1);
12815 wl.mTimerWindow.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12816 } else {
12817 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012818 }
Jeff Brown6a8bd7b2015-06-19 15:07:51 -070012819 if (wl.mTimerDraw != null) {
Adam Lesinski9425fe22015-06-19 12:02:13 -070012820 out.writeInt(1);
Jeff Brown6a8bd7b2015-06-19 15:07:51 -070012821 wl.mTimerDraw.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Adam Lesinski9425fe22015-06-19 12:02:13 -070012822 } else {
12823 out.writeInt(0);
12824 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012825 }
12826
Bookatz2bffb5b2017-04-13 11:59:33 -070012827 final ArrayMap<String, DualTimer> syncStats = u.mSyncStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -070012828 int NS = syncStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012829 out.writeInt(NS);
12830 for (int is=0; is<NS; is++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -070012831 out.writeString(syncStats.keyAt(is));
12832 syncStats.valueAt(is).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012833 }
12834
Bookatzaa4594a2017-03-24 12:39:56 -070012835 final ArrayMap<String, DualTimer> jobStats = u.mJobStats.getMap();
Dianne Hackbornd953c532014-08-16 18:17:38 -070012836 int NJ = jobStats.size();
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012837 out.writeInt(NJ);
12838 for (int ij=0; ij<NJ; ij++) {
Dianne Hackbornd953c532014-08-16 18:17:38 -070012839 out.writeString(jobStats.keyAt(ij));
12840 jobStats.valueAt(ij).writeSummaryFromParcelLocked(out, NOWREAL_SYS);
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012841 }
12842
Dianne Hackborn94326cb2017-06-28 16:17:20 -070012843 u.writeJobCompletionsToParcelLocked(out);
12844
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012845 int NSE = u.mSensorStats.size();
12846 out.writeInt(NSE);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012847 for (int ise=0; ise<NSE; ise++) {
12848 out.writeInt(u.mSensorStats.keyAt(ise));
12849 Uid.Sensor se = u.mSensorStats.valueAt(ise);
12850 if (se.mTimer != null) {
12851 out.writeInt(1);
12852 se.mTimer.writeSummaryFromParcelLocked(out, NOWREAL_SYS);
12853 } else {
12854 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012855 }
12856 }
12857
12858 int NP = u.mProcessStats.size();
12859 out.writeInt(NP);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012860 for (int ip=0; ip<NP; ip++) {
12861 out.writeString(u.mProcessStats.keyAt(ip));
12862 Uid.Proc ps = u.mProcessStats.valueAt(ip);
12863 out.writeLong(ps.mUserTime);
12864 out.writeLong(ps.mSystemTime);
12865 out.writeLong(ps.mForegroundTime);
12866 out.writeInt(ps.mStarts);
Dianne Hackborn1e01d162014-12-04 17:46:42 -080012867 out.writeInt(ps.mNumCrashes);
12868 out.writeInt(ps.mNumAnrs);
Dianne Hackborn61659e52014-07-09 16:13:01 -070012869 ps.writeExcessivePowerToParcelLocked(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012870 }
12871
12872 NP = u.mPackageStats.size();
12873 out.writeInt(NP);
12874 if (NP > 0) {
12875 for (Map.Entry<String, BatteryStatsImpl.Uid.Pkg> ent
12876 : u.mPackageStats.entrySet()) {
12877 out.writeString(ent.getKey());
12878 Uid.Pkg ps = ent.getValue();
Dianne Hackborn1e725a72015-03-24 18:23:19 -070012879 final int NWA = ps.mWakeupAlarms.size();
12880 out.writeInt(NWA);
12881 for (int iwa=0; iwa<NWA; iwa++) {
12882 out.writeString(ps.mWakeupAlarms.keyAt(iwa));
12883 ps.mWakeupAlarms.valueAt(iwa).writeSummaryFromParcelLocked(out);
12884 }
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012885 NS = ps.mServiceStats.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012886 out.writeInt(NS);
Dianne Hackborn1e725a72015-03-24 18:23:19 -070012887 for (int is=0; is<NS; is++) {
12888 out.writeString(ps.mServiceStats.keyAt(is));
12889 BatteryStatsImpl.Uid.Pkg.Serv ss = ps.mServiceStats.valueAt(is);
12890 long time = ss.getStartTimeToNowLocked(
12891 mOnBatteryTimeBase.getUptime(NOW_SYS));
12892 out.writeLong(time);
12893 out.writeInt(ss.mStarts);
12894 out.writeInt(ss.mLaunches);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012895 }
12896 }
12897 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012898 }
12899 }
12900
12901 public void readFromParcel(Parcel in) {
12902 readFromParcelLocked(in);
12903 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012904
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012905 void readFromParcelLocked(Parcel in) {
12906 int magic = in.readInt();
12907 if (magic != MAGIC) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -070012908 throw new ParcelFormatException("Bad magic number: #" + Integer.toHexString(magic));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012909 }
12910
Dianne Hackbornae384452011-06-28 12:33:48 -070012911 readHistory(in, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070012912
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012913 mStartCount = in.readInt();
Dianne Hackborn5f4a5f92014-01-24 16:59:34 -080012914 mStartClockTime = in.readLong();
Dianne Hackborncd0e3352014-08-07 17:08:09 -070012915 mStartPlatformVersion = in.readString();
12916 mEndPlatformVersion = in.readString();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012917 mUptime = in.readLong();
12918 mUptimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012919 mRealtime = in.readLong();
12920 mRealtimeStart = in.readLong();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012921 mOnBattery = in.readInt() != 0;
Adam Lesinskif9b20a92016-06-17 17:30:01 -070012922 mEstimatedBatteryCapacity = in.readInt();
Jocelyn Dangc627d102017-04-14 13:15:14 -070012923 mMinLearnedBatteryCapacity = in.readInt();
12924 mMaxLearnedBatteryCapacity = in.readInt();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080012925 mOnBatteryInternal = false; // we are no longer really running.
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012926 mOnBatteryTimeBase.readFromParcel(in);
12927 mOnBatteryScreenOffTimeBase.readFromParcel(in);
12928
Jeff Browne95c3cd2014-05-02 16:59:26 -070012929 mScreenState = Display.STATE_UNKNOWN;
Joe Onoratoabded112016-02-08 16:49:39 -080012930 mScreenOnTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in);
Mike Mac2f518a2017-09-19 16:06:03 -070012931 mScreenDozeTimer = new StopwatchTimer(mClocks, null, -1, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012932 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012933 mScreenBrightnessTimer[i] = new StopwatchTimer(mClocks, null, -100-i, null,
12934 mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012935 }
Dianne Hackborn29325132014-05-21 15:01:03 -070012936 mInteractive = false;
Joe Onoratoabded112016-02-08 16:49:39 -080012937 mInteractiveTimer = new StopwatchTimer(mClocks, null, -10, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012938 mPhoneOn = false;
Joe Onoratoabded112016-02-08 16:49:39 -080012939 mPowerSaveModeEnabledTimer = new StopwatchTimer(mClocks, null, -2, null,
12940 mOnBatteryTimeBase, in);
Dianne Hackborn08c47a52015-10-15 12:38:14 -070012941 mLongestLightIdleTime = in.readLong();
12942 mLongestFullIdleTime = in.readLong();
Joe Onoratoabded112016-02-08 16:49:39 -080012943 mDeviceIdleModeLightTimer = new StopwatchTimer(mClocks, null, -14, null,
12944 mOnBatteryTimeBase, in);
12945 mDeviceIdleModeFullTimer = new StopwatchTimer(mClocks, null, -11, null,
12946 mOnBatteryTimeBase, in);
12947 mDeviceLightIdlingTimer = new StopwatchTimer(mClocks, null, -15, null,
12948 mOnBatteryTimeBase, in);
12949 mDeviceIdlingTimer = new StopwatchTimer(mClocks, null, -12, null, mOnBatteryTimeBase, in);
12950 mPhoneOnTimer = new StopwatchTimer(mClocks, null, -3, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012951 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012952 mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -200-i,
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012953 null, mOnBatteryTimeBase, in);
12954 }
Joe Onoratoabded112016-02-08 16:49:39 -080012955 mPhoneSignalScanningTimer = new StopwatchTimer(mClocks, null, -200+1, null,
12956 mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012957 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012958 mPhoneDataConnectionsTimer[i] = new StopwatchTimer(mClocks, null, -300-i,
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012959 null, mOnBatteryTimeBase, in);
12960 }
12961 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
12962 mNetworkByteActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
12963 mNetworkPacketActivityCounters[i] = new LongSamplingCounter(mOnBatteryTimeBase, in);
12964 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070012965 mMobileRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Joe Onoratoabded112016-02-08 16:49:39 -080012966 mMobileRadioActiveTimer = new StopwatchTimer(mClocks, null, -400, null,
12967 mOnBatteryTimeBase, in);
Kweku Adams87b19ec2017-10-09 12:40:03 -070012968 mMobileRadioActivePerAppTimer = new StopwatchTimer(mClocks, null, -401, null,
Joe Onoratoabded112016-02-08 16:49:39 -080012969 mOnBatteryTimeBase, in);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070012970 mMobileRadioActiveAdjustedTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012971 mMobileRadioActiveUnknownTime = new LongSamplingCounter(mOnBatteryTimeBase, in);
12972 mMobileRadioActiveUnknownCount = new LongSamplingCounter(mOnBatteryTimeBase, in);
Dianne Hackborn0c820db2015-04-14 17:47:34 -070012973 mWifiRadioPowerState = DataConnectionRealTimeInfo.DC_POWER_STATE_LOW;
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012974 mWifiOn = false;
Joe Onoratoabded112016-02-08 16:49:39 -080012975 mWifiOnTimer = new StopwatchTimer(mClocks, null, -4, null, mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012976 mGlobalWifiRunning = false;
Joe Onoratoabded112016-02-08 16:49:39 -080012977 mGlobalWifiRunningTimer = new StopwatchTimer(mClocks, null, -5, null,
12978 mOnBatteryTimeBase, in);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012979 for (int i=0; i<NUM_WIFI_STATES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012980 mWifiStateTimer[i] = new StopwatchTimer(mClocks, null, -600-i,
Dianne Hackborn97ae5382014-03-05 16:43:25 -080012981 null, mOnBatteryTimeBase, in);
12982 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070012983 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012984 mWifiSupplStateTimer[i] = new StopwatchTimer(mClocks, null, -700-i,
Dianne Hackborn3251b902014-06-20 14:40:53 -070012985 null, mOnBatteryTimeBase, in);
12986 }
12987 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
Joe Onoratoabded112016-02-08 16:49:39 -080012988 mWifiSignalStrengthsTimer[i] = new StopwatchTimer(mClocks, null, -800-i,
Dianne Hackborn3251b902014-06-20 14:40:53 -070012989 null, mOnBatteryTimeBase, in);
12990 }
Adam Lesinski33dac552015-03-09 15:24:48 -070012991
Adam Lesinski21f76aa2016-01-25 12:27:06 -080012992 mWifiActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
12993 NUM_WIFI_TX_LEVELS, in);
12994 mBluetoothActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
12995 NUM_BT_TX_LEVELS, in);
12996 mModemActivity = new ControllerActivityCounterImpl(mOnBatteryTimeBase,
12997 ModemActivityInfo.TX_POWER_LEVELS, in);
12998 mHasWifiReporting = in.readInt() != 0;
12999 mHasBluetoothReporting = in.readInt() != 0;
13000 mHasModemReporting = in.readInt() != 0;
13001
Dianne Hackborn1e01d162014-12-04 17:46:42 -080013002 mNumConnectivityChange = in.readInt();
13003 mLoadedNumConnectivityChange = in.readInt();
13004 mUnpluggedNumConnectivityChange = in.readInt();
Dianne Hackborn10eaa852014-07-22 22:54:55 -070013005 mAudioOnNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080013006 mAudioOnTimer = new StopwatchTimer(mClocks, null, -7, null, mOnBatteryTimeBase);
Dianne Hackborn10eaa852014-07-22 22:54:55 -070013007 mVideoOnNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080013008 mVideoOnTimer = new StopwatchTimer(mClocks, null, -8, null, mOnBatteryTimeBase);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070013009 mFlashlightOnNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080013010 mFlashlightOnTimer = new StopwatchTimer(mClocks, null, -9, null, mOnBatteryTimeBase, in);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070013011 mCameraOnNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080013012 mCameraOnTimer = new StopwatchTimer(mClocks, null, -13, null, mOnBatteryTimeBase, in);
Adam Lesinski9f55cc72016-01-27 20:42:14 -080013013 mBluetoothScanNesting = 0;
Joe Onoratoabded112016-02-08 16:49:39 -080013014 mBluetoothScanTimer = new StopwatchTimer(mClocks, null, -14, null, mOnBatteryTimeBase, in);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070013015 mDischargeUnplugLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070013016 mDischargePlugLevel = in.readInt();
Evan Millar633a1742009-04-02 16:36:33 -070013017 mDischargeCurrentLevel = in.readInt();
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070013018 mCurrentBatteryLevel = in.readInt();
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013019 mLowDischargeAmountSinceCharge = in.readInt();
13020 mHighDischargeAmountSinceCharge = in.readInt();
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080013021 mDischargeAmountScreenOn = in.readInt();
13022 mDischargeAmountScreenOnSinceCharge = in.readInt();
13023 mDischargeAmountScreenOff = in.readInt();
13024 mDischargeAmountScreenOffSinceCharge = in.readInt();
Mike Mac2f518a2017-09-19 16:06:03 -070013025 mDischargeAmountScreenDoze = in.readInt();
13026 mDischargeAmountScreenDozeSinceCharge = in.readInt();
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080013027 mDischargeStepTracker.readFromParcel(in);
13028 mChargeStepTracker.readFromParcel(in);
Adam Lesinski3ee3f632016-06-08 13:55:55 -070013029 mDischargeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
Mike Mac2f518a2017-09-19 16:06:03 -070013030 mDischargeScreenOffCounter = new LongSamplingCounter(mOnBatteryScreenOffTimeBase, in);
13031 mDischargeScreenDozeCounter = new LongSamplingCounter(mOnBatteryTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013032 mLastWriteTime = in.readLong();
13033
Bookatz50df7112017-08-04 14:53:26 -070013034 mRpmStats.clear();
13035 int NRPMS = in.readInt();
13036 for (int irpm = 0; irpm < NRPMS; irpm++) {
13037 if (in.readInt() != 0) {
13038 String rpmName = in.readString();
13039 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in);
13040 mRpmStats.put(rpmName, rpmt);
13041 }
13042 }
13043 mScreenOffRpmStats.clear();
13044 int NSORPMS = in.readInt();
13045 for (int irpm = 0; irpm < NSORPMS; irpm++) {
13046 if (in.readInt() != 0) {
13047 String rpmName = in.readString();
13048 SamplingTimer rpmt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in);
13049 mScreenOffRpmStats.put(rpmName, rpmt);
13050 }
13051 }
13052
Evan Millarc64edde2009-04-18 12:26:32 -070013053 mKernelWakelockStats.clear();
13054 int NKW = in.readInt();
13055 for (int ikw = 0; ikw < NKW; ikw++) {
13056 if (in.readInt() != 0) {
13057 String wakelockName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -080013058 SamplingTimer kwlt = new SamplingTimer(mClocks, mOnBatteryScreenOffTimeBase, in);
Evan Millarc64edde2009-04-18 12:26:32 -070013059 mKernelWakelockStats.put(wakelockName, kwlt);
13060 }
13061 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070013062
Dianne Hackborna1bd7922014-03-21 11:07:11 -070013063 mWakeupReasonStats.clear();
13064 int NWR = in.readInt();
13065 for (int iwr = 0; iwr < NWR; iwr++) {
13066 if (in.readInt() != 0) {
13067 String reasonName = in.readString();
Joe Onoratoabded112016-02-08 16:49:39 -080013068 SamplingTimer timer = new SamplingTimer(mClocks, mOnBatteryTimeBase, in);
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070013069 mWakeupReasonStats.put(reasonName, timer);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070013070 }
13071 }
13072
James Carr3a226052016-07-01 14:49:52 -070013073 mKernelMemoryStats.clear();
13074 int nmt = in.readInt();
13075 for (int imt = 0; imt < nmt; imt++) {
13076 if (in.readInt() != 0) {
13077 Long bucket = in.readLong();
13078 SamplingTimer kmt = new SamplingTimer(mClocks, mOnBatteryTimeBase, in);
13079 mKernelMemoryStats.put(bucket, kmt);
13080 }
13081 }
13082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013083 mPartialTimers.clear();
13084 mFullTimers.clear();
13085 mWindowTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070013086 mWifiRunningTimers.clear();
13087 mFullWifiLockTimers.clear();
Nick Pelly6ccaa542012-06-15 15:22:47 -070013088 mWifiScanTimers.clear();
Robert Greenwalta029ea12013-09-25 16:38:12 -070013089 mWifiBatchedScanTimers.clear();
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070013090 mWifiMulticastTimers.clear();
Dianne Hackborn10eaa852014-07-22 22:54:55 -070013091 mAudioTurnedOnTimers.clear();
13092 mVideoTurnedOnTimers.clear();
Ruben Brunk6d2c3632015-05-26 17:32:16 -070013093 mFlashlightTurnedOnTimers.clear();
13094 mCameraTurnedOnTimers.clear();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013095
13096 int numUids = in.readInt();
13097 mUidStats.clear();
13098 for (int i = 0; i < numUids; i++) {
13099 int uid = in.readInt();
Joe Onoratoabded112016-02-08 16:49:39 -080013100 Uid u = new Uid(this, uid);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080013101 u.readFromParcelLocked(mOnBatteryTimeBase, mOnBatteryScreenOffTimeBase, in);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013102 mUidStats.append(uid, u);
13103 }
13104 }
13105
13106 public void writeToParcel(Parcel out, int flags) {
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013107 writeToParcelLocked(out, true, flags);
13108 }
13109
13110 public void writeToParcelWithoutUids(Parcel out, int flags) {
13111 writeToParcelLocked(out, false, flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013112 }
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070013113
13114 @SuppressWarnings("unused")
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013115 void writeToParcelLocked(Parcel out, boolean inclUids, int flags) {
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070013116 // Need to update with current kernel wake lock counts.
Dianne Hackborna7c837f2014-01-15 16:20:44 -080013117 pullPendingStateUpdatesLocked();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070013118
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070013119 // Pull the clock time. This may update the time and make a new history entry
13120 // if we had originally pulled a time before the RTC was set.
13121 long startClockTime = getStartClockTime();
13122
Joe Onoratoabded112016-02-08 16:49:39 -080013123 final long uSecUptime = mClocks.uptimeMillis() * 1000;
13124 final long uSecRealtime = mClocks.elapsedRealtime() * 1000;
Dianne Hackborn97ae5382014-03-05 16:43:25 -080013125 final long batteryRealtime = mOnBatteryTimeBase.getRealtime(uSecRealtime);
13126 final long batteryScreenOffRealtime = mOnBatteryScreenOffTimeBase.getRealtime(uSecRealtime);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070013127
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013128 out.writeInt(MAGIC);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070013129
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070013130 writeHistory(out, true, false);
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070013131
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013132 out.writeInt(mStartCount);
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070013133 out.writeLong(startClockTime);
Dianne Hackborncd0e3352014-08-07 17:08:09 -070013134 out.writeString(mStartPlatformVersion);
13135 out.writeString(mEndPlatformVersion);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013136 out.writeLong(mUptime);
13137 out.writeLong(mUptimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013138 out.writeLong(mRealtime);
13139 out.writeLong(mRealtimeStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013140 out.writeInt(mOnBattery ? 1 : 0);
Adam Lesinskif9b20a92016-06-17 17:30:01 -070013141 out.writeInt(mEstimatedBatteryCapacity);
Jocelyn Dangc627d102017-04-14 13:15:14 -070013142 out.writeInt(mMinLearnedBatteryCapacity);
13143 out.writeInt(mMaxLearnedBatteryCapacity);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080013144 mOnBatteryTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
13145 mOnBatteryScreenOffTimeBase.writeToParcel(out, uSecUptime, uSecRealtime);
13146
13147 mScreenOnTimer.writeToParcel(out, uSecRealtime);
Mike Mac2f518a2017-09-19 16:06:03 -070013148 mScreenDozeTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080013149 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
13150 mScreenBrightnessTimer[i].writeToParcel(out, uSecRealtime);
13151 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070013152 mInteractiveTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070013153 mPowerSaveModeEnabledTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn08c47a52015-10-15 12:38:14 -070013154 out.writeLong(mLongestLightIdleTime);
13155 out.writeLong(mLongestFullIdleTime);
13156 mDeviceIdleModeLightTimer.writeToParcel(out, uSecRealtime);
13157 mDeviceIdleModeFullTimer.writeToParcel(out, uSecRealtime);
13158 mDeviceLightIdlingTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn88e98df2015-03-23 13:29:14 -070013159 mDeviceIdlingTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080013160 mPhoneOnTimer.writeToParcel(out, uSecRealtime);
13161 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
13162 mPhoneSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
13163 }
13164 mPhoneSignalScanningTimer.writeToParcel(out, uSecRealtime);
13165 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
13166 mPhoneDataConnectionsTimer[i].writeToParcel(out, uSecRealtime);
13167 }
13168 for (int i = 0; i < NUM_NETWORK_ACTIVITY_TYPES; i++) {
13169 mNetworkByteActivityCounters[i].writeToParcel(out);
13170 mNetworkPacketActivityCounters[i].writeToParcel(out);
13171 }
13172 mMobileRadioActiveTimer.writeToParcel(out, uSecRealtime);
13173 mMobileRadioActivePerAppTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborna1bd7922014-03-21 11:07:11 -070013174 mMobileRadioActiveAdjustedTime.writeToParcel(out);
Dianne Hackborn97ae5382014-03-05 16:43:25 -080013175 mMobileRadioActiveUnknownTime.writeToParcel(out);
13176 mMobileRadioActiveUnknownCount.writeToParcel(out);
13177 mWifiOnTimer.writeToParcel(out, uSecRealtime);
13178 mGlobalWifiRunningTimer.writeToParcel(out, uSecRealtime);
13179 for (int i=0; i<NUM_WIFI_STATES; i++) {
13180 mWifiStateTimer[i].writeToParcel(out, uSecRealtime);
13181 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070013182 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
13183 mWifiSupplStateTimer[i].writeToParcel(out, uSecRealtime);
13184 }
13185 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
13186 mWifiSignalStrengthsTimer[i].writeToParcel(out, uSecRealtime);
13187 }
Adam Lesinski21f76aa2016-01-25 12:27:06 -080013188 mWifiActivity.writeToParcel(out, 0);
13189 mBluetoothActivity.writeToParcel(out, 0);
13190 mModemActivity.writeToParcel(out, 0);
13191 out.writeInt(mHasWifiReporting ? 1 : 0);
13192 out.writeInt(mHasBluetoothReporting ? 1 : 0);
13193 out.writeInt(mHasModemReporting ? 1 : 0);
13194
Dianne Hackborn1e01d162014-12-04 17:46:42 -080013195 out.writeInt(mNumConnectivityChange);
13196 out.writeInt(mLoadedNumConnectivityChange);
13197 out.writeInt(mUnpluggedNumConnectivityChange);
Dianne Hackbornabc7c492014-06-30 16:57:46 -070013198 mFlashlightOnTimer.writeToParcel(out, uSecRealtime);
Ruben Brunk6d2c3632015-05-26 17:32:16 -070013199 mCameraOnTimer.writeToParcel(out, uSecRealtime);
Adam Lesinski9f55cc72016-01-27 20:42:14 -080013200 mBluetoothScanTimer.writeToParcel(out, uSecRealtime);
Dianne Hackborn6b7b4842010-06-14 17:17:44 -070013201 out.writeInt(mDischargeUnplugLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070013202 out.writeInt(mDischargePlugLevel);
Evan Millar633a1742009-04-02 16:36:33 -070013203 out.writeInt(mDischargeCurrentLevel);
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070013204 out.writeInt(mCurrentBatteryLevel);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013205 out.writeInt(mLowDischargeAmountSinceCharge);
13206 out.writeInt(mHighDischargeAmountSinceCharge);
Dianne Hackbornc1b40e32011-01-05 18:27:40 -080013207 out.writeInt(mDischargeAmountScreenOn);
13208 out.writeInt(mDischargeAmountScreenOnSinceCharge);
13209 out.writeInt(mDischargeAmountScreenOff);
13210 out.writeInt(mDischargeAmountScreenOffSinceCharge);
Mike Mac2f518a2017-09-19 16:06:03 -070013211 out.writeInt(mDischargeAmountScreenDoze);
13212 out.writeInt(mDischargeAmountScreenDozeSinceCharge);
Dianne Hackbornd4a8af72015-03-03 10:06:15 -080013213 mDischargeStepTracker.writeToParcel(out);
13214 mChargeStepTracker.writeToParcel(out);
Adam Lesinski3ee3f632016-06-08 13:55:55 -070013215 mDischargeCounter.writeToParcel(out);
13216 mDischargeScreenOffCounter.writeToParcel(out);
Mike Mac2f518a2017-09-19 16:06:03 -070013217 mDischargeScreenDozeCounter.writeToParcel(out);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013218 out.writeLong(mLastWriteTime);
13219
Bookatz50df7112017-08-04 14:53:26 -070013220 out.writeInt(mRpmStats.size());
13221 for (Map.Entry<String, SamplingTimer> ent : mRpmStats.entrySet()) {
13222 SamplingTimer rpmt = ent.getValue();
13223 if (rpmt != null) {
13224 out.writeInt(1);
13225 out.writeString(ent.getKey());
13226 rpmt.writeToParcel(out, uSecRealtime);
13227 } else {
13228 out.writeInt(0);
13229 }
13230 }
13231 out.writeInt(mScreenOffRpmStats.size());
13232 for (Map.Entry<String, SamplingTimer> ent : mScreenOffRpmStats.entrySet()) {
13233 SamplingTimer rpmt = ent.getValue();
13234 if (rpmt != null) {
13235 out.writeInt(1);
13236 out.writeString(ent.getKey());
13237 rpmt.writeToParcel(out, uSecRealtime);
13238 } else {
13239 out.writeInt(0);
13240 }
13241 }
13242
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013243 if (inclUids) {
13244 out.writeInt(mKernelWakelockStats.size());
13245 for (Map.Entry<String, SamplingTimer> ent : mKernelWakelockStats.entrySet()) {
13246 SamplingTimer kwlt = ent.getValue();
13247 if (kwlt != null) {
13248 out.writeInt(1);
13249 out.writeString(ent.getKey());
Dianne Hackborna1bd7922014-03-21 11:07:11 -070013250 kwlt.writeToParcel(out, uSecRealtime);
13251 } else {
13252 out.writeInt(0);
13253 }
13254 }
13255 out.writeInt(mWakeupReasonStats.size());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070013256 for (Map.Entry<String, SamplingTimer> ent : mWakeupReasonStats.entrySet()) {
13257 SamplingTimer timer = ent.getValue();
13258 if (timer != null) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -070013259 out.writeInt(1);
13260 out.writeString(ent.getKey());
Dianne Hackbornc3940bc2014-09-05 15:50:25 -070013261 timer.writeToParcel(out, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013262 } else {
13263 out.writeInt(0);
13264 }
Evan Millarc64edde2009-04-18 12:26:32 -070013265 }
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013266 } else {
Bookatzba78b2b2017-10-10 11:06:33 -070013267 out.writeInt(0);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013268 out.writeInt(0);
Evan Millarc64edde2009-04-18 12:26:32 -070013269 }
Amith Yamasanie43530a2009-08-21 13:11:37 -070013270
James Carr3a226052016-07-01 14:49:52 -070013271 out.writeInt(mKernelMemoryStats.size());
13272 for (int i = 0; i < mKernelMemoryStats.size(); i++) {
13273 SamplingTimer kmt = mKernelMemoryStats.valueAt(i);
13274 if (kmt != null) {
13275 out.writeInt(1);
13276 out.writeLong(mKernelMemoryStats.keyAt(i));
13277 kmt.writeToParcel(out, uSecRealtime);
13278 } else {
13279 out.writeInt(0);
13280 }
13281 }
13282
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013283 if (inclUids) {
13284 int size = mUidStats.size();
13285 out.writeInt(size);
13286 for (int i = 0; i < size; i++) {
13287 out.writeInt(mUidStats.keyAt(i));
13288 Uid uid = mUidStats.valueAt(i);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013289
Bookatz867c0d72017-03-07 18:23:42 -080013290 uid.writeToParcelLocked(out, uSecUptime, uSecRealtime);
Dianne Hackborn3bee5af82010-07-23 00:22:04 -070013291 }
13292 } else {
13293 out.writeInt(0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013294 }
13295 }
13296
13297 public static final Parcelable.Creator<BatteryStatsImpl> CREATOR =
13298 new Parcelable.Creator<BatteryStatsImpl>() {
13299 public BatteryStatsImpl createFromParcel(Parcel in) {
13300 return new BatteryStatsImpl(in);
13301 }
13302
13303 public BatteryStatsImpl[] newArray(int size) {
13304 return new BatteryStatsImpl[size];
13305 }
13306 };
Jaikumar Ganesh5a1e4cf2010-10-18 17:05:09 -070013307
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070013308 public void prepareForDumpLocked() {
13309 // Need to retrieve current kernel wake lock stats before printing.
Dianne Hackborna7c837f2014-01-15 16:20:44 -080013310 pullPendingStateUpdatesLocked();
Dianne Hackborn7d9eefd2014-08-27 18:30:31 -070013311
13312 // Pull the clock time. This may update the time and make a new history entry
13313 // if we had originally pulled a time before the RTC was set.
13314 getStartClockTime();
Dianne Hackborn0ffc9882011-04-13 18:15:56 -070013315 }
13316
Dianne Hackbornc51cf032014-03-02 19:08:15 -080013317 public void dumpLocked(Context context, PrintWriter pw, int flags, int reqUid, long histStart) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013318 if (DEBUG) {
Dianne Hackborn97ae5382014-03-05 16:43:25 -080013319 pw.println("mOnBatteryTimeBase:");
13320 mOnBatteryTimeBase.dump(pw, " ");
13321 pw.println("mOnBatteryScreenOffTimeBase:");
13322 mOnBatteryScreenOffTimeBase.dump(pw, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070013323 Printer pr = new PrintWriterPrinter(pw);
Mike Mac2f518a2017-09-19 16:06:03 -070013324 pr.println("*** Screen on timer:");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070013325 mScreenOnTimer.logState(pr, " ");
Mike Mac2f518a2017-09-19 16:06:03 -070013326 pr.println("*** Screen doze timer:");
13327 mScreenDozeTimer.logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -070013328 for (int i=0; i<NUM_SCREEN_BRIGHTNESS_BINS; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070013329 pr.println("*** Screen brightness #" + i + ":");
13330 mScreenBrightnessTimer[i].logState(pr, " ");
Dianne Hackborn617f8772009-03-31 15:04:46 -070013331 }
Jeff Browne95c3cd2014-05-02 16:59:26 -070013332 pr.println("*** Interactive timer:");
13333 mInteractiveTimer.logState(pr, " ");
Dianne Hackborn8ad2af72015-03-17 17:00:24 -070013334 pr.println("*** Power save mode timer:");
13335 mPowerSaveModeEnabledTimer.logState(pr, " ");
Dianne Hackborn08c47a52015-10-15 12:38:14 -070013336 pr.println("*** Device idle mode light timer:");
13337 mDeviceIdleModeLightTimer.logState(pr, " ");
13338 pr.println("*** Device idle mode full timer:");
13339 mDeviceIdleModeFullTimer.logState(pr, " ");
13340 pr.println("*** Device light idling timer:");
13341 mDeviceLightIdlingTimer.logState(pr, " ");
Dianne Hackborn88e98df2015-03-23 13:29:14 -070013342 pr.println("*** Device idling timer:");
13343 mDeviceIdlingTimer.logState(pr, " ");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070013344 pr.println("*** Phone timer:");
13345 mPhoneOnTimer.logState(pr, " ");
Wink Saville52840902011-02-18 12:40:47 -080013346 for (int i=0; i<SignalStrength.NUM_SIGNAL_STRENGTH_BINS; i++) {
Dianne Hackborn3251b902014-06-20 14:40:53 -070013347 pr.println("*** Phone signal strength #" + i + ":");
Dianne Hackborn1d442e02009-04-20 18:14:05 -070013348 mPhoneSignalStrengthsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -070013349 }
Amith Yamasanif37447b2009-10-08 18:28:01 -070013350 pr.println("*** Signal scanning :");
13351 mPhoneSignalScanningTimer.logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -070013352 for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
Dianne Hackborn1d442e02009-04-20 18:14:05 -070013353 pr.println("*** Data connection type #" + i + ":");
13354 mPhoneDataConnectionsTimer[i].logState(pr, " ");
Dianne Hackborn627bba72009-03-24 22:32:56 -070013355 }
Dianne Hackborn2ffa11e2014-04-21 15:56:18 -070013356 pr.println("*** mMobileRadioPowerState=" + mMobileRadioPowerState);
Dianne Hackborne13c4c02014-02-11 17:18:35 -080013357 pr.println("*** Mobile network active timer:");
13358 mMobileRadioActiveTimer.logState(pr, " ");
Dianne Hackborna1bd7922014-03-21 11:07:11 -070013359 pr.println("*** Mobile network active adjusted timer:");
13360 mMobileRadioActiveAdjustedTime.logState(pr, " ");
Dianne Hackborn0c820db2015-04-14 17:47:34 -070013361 pr.println("*** mWifiRadioPowerState=" + mWifiRadioPowerState);
Dianne Hackborn1d442e02009-04-20 18:14:05 -070013362 pr.println("*** Wifi timer:");
13363 mWifiOnTimer.logState(pr, " ");
13364 pr.println("*** WifiRunning timer:");
Dianne Hackborn58e0eef2010-09-16 01:22:10 -070013365 mGlobalWifiRunningTimer.logState(pr, " ");
Dianne Hackbornca1bf212014-02-14 14:18:36 -080013366 for (int i=0; i<NUM_WIFI_STATES; i++) {
13367 pr.println("*** Wifi state #" + i + ":");
13368 mWifiStateTimer[i].logState(pr, " ");
13369 }
Dianne Hackborn3251b902014-06-20 14:40:53 -070013370 for (int i=0; i<NUM_WIFI_SUPPL_STATES; i++) {
13371 pr.println("*** Wifi suppl state #" + i + ":");
13372 mWifiSupplStateTimer[i].logState(pr, " ");
13373 }
13374 for (int i=0; i<NUM_WIFI_SIGNAL_STRENGTH_BINS; i++) {
13375 pr.println("*** Wifi signal strength #" + i + ":");
13376 mWifiSignalStrengthsTimer[i].logState(pr, " ");
13377 }
Dianne Hackbornabc7c492014-06-30 16:57:46 -070013378 pr.println("*** Flashlight timer:");
13379 mFlashlightOnTimer.logState(pr, " ");
Ruben Brunk6d2c3632015-05-26 17:32:16 -070013380 pr.println("*** Camera timer:");
13381 mCameraOnTimer.logState(pr, " ");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013382 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -080013383 super.dumpLocked(context, pw, flags, reqUid, histStart);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013384 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080013385}