blob: a376e7a15410e640d7753a0cc47f9b31d94e23d8 [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.server.am;
18
Bookatzdb026a22018-01-10 19:01:56 -080019import android.app.ActivityManager;
Bookatz235343d2018-03-26 13:03:50 -070020import android.app.job.JobProtoEnums;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070021import android.bluetooth.BluetoothActivityEnergyInfo;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022import android.content.Context;
Dianne Hackborne4a59512010-12-07 11:08:07 -080023import android.content.pm.ApplicationInfo;
Kenny Root3abd75b2011-09-29 11:00:41 -070024import android.content.pm.PackageManager;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070025import android.net.wifi.WifiActivityEnergyInfo;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070026import android.os.BatteryStats;
David Chenc8a43242017-10-17 16:23:28 -070027import android.os.BatteryStatsInternal;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028import android.os.Binder;
Jeff Brown6f357d32014-01-15 20:40:55 -080029import android.os.Handler;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.os.IBinder;
31import android.os.Parcel;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070032import android.os.ParcelFileDescriptor;
Adam Lesinski9ae9cba2015-07-08 17:09:34 -070033import android.os.ParcelFormatException;
Mike Mafbc01fc2018-04-02 10:28:28 -070034import android.os.PowerManager.ServiceType;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070035import android.os.PowerManagerInternal;
Mike Mafbc01fc2018-04-02 10:28:28 -070036import android.os.PowerSaveState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.os.Process;
38import android.os.ServiceManager;
Dianne Hackborne5167ca2014-03-08 14:39:10 -080039import android.os.SystemClock;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -070040import android.os.UserHandle;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070041import android.os.UserManagerInternal;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070042import android.os.WorkSource;
Siddharth Raya1fd0572017-11-13 14:20:47 -080043import android.os.connectivity.CellularBatteryStats;
Siddharth Ray78ccaf52017-12-23 16:16:21 -080044import android.os.connectivity.GpsBatteryStats;
Mike Mafbc01fc2018-04-02 10:28:28 -070045import android.os.connectivity.WifiBatteryStats;
Joe Onorato713fec82016-03-04 10:34:02 -080046import android.os.health.HealthStatsParceler;
47import android.os.health.HealthStatsWriter;
48import android.os.health.UidHealthStats;
Adam Lesinski06f46cb2015-06-23 13:42:53 -070049import android.telephony.DataConnectionRealTimeInfo;
Adam Lesinski21f76aa2016-01-25 12:27:06 -080050import android.telephony.ModemActivityInfo;
Wink Savillee9b06d72009-05-18 21:47:50 -070051import android.telephony.SignalStrength;
Dianne Hackborne4a59512010-12-07 11:08:07 -080052import android.telephony.TelephonyManager;
Joe Onorato8a9b2202010-02-26 18:56:32 -080053import android.util.Slog;
Mike Mafbc01fc2018-04-02 10:28:28 -070054import android.util.StatsLog;
Amith Yamasani674c9bb2017-02-01 09:45:17 -080055
Amith Yamasani32dbefd2009-06-19 09:21:17 -070056import com.android.internal.app.IBatteryStats;
Dianne Hackbornd953c532014-08-16 18:17:38 -070057import com.android.internal.os.BatteryStatsHelper;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070058import com.android.internal.os.BatteryStatsImpl;
Amith Yamasanie43530a2009-08-21 13:11:37 -070059import com.android.internal.os.PowerProfile;
Bookatz50df7112017-08-04 14:53:26 -070060import com.android.internal.os.RpmStats;
Jeff Sharkeyfe9a53b2017-03-31 14:08:23 -060061import com.android.internal.util.DumpUtils;
Hui Yu0ed84f12018-06-20 19:07:56 -070062import com.android.internal.util.ParseUtils;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070063import com.android.server.LocalServices;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070064
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070065import java.io.File;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import java.io.FileDescriptor;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070067import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068import java.io.PrintWriter;
Adam Lesinski515702c2015-07-23 18:13:38 -070069import java.nio.ByteBuffer;
70import java.nio.CharBuffer;
71import java.nio.charset.CharsetDecoder;
72import java.nio.charset.CodingErrorAction;
73import java.nio.charset.StandardCharsets;
Joe Onorato713fec82016-03-04 10:34:02 -080074import java.util.Arrays;
Dianne Hackborne4a59512010-12-07 11:08:07 -080075import java.util.List;
Adam Lesinskib3a1bad2017-05-26 11:50:40 -070076import java.util.concurrent.ExecutionException;
77import java.util.concurrent.Future;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078
79/**
80 * All information we are collecting about things that can happen that impact
81 * battery life.
82 */
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070083public final class BatteryStatsService extends IBatteryStats.Stub
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -070084 implements PowerManagerInternal.LowPowerModeListener,
85 BatteryStatsImpl.PlatformIdleStateCallback {
Dianne Hackbornc51cf032014-03-02 19:08:15 -080086 static final String TAG = "BatteryStatsService";
Joe Onorato82ba91d2017-04-27 16:18:05 -070087 static final boolean DBG = false;
Dianne Hackbornc51cf032014-03-02 19:08:15 -080088
Adam Lesinski010bf372016-04-11 12:18:18 -070089 private static IBatteryStats sService;
90
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 final BatteryStatsImpl mStats;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070092 private final BatteryStatsImpl.UserInfoProvider mUserManagerUserInfoProvider;
Adam Lesinskib3a1bad2017-05-26 11:50:40 -070093 private final Context mContext;
94 private final BatteryExternalStatsWorker mWorker;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070095
Bookatz50df7112017-08-04 14:53:26 -070096 private native void getLowPowerStats(RpmStats rpmStats);
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -070097 private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +000098 private native int getSubsystemLowPowerStats(ByteBuffer outBuffer);
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -070099 private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8
100 .newDecoder()
101 .onMalformedInput(CodingErrorAction.REPLACE)
102 .onUnmappableCharacter(CodingErrorAction.REPLACE)
103 .replaceWith("?");
104 private ByteBuffer mUtf8BufferStat = ByteBuffer.allocateDirect(MAX_LOW_POWER_STATS_SIZE);
105 private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE);
Kelly Rossmoyer03ad13e2018-03-13 13:10:14 -0700106 private static final int MAX_LOW_POWER_STATS_SIZE = 2048;
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700107
Bookatz50df7112017-08-04 14:53:26 -0700108 /**
109 * Replaces the information in the given rpmStats with up-to-date information.
110 */
111 @Override
112 public void fillLowPowerStats(RpmStats rpmStats) {
113 if (DBG) Slog.d(TAG, "begin getLowPowerStats");
114 try {
115 getLowPowerStats(rpmStats);
116 } finally {
117 if (DBG) Slog.d(TAG, "end getLowPowerStats");
118 }
119 }
120
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700121 @Override
122 public String getPlatformLowPowerStats() {
Joe Onorato82ba91d2017-04-27 16:18:05 -0700123 if (DBG) Slog.d(TAG, "begin getPlatformLowPowerStats");
Adam Lesinskicd722082017-03-30 13:54:09 -0700124 try {
125 mUtf8BufferStat.clear();
126 mUtf16BufferStat.clear();
127 mDecoderStat.reset();
128 int bytesWritten = getPlatformLowPowerStats(mUtf8BufferStat);
129 if (bytesWritten < 0) {
130 return null;
131 } else if (bytesWritten == 0) {
132 return "Empty";
133 }
134 mUtf8BufferStat.limit(bytesWritten);
135 mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
136 mUtf16BufferStat.flip();
137 return mUtf16BufferStat.toString();
138 } finally {
Joe Onorato82ba91d2017-04-27 16:18:05 -0700139 if (DBG) Slog.d(TAG, "end getPlatformLowPowerStats");
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700140 }
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700141 }
142
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +0000143 @Override
144 public String getSubsystemLowPowerStats() {
Bookatz50df7112017-08-04 14:53:26 -0700145 if (DBG) Slog.d(TAG, "begin getSubsystemLowPowerStats");
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +0000146 try {
147 mUtf8BufferStat.clear();
148 mUtf16BufferStat.clear();
149 mDecoderStat.reset();
150 int bytesWritten = getSubsystemLowPowerStats(mUtf8BufferStat);
151 if (bytesWritten < 0) {
152 return null;
153 } else if (bytesWritten == 0) {
154 return "Empty";
155 }
156 mUtf8BufferStat.limit(bytesWritten);
157 mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
158 mUtf16BufferStat.flip();
159 return mUtf16BufferStat.toString();
160 } finally {
Bookatz50df7112017-08-04 14:53:26 -0700161 if (DBG) Slog.d(TAG, "end getSubsystemLowPowerStats");
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +0000162 }
163 }
164
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700165 BatteryStatsService(Context context, File systemDir, Handler handler) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700166 // BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through.
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700167 mContext = context;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700168 mUserManagerUserInfoProvider = new BatteryStatsImpl.UserInfoProvider() {
169 private UserManagerInternal umi;
170 @Override
171 public int[] getUserIds() {
172 if (umi == null) {
173 umi = LocalServices.getService(UserManagerInternal.class);
174 }
175 return (umi != null) ? umi.getUserIds() : null;
176 }
177 };
178 mStats = new BatteryStatsImpl(systemDir, handler, this, mUserManagerUserInfoProvider);
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700179 mWorker = new BatteryExternalStatsWorker(context, mStats);
180 mStats.setExternalStatsSyncLocked(mWorker);
181 mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
182 com.android.internal.R.integer.config_radioScanningTimeout) * 1000L);
183 mStats.setPowerProfileLocked(new PowerProfile(context));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800184 }
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700185
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700186 public void publish() {
David Chenc8a43242017-10-17 16:23:28 -0700187 LocalServices.addService(BatteryStatsInternal.class, new LocalService());
Adam Lesinski6832f392015-09-05 18:05:40 -0700188 ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
Jeff Brown2c43c332014-06-12 22:38:59 -0700189 }
190
Sudheer Shanka5c19b892018-01-05 17:25:46 -0800191 public void systemServicesReady() {
192 mStats.systemServicesReady(mContext);
193 }
194
David Chenc8a43242017-10-17 16:23:28 -0700195 private final class LocalService extends BatteryStatsInternal {
196 @Override
197 public String[] getWifiIfaces() {
198 return mStats.getWifiIfaces().clone();
199 }
200
201 @Override
202 public String[] getMobileIfaces() {
203 return mStats.getMobileIfaces().clone();
204 }
Amith Yamasani977e11f2018-02-16 11:29:54 -0800205
206 @Override
207 public void noteJobsDeferred(int uid, int numDeferred, long sinceLast) {
208 if (DBG) Slog.d(TAG, "Jobs deferred " + uid + ": " + numDeferred + " " + sinceLast);
209 BatteryStatsService.this.noteJobsDeferred(uid, numDeferred, sinceLast);
210 }
David Chenc8a43242017-10-17 16:23:28 -0700211 }
212
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700213 private static void awaitUninterruptibly(Future<?> future) {
214 while (true) {
215 try {
216 future.get();
217 return;
218 } catch (ExecutionException e) {
219 return;
220 } catch (InterruptedException e) {
221 // Keep looping
222 }
223 }
224 }
225
Sudheer Shankab2f83c12017-11-13 19:25:01 -0800226 private void syncStats(String reason, int flags) {
227 awaitUninterruptibly(mWorker.scheduleSync(reason, flags));
228 }
229
Jeff Brown2c43c332014-06-12 22:38:59 -0700230 /**
231 * At the time when the constructor runs, the power manager has not yet been
232 * initialized. So we initialize the low power observer later.
233 */
234 public void initPowerManagement() {
Adam Lesinski010bf372016-04-11 12:18:18 -0700235 final PowerManagerInternal powerMgr = LocalServices.getService(PowerManagerInternal.class);
236 powerMgr.registerLowPowerModeObserver(this);
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700237 synchronized (mStats) {
238 mStats.notePowerSaveModeLocked(
239 powerMgr.getLowPowerState(ServiceType.BATTERY_STATS)
240 .batterySaverEnabled);
241 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800242 (new WakeupReasonThread()).start();
Jeff Brown2c43c332014-06-12 22:38:59 -0700243 }
244
Dianne Hackborn55280a92009-05-07 15:53:46 -0700245 public void shutdown() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800246 Slog.w("BatteryStats", "Writing battery stats before shutdown...");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700247
Sudheer Shankab2f83c12017-11-13 19:25:01 -0800248 syncStats("shutdown", BatteryExternalStatsWorker.UPDATE_ALL);
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700249
Dianne Hackborn55280a92009-05-07 15:53:46 -0700250 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700251 mStats.shutdownLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -0700252 }
Adam Lesinski20b84df2016-04-19 17:33:33 -0700253
254 // Shutdown the thread we made.
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700255 mWorker.shutdown();
Dianne Hackborn55280a92009-05-07 15:53:46 -0700256 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700257
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800258 public static IBatteryStats getService() {
259 if (sService != null) {
260 return sService;
261 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700262 IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800263 sService = asInterface(b);
264 return sService;
265 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700266
267 @Override
jackqdyulei455e90a2017-02-09 15:29:16 -0800268 public int getServiceType() {
269 return ServiceType.BATTERY_STATS;
270 }
271
272 @Override
273 public void onLowPowerModeChanged(PowerSaveState result) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700274 synchronized (mStats) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700275 mStats.notePowerSaveModeLocked(result.batterySaverEnabled);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700276 }
277 }
278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 /**
280 * @return the current statistics object, which may be modified
281 * to reflect events that affect battery usage. You must lock the
282 * stats object before doing anything with it.
283 */
284 public BatteryStatsImpl getActiveStatistics() {
285 return mStats;
286 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700287
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700288 /**
289 * Schedules a write to disk to occur. This will cause the BatteryStatsImpl
290 * object to update with the latest info, then write to disk.
291 */
292 public void scheduleWriteToDisk() {
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700293 mWorker.scheduleWrite();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700294 }
295
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700296 // These are for direct use by the activity manager...
297
Adam Lesinskib83ffee2015-05-12 14:43:47 -0700298 /**
299 * Remove a UID from the BatteryStats and BatteryStats' external dependencies.
300 */
301 void removeUid(int uid) {
302 synchronized (mStats) {
303 mStats.removeUidStatsLocked(uid);
304 }
305 }
306
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700307 void onCleanupUser(int userId) {
308 synchronized (mStats) {
309 mStats.onCleanupUserLocked(userId);
310 }
311 }
312
313 void onUserRemoved(int userId) {
314 synchronized (mStats) {
315 mStats.onUserRemovedLocked(userId);
316 }
317 }
318
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700319 void addIsolatedUid(int isolatedUid, int appUid) {
320 synchronized (mStats) {
321 mStats.addIsolatedUidLocked(isolatedUid, appUid);
322 }
323 }
324
325 void removeIsolatedUid(int isolatedUid, int appUid) {
326 synchronized (mStats) {
Adam Lesinski61db88f2015-07-01 15:05:07 -0700327 mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid);
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700328 }
329 }
330
331 void noteProcessStart(String name, int uid) {
332 synchronized (mStats) {
333 mStats.noteProcessStartLocked(name, uid);
Bookatz90867622018-01-31 15:05:57 -0800334 StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800335 StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__STARTED);
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700336 }
337 }
338
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800339 void noteProcessCrash(String name, int uid) {
340 synchronized (mStats) {
341 mStats.noteProcessCrashLocked(name, uid);
Bookatz90867622018-01-31 15:05:57 -0800342 StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800343 StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__CRASHED);
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800344 }
345 }
346
347 void noteProcessAnr(String name, int uid) {
348 synchronized (mStats) {
349 mStats.noteProcessAnrLocked(name, uid);
350 }
351 }
352
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700353 void noteProcessFinish(String name, int uid) {
354 synchronized (mStats) {
355 mStats.noteProcessFinishLocked(name, uid);
Bookatz90867622018-01-31 15:05:57 -0800356 StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800357 StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__FINISHED);
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700358 }
359 }
360
Bookatzdb026a22018-01-10 19:01:56 -0800361 /** @param state Process state from ActivityManager.java. */
Dianne Hackborna8d10942015-11-19 17:55:19 -0800362 void noteUidProcessState(int uid, int state) {
363 synchronized (mStats) {
Bookatzdb026a22018-01-10 19:01:56 -0800364 StatsLog.write(StatsLog.UID_PROCESS_STATE_CHANGED, uid,
365 ActivityManager.processStateAmToProto(state));
Yao Chend54f9dd2017-10-17 17:37:48 +0000366
Dianne Hackborna8d10942015-11-19 17:55:19 -0800367 mStats.noteUidProcessStateLocked(uid, state);
368 }
369 }
370
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700371 // Public interface...
372
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800373 public byte[] getStatistics() {
374 mContext.enforceCallingPermission(
375 android.Manifest.permission.BATTERY_STATS, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800376 //Slog.i("foo", "SENDING BATTERY INFO:");
377 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800378 Parcel out = Parcel.obtain();
Sudheer Shankab2f83c12017-11-13 19:25:01 -0800379 syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700380 synchronized (mStats) {
381 mStats.writeToParcel(out, 0);
382 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800383 byte[] data = out.marshall();
384 out.recycle();
385 return data;
386 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700387
388 public ParcelFileDescriptor getStatisticsStream() {
389 mContext.enforceCallingPermission(
390 android.Manifest.permission.BATTERY_STATS, null);
391 //Slog.i("foo", "SENDING BATTERY INFO:");
392 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
393 Parcel out = Parcel.obtain();
Sudheer Shankab2f83c12017-11-13 19:25:01 -0800394 syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700395 synchronized (mStats) {
396 mStats.writeToParcel(out, 0);
397 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700398 byte[] data = out.marshall();
Hui Yu0ed84f12018-06-20 19:07:56 -0700399 if (DBG) Slog.d(TAG, "getStatisticsStream parcel size is:" + data.length);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700400 out.recycle();
401 try {
402 return ParcelFileDescriptor.fromData(data, "battery-stats");
403 } catch (IOException e) {
404 Slog.w(TAG, "Unable to create shared memory", e);
405 return null;
406 }
407 }
408
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700409 public boolean isCharging() {
410 synchronized (mStats) {
411 return mStats.isCharging();
412 }
413 }
414
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -0700415 public long computeBatteryTimeRemaining() {
416 synchronized (mStats) {
417 long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
418 return time >= 0 ? (time/1000) : time;
419 }
420 }
421
422 public long computeChargeTimeRemaining() {
423 synchronized (mStats) {
424 long time = mStats.computeChargeTimeRemaining(SystemClock.elapsedRealtime());
425 return time >= 0 ? (time/1000) : time;
426 }
427 }
428
Dianne Hackborn099bc622014-01-22 13:39:16 -0800429 public void noteEvent(int code, String name, int uid) {
430 enforceCallingPermission();
431 synchronized (mStats) {
432 mStats.noteEventLocked(code, name, uid);
433 }
434 }
435
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700436 public void noteSyncStart(String name, int uid) {
437 enforceCallingPermission();
438 synchronized (mStats) {
439 mStats.noteSyncStartLocked(name, uid);
Bookatz235343d2018-03-26 13:03:50 -0700440 StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, uid, null, name,
441 StatsLog.SYNC_STATE_CHANGED__STATE__ON);
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700442 }
443 }
444
445 public void noteSyncFinish(String name, int uid) {
446 enforceCallingPermission();
447 synchronized (mStats) {
448 mStats.noteSyncFinishLocked(name, uid);
Bookatz235343d2018-03-26 13:03:50 -0700449 StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, uid, null, name,
450 StatsLog.SYNC_STATE_CHANGED__STATE__OFF);
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700451 }
452 }
453
454 public void noteJobStart(String name, int uid) {
455 enforceCallingPermission();
456 synchronized (mStats) {
457 mStats.noteJobStartLocked(name, uid);
Bookatz235343d2018-03-26 13:03:50 -0700458 StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, uid, null,
459 name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED,
460 JobProtoEnums.STOP_REASON_UNKNOWN);
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700461 }
462 }
463
Dianne Hackborn94326cb2017-06-28 16:17:20 -0700464 public void noteJobFinish(String name, int uid, int stopReason) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700465 enforceCallingPermission();
466 synchronized (mStats) {
Dianne Hackborn94326cb2017-06-28 16:17:20 -0700467 mStats.noteJobFinishLocked(name, uid, stopReason);
Bookatz235343d2018-03-26 13:03:50 -0700468 StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, uid, null,
469 name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
470 stopReason);
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700471 }
472 }
473
Amith Yamasani977e11f2018-02-16 11:29:54 -0800474 void noteJobsDeferred(int uid, int numDeferred, long sinceLast) {
475 // No need to enforce calling permission, as it is called from an internal interface
476 synchronized (mStats) {
477 mStats.noteJobsDeferredLocked(uid, numDeferred, sinceLast);
478 }
479 }
480
Narayan Kamath695cf722017-12-21 18:32:47 +0000481 public void noteWakupAlarm(String name, int uid, WorkSource workSource, String tag) {
Dianne Hackborn1e383822015-04-10 14:02:33 -0700482 enforceCallingPermission();
483 synchronized (mStats) {
Narayan Kamath695cf722017-12-21 18:32:47 +0000484 mStats.noteWakupAlarmLocked(name, uid, workSource, tag);
Dianne Hackborn1e383822015-04-10 14:02:33 -0700485 }
486 }
487
Narayan Kamath695cf722017-12-21 18:32:47 +0000488 public void noteAlarmStart(String name, WorkSource workSource, int uid) {
Dianne Hackborn1e383822015-04-10 14:02:33 -0700489 enforceCallingPermission();
490 synchronized (mStats) {
Narayan Kamath695cf722017-12-21 18:32:47 +0000491 mStats.noteAlarmStartLocked(name, workSource, uid);
492 }
493 }
494
495 public void noteAlarmFinish(String name, WorkSource workSource, int uid) {
496 enforceCallingPermission();
497 synchronized (mStats) {
498 mStats.noteAlarmFinishLocked(name, workSource, uid);
Dianne Hackborn1e383822015-04-10 14:02:33 -0700499 }
500 }
501
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800502 public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800503 boolean unimportantForLogging) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800504 enforceCallingPermission();
505 synchronized (mStats) {
Narayan Kamath81822022017-12-08 11:56:01 +0000506 mStats.noteStartWakeLocked(uid, pid, null, name, historyName, type,
507 unimportantForLogging, SystemClock.elapsedRealtime(),
508 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800509 }
510 }
511
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700512 public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800513 enforceCallingPermission();
514 synchronized (mStats) {
Narayan Kamath81822022017-12-08 11:56:01 +0000515 mStats.noteStopWakeLocked(uid, pid, null, name, historyName, type,
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700516 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800517 }
518 }
519
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800520 public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
521 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700522 enforceCallingPermission();
523 synchronized (mStats) {
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800524 mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
525 type, unimportantForLogging);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700526 }
527 }
528
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700529 public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name,
530 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800531 String newHistoryName, int newType, boolean newUnimportantForLogging) {
532 enforceCallingPermission();
533 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700534 mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800535 newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
536 }
537 }
538
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700539 public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName,
540 int type) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700541 enforceCallingPermission();
542 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700543 mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700544 }
545 }
546
Narayan Kamath96a92562018-01-02 18:57:17 +0000547 @Override
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700548 public void noteLongPartialWakelockStart(String name, String historyName, int uid) {
549 enforceCallingPermission();
550 synchronized (mStats) {
551 mStats.noteLongPartialWakelockStart(name, historyName, uid);
552 }
553 }
554
Narayan Kamath96a92562018-01-02 18:57:17 +0000555 @Override
556 public void noteLongPartialWakelockStartFromSource(String name, String historyName,
557 WorkSource workSource) {
558 enforceCallingPermission();
559 synchronized (mStats) {
560 mStats.noteLongPartialWakelockStartFromSource(name, historyName, workSource);
561 }
562 }
563
564 @Override
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700565 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) {
566 enforceCallingPermission();
567 synchronized (mStats) {
568 mStats.noteLongPartialWakelockFinish(name, historyName, uid);
569 }
570 }
571
Narayan Kamath96a92562018-01-02 18:57:17 +0000572 @Override
573 public void noteLongPartialWakelockFinishFromSource(String name, String historyName,
574 WorkSource workSource) {
575 enforceCallingPermission();
576 synchronized (mStats) {
577 mStats.noteLongPartialWakelockFinishFromSource(name, historyName, workSource);
578 }
579 }
580
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800581 public void noteStartSensor(int uid, int sensor) {
582 enforceCallingPermission();
583 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700584 mStats.noteStartSensorLocked(uid, sensor);
Bookatz235343d2018-03-26 13:03:50 -0700585 StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, uid, null, sensor,
586 StatsLog.SENSOR_STATE_CHANGED__STATE__ON);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800587 }
588 }
Chenjie Yu29fb1f72017-09-13 12:18:50 -0700589
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800590 public void noteStopSensor(int uid, int sensor) {
591 enforceCallingPermission();
592 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700593 mStats.noteStopSensorLocked(uid, sensor);
Bookatz235343d2018-03-26 13:03:50 -0700594 StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, uid, null,
595 sensor, StatsLog.SENSOR_STATE_CHANGED__STATE__OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800596 }
597 }
Chenjie Yu29fb1f72017-09-13 12:18:50 -0700598
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800599 public void noteVibratorOn(int uid, long durationMillis) {
600 enforceCallingPermission();
601 synchronized (mStats) {
602 mStats.noteVibratorOnLocked(uid, durationMillis);
603 }
604 }
605
606 public void noteVibratorOff(int uid) {
607 enforceCallingPermission();
608 synchronized (mStats) {
609 mStats.noteVibratorOffLocked(uid);
610 }
611 }
612
Narayan Kamath32684dd2018-01-08 17:32:51 +0000613 @Override
614 public void noteGpsChanged(WorkSource oldWs, WorkSource newWs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800615 enforceCallingPermission();
616 synchronized (mStats) {
Narayan Kamath32684dd2018-01-08 17:32:51 +0000617 mStats.noteGpsChangedLocked(oldWs, newWs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800618 }
619 }
Chenjie Yu29fb1f72017-09-13 12:18:50 -0700620
Siddharth Ray78ccaf52017-12-23 16:16:21 -0800621 public void noteGpsSignalQuality(int signalLevel) {
622 synchronized (mStats) {
623 mStats.noteGpsSignalQualityLocked(signalLevel);
624 }
625 }
626
Jeff Browne95c3cd2014-05-02 16:59:26 -0700627 public void noteScreenState(int state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 enforceCallingPermission();
Joe Onorato82ba91d2017-04-27 16:18:05 -0700629 if (DBG) Slog.d(TAG, "begin noteScreenState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800630 synchronized (mStats) {
Yao Chend54f9dd2017-10-17 17:37:48 +0000631 StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, state);
632
633 mStats.noteScreenStateLocked(state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634 }
Joe Onorato82ba91d2017-04-27 16:18:05 -0700635 if (DBG) Slog.d(TAG, "end noteScreenState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800636 }
Chenjie Yu29fb1f72017-09-13 12:18:50 -0700637
Dianne Hackborn617f8772009-03-31 15:04:46 -0700638 public void noteScreenBrightness(int brightness) {
639 enforceCallingPermission();
640 synchronized (mStats) {
Bookatzc1a050a2017-10-10 15:49:28 -0700641 StatsLog.write(StatsLog.SCREEN_BRIGHTNESS_CHANGED, brightness);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700642 mStats.noteScreenBrightnessLocked(brightness);
643 }
644 }
yroe03583e2017-09-20 22:51:26 -0700645
Dianne Hackborn617f8772009-03-31 15:04:46 -0700646 public void noteUserActivity(int uid, int event) {
647 enforceCallingPermission();
648 synchronized (mStats) {
649 mStats.noteUserActivityLocked(uid, event);
650 }
651 }
yroe03583e2017-09-20 22:51:26 -0700652
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700653 public void noteWakeUp(String reason, int reasonUid) {
654 enforceCallingPermission();
655 synchronized (mStats) {
656 mStats.noteWakeUpLocked(reason, reasonUid);
657 }
658 }
659
Jeff Browne95c3cd2014-05-02 16:59:26 -0700660 public void noteInteractive(boolean interactive) {
661 enforceCallingPermission();
662 synchronized (mStats) {
663 mStats.noteInteractiveLocked(interactive);
664 }
665 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800666
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800667 public void noteConnectivityChanged(int type, String extra) {
668 enforceCallingPermission();
669 synchronized (mStats) {
670 mStats.noteConnectivityChangedLocked(type, extra);
671 }
672 }
673
Ruchi Kandoifa97fcf2016-05-13 15:10:39 -0700674 public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800675 enforceCallingPermission();
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700676 final boolean update;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800677 synchronized (mStats) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700678 update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid);
679 }
680
681 if (update) {
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700682 mWorker.scheduleSync("modem-data", BatteryExternalStatsWorker.UPDATE_RADIO);
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800683 }
684 }
685
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800686 public void notePhoneOn() {
687 enforceCallingPermission();
688 synchronized (mStats) {
689 mStats.notePhoneOnLocked();
690 }
691 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700692
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800693 public void notePhoneOff() {
694 enforceCallingPermission();
695 synchronized (mStats) {
696 mStats.notePhoneOffLocked();
697 }
698 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700699
Wink Savillee9b06d72009-05-18 21:47:50 -0700700 public void notePhoneSignalStrength(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700701 enforceCallingPermission();
702 synchronized (mStats) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700703 mStats.notePhoneSignalStrengthLocked(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700704 }
705 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700706
Dianne Hackborn627bba72009-03-24 22:32:56 -0700707 public void notePhoneDataConnectionState(int dataType, boolean hasData) {
708 enforceCallingPermission();
709 synchronized (mStats) {
710 mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
711 }
712 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700713
Amith Yamasanif37447b2009-10-08 18:28:01 -0700714 public void notePhoneState(int state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700715 enforceCallingPermission();
Dianne Hackborne4a59512010-12-07 11:08:07 -0800716 int simState = TelephonyManager.getDefault().getSimState();
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700717 synchronized (mStats) {
Dianne Hackborne4a59512010-12-07 11:08:07 -0800718 mStats.notePhoneStateLocked(state, simState);
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700719 }
720 }
721
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700722 public void noteWifiOn() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700723 enforceCallingPermission();
724 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700725 mStats.noteWifiOnLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700726 }
Bookatzda1798c2018-12-13 14:16:00 -0800727 StatsLog.write(StatsLog.WIFI_ENABLED_STATE_CHANGED,
728 StatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__ON);
The Android Open Source Project10592532009-03-18 17:39:46 -0700729 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700730
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700731 public void noteWifiOff() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700732 enforceCallingPermission();
733 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700734 mStats.noteWifiOffLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700735 }
Bookatzda1798c2018-12-13 14:16:00 -0800736 StatsLog.write(StatsLog.WIFI_ENABLED_STATE_CHANGED,
737 StatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__OFF);
The Android Open Source Project10592532009-03-18 17:39:46 -0700738 }
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700739
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700740 public void noteStartAudio(int uid) {
741 enforceCallingPermission();
742 synchronized (mStats) {
743 mStats.noteAudioOnLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700744 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null,
745 StatsLog.AUDIO_STATE_CHANGED__STATE__ON);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700746 }
747 }
748
749 public void noteStopAudio(int uid) {
750 enforceCallingPermission();
751 synchronized (mStats) {
752 mStats.noteAudioOffLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700753 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null,
754 StatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700755 }
756 }
757
758 public void noteStartVideo(int uid) {
759 enforceCallingPermission();
760 synchronized (mStats) {
761 mStats.noteVideoOnLocked(uid);
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800762 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid, null,
763 StatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__ON);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700764 }
765 }
766
767 public void noteStopVideo(int uid) {
768 enforceCallingPermission();
769 synchronized (mStats) {
770 mStats.noteVideoOffLocked(uid);
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800771 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid,
772 null, StatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__OFF);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700773 }
774 }
775
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700776 public void noteResetAudio() {
777 enforceCallingPermission();
778 synchronized (mStats) {
779 mStats.noteResetAudioLocked();
Bookatz235343d2018-03-26 13:03:50 -0700780 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, -1, null,
781 StatsLog.AUDIO_STATE_CHANGED__STATE__RESET);
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700782 }
783 }
784
785 public void noteResetVideo() {
786 enforceCallingPermission();
787 synchronized (mStats) {
788 mStats.noteResetVideoLocked();
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800789 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, -1, null,
790 StatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__RESET);
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700791 }
792 }
793
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700794 public void noteFlashlightOn(int uid) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700795 enforceCallingPermission();
796 synchronized (mStats) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700797 mStats.noteFlashlightOnLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700798 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, uid, null,
799 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON);
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700800 }
801 }
802
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700803 public void noteFlashlightOff(int uid) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700804 enforceCallingPermission();
805 synchronized (mStats) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700806 mStats.noteFlashlightOffLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700807 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, uid, null,
808 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700809 }
810 }
811
812 public void noteStartCamera(int uid) {
813 enforceCallingPermission();
Joe Onorato82ba91d2017-04-27 16:18:05 -0700814 if (DBG) Slog.d(TAG, "begin noteStartCamera");
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700815 synchronized (mStats) {
816 mStats.noteCameraOnLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700817 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, uid, null,
818 StatsLog.CAMERA_STATE_CHANGED__STATE__ON);
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700819 }
Joe Onorato82ba91d2017-04-27 16:18:05 -0700820 if (DBG) Slog.d(TAG, "end noteStartCamera");
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700821 }
822
823 public void noteStopCamera(int uid) {
824 enforceCallingPermission();
825 synchronized (mStats) {
826 mStats.noteCameraOffLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700827 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, uid, null,
828 StatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700829 }
830 }
831
832 public void noteResetCamera() {
833 enforceCallingPermission();
834 synchronized (mStats) {
835 mStats.noteResetCameraLocked();
Bookatz235343d2018-03-26 13:03:50 -0700836 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, -1, null,
837 StatsLog.CAMERA_STATE_CHANGED__STATE__RESET);
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700838 }
839 }
840
841 public void noteResetFlashlight() {
842 enforceCallingPermission();
843 synchronized (mStats) {
844 mStats.noteResetFlashlightLocked();
Bookatz235343d2018-03-26 13:03:50 -0700845 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, -1, null,
846 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__RESET);
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700847 }
848 }
849
Adam Lesinskie08af192015-03-25 16:42:59 -0700850 @Override
Adam Lesinski5f056f62016-07-14 16:56:08 -0700851 public void noteWifiRadioPowerState(int powerState, long tsNanos, int uid) {
Adam Lesinskie08af192015-03-25 16:42:59 -0700852 enforceCallingPermission();
853
854 // There was a change in WiFi power state.
855 // Collect data now for the past activity.
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700856 synchronized (mStats) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700857 if (mStats.isOnBattery()) {
Adam Lesinski06f46cb2015-06-23 13:42:53 -0700858 final String type = (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH ||
859 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active"
860 : "inactive";
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700861 mWorker.scheduleSync("wifi-data: " + type, BatteryExternalStatsWorker.UPDATE_WIFI);
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700862 }
Adam Lesinski5f056f62016-07-14 16:56:08 -0700863 mStats.noteWifiRadioPowerState(powerState, tsNanos, uid);
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700864 }
Adam Lesinskie08af192015-03-25 16:42:59 -0700865 }
866
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700867 public void noteWifiRunning(WorkSource ws) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700868 enforceCallingPermission();
869 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700870 mStats.noteWifiRunningLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700871 }
Bookatzda1798c2018-12-13 14:16:00 -0800872 // TODO: Log WIFI_RUNNING_STATE_CHANGED in a better spot to include Hotspot too.
873 StatsLog.write(StatsLog.WIFI_RUNNING_STATE_CHANGED,
874 ws, StatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700875 }
876
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700877 public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700878 enforceCallingPermission();
879 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700880 mStats.noteWifiRunningChangedLocked(oldWs, newWs);
881 }
Bookatzda1798c2018-12-13 14:16:00 -0800882 StatsLog.write(StatsLog.WIFI_RUNNING_STATE_CHANGED,
883 newWs, StatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON);
884 StatsLog.write(StatsLog.WIFI_RUNNING_STATE_CHANGED,
885 oldWs, StatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF);
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700886 }
887
888 public void noteWifiStopped(WorkSource ws) {
889 enforceCallingPermission();
890 synchronized (mStats) {
891 mStats.noteWifiStoppedLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700892 }
Bookatzda1798c2018-12-13 14:16:00 -0800893 StatsLog.write(StatsLog.WIFI_RUNNING_STATE_CHANGED,
894 ws, StatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700895 }
896
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800897 public void noteWifiState(int wifiState, String accessPoint) {
898 enforceCallingPermission();
899 synchronized (mStats) {
900 mStats.noteWifiStateLocked(wifiState, accessPoint);
901 }
902 }
903
Dianne Hackborn3251b902014-06-20 14:40:53 -0700904 public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) {
905 enforceCallingPermission();
906 synchronized (mStats) {
907 mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth);
908 }
909 }
910
911 public void noteWifiRssiChanged(int newRssi) {
912 enforceCallingPermission();
913 synchronized (mStats) {
914 mStats.noteWifiRssiChangedLocked(newRssi);
915 }
916 }
917
The Android Open Source Project10592532009-03-18 17:39:46 -0700918 public void noteFullWifiLockAcquired(int uid) {
919 enforceCallingPermission();
920 synchronized (mStats) {
921 mStats.noteFullWifiLockAcquiredLocked(uid);
922 }
923 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700924
The Android Open Source Project10592532009-03-18 17:39:46 -0700925 public void noteFullWifiLockReleased(int uid) {
926 enforceCallingPermission();
927 synchronized (mStats) {
928 mStats.noteFullWifiLockReleasedLocked(uid);
929 }
930 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700931
932 public void noteWifiScanStarted(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700933 enforceCallingPermission();
934 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700935 mStats.noteWifiScanStartedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700936 }
937 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700938
939 public void noteWifiScanStopped(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700940 enforceCallingPermission();
941 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700942 mStats.noteWifiScanStoppedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700943 }
944 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800945
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700946 public void noteWifiMulticastEnabled(int uid) {
947 enforceCallingPermission();
948 synchronized (mStats) {
949 mStats.noteWifiMulticastEnabledLocked(uid);
950 }
951 }
952
953 public void noteWifiMulticastDisabled(int uid) {
954 enforceCallingPermission();
955 synchronized (mStats) {
956 mStats.noteWifiMulticastDisabledLocked(uid);
957 }
958 }
959
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700960 public void noteFullWifiLockAcquiredFromSource(WorkSource ws) {
961 enforceCallingPermission();
962 synchronized (mStats) {
963 mStats.noteFullWifiLockAcquiredFromSourceLocked(ws);
964 }
965 }
966
967 public void noteFullWifiLockReleasedFromSource(WorkSource ws) {
968 enforceCallingPermission();
969 synchronized (mStats) {
970 mStats.noteFullWifiLockReleasedFromSourceLocked(ws);
971 }
972 }
973
Nick Pelly6ccaa542012-06-15 15:22:47 -0700974 public void noteWifiScanStartedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700975 enforceCallingPermission();
976 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700977 mStats.noteWifiScanStartedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700978 }
979 }
980
Nick Pelly6ccaa542012-06-15 15:22:47 -0700981 public void noteWifiScanStoppedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700982 enforceCallingPermission();
983 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700984 mStats.noteWifiScanStoppedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700985 }
986 }
987
Robert Greenwalta029ea12013-09-25 16:38:12 -0700988 public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) {
989 enforceCallingPermission();
990 synchronized (mStats) {
991 mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph);
992 }
993 }
994
995 public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) {
996 enforceCallingPermission();
997 synchronized (mStats) {
998 mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws);
999 }
1000 }
1001
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001002 @Override
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001003 public void noteNetworkInterfaceType(String iface, int networkType) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001004 enforceCallingPermission();
1005 synchronized (mStats) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001006 mStats.noteNetworkInterfaceTypeLocked(iface, networkType);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -07001007 }
1008 }
1009
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001010 @Override
1011 public void noteNetworkStatsEnabled() {
1012 enforceCallingPermission();
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001013 // During device boot, qtaguid isn't enabled until after the inital
1014 // loading of battery stats. Now that they're enabled, take our initial
1015 // snapshot for future delta calculation.
1016 mWorker.scheduleSync("network-stats-enabled",
1017 BatteryExternalStatsWorker.UPDATE_RADIO | BatteryExternalStatsWorker.UPDATE_WIFI);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001018 }
1019
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07001020 @Override
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001021 public void noteDeviceIdleMode(int mode, String activeReason, int activeUid) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07001022 enforceCallingPermission();
1023 synchronized (mStats) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001024 mStats.noteDeviceIdleModeLocked(mode, activeReason, activeUid);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07001025 }
1026 }
1027
Dianne Hackborn3accca02013-09-20 09:32:11 -07001028 public void notePackageInstalled(String pkgName, long versionCode) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07001029 enforceCallingPermission();
1030 synchronized (mStats) {
1031 mStats.notePackageInstalledLocked(pkgName, versionCode);
1032 }
1033 }
1034
1035 public void notePackageUninstalled(String pkgName) {
1036 enforceCallingPermission();
1037 synchronized (mStats) {
1038 mStats.notePackageUninstalledLocked(pkgName);
1039 }
1040 }
1041
Adam Lesinski6771d622016-01-15 18:14:47 -08001042 @Override
Bookatzb1f04f32017-05-19 13:57:32 -07001043 public void noteBleScanStarted(WorkSource ws, boolean isUnoptimized) {
Adam Lesinski6771d622016-01-15 18:14:47 -08001044 enforceCallingPermission();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001045 synchronized (mStats) {
Bookatzb1f04f32017-05-19 13:57:32 -07001046 mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001047 }
Adam Lesinski6771d622016-01-15 18:14:47 -08001048 }
1049
1050 @Override
Bookatz94c5a312017-07-11 16:49:17 -07001051 public void noteBleScanStopped(WorkSource ws, boolean isUnoptimized) {
Adam Lesinski6771d622016-01-15 18:14:47 -08001052 enforceCallingPermission();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001053 synchronized (mStats) {
Bookatz94c5a312017-07-11 16:49:17 -07001054 mStats.noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001055 }
1056 }
1057
1058 @Override
1059 public void noteResetBleScan() {
1060 enforceCallingPermission();
1061 synchronized (mStats) {
1062 mStats.noteResetBluetoothScanLocked();
1063 }
Adam Lesinski6771d622016-01-15 18:14:47 -08001064 }
1065
Adam Lesinski010bf372016-04-11 12:18:18 -07001066 @Override
Bookatz4ebc0642017-05-11 12:21:19 -07001067 public void noteBleScanResults(WorkSource ws, int numNewResults) {
Bookatz956f36bf2017-04-28 09:48:17 -07001068 enforceCallingPermission();
1069 synchronized (mStats) {
Bookatz4ebc0642017-05-11 12:21:19 -07001070 mStats.noteBluetoothScanResultsFromSourceLocked(ws, numNewResults);
Bookatz956f36bf2017-04-28 09:48:17 -07001071 }
1072 }
1073
1074 @Override
Adam Lesinski010bf372016-04-11 12:18:18 -07001075 public void noteWifiControllerActivity(WifiActivityEnergyInfo info) {
1076 enforceCallingPermission();
1077
1078 if (info == null || !info.isValid()) {
1079 Slog.e(TAG, "invalid wifi data given: " + info);
1080 return;
1081 }
1082
Adam Lesinski14ae39a2017-05-26 11:50:40 -07001083 mStats.updateWifiState(info);
Adam Lesinski010bf372016-04-11 12:18:18 -07001084 }
1085
1086 @Override
1087 public void noteBluetoothControllerActivity(BluetoothActivityEnergyInfo info) {
1088 enforceCallingPermission();
1089 if (info == null || !info.isValid()) {
1090 Slog.e(TAG, "invalid bluetooth data given: " + info);
1091 return;
1092 }
1093
Adam Lesinskic357e682018-02-28 12:55:39 -08001094 synchronized (mStats) {
1095 mStats.updateBluetoothStateLocked(info);
1096 }
Adam Lesinski010bf372016-04-11 12:18:18 -07001097 }
1098
1099 @Override
1100 public void noteModemControllerActivity(ModemActivityInfo info) {
1101 enforceCallingPermission();
1102
1103 if (info == null || !info.isValid()) {
1104 Slog.e(TAG, "invalid modem data given: " + info);
1105 return;
1106 }
1107
Adam Lesinski14ae39a2017-05-26 11:50:40 -07001108 mStats.updateMobileRadioState(info);
Adam Lesinski010bf372016-04-11 12:18:18 -07001109 }
1110
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001111 public boolean isOnBattery() {
1112 return mStats.isOnBattery();
1113 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001114
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001115 @Override
1116 public void setBatteryState(final int status, final int health, final int plugType,
Adam Lesinski041d9172016-12-12 12:03:56 -08001117 final int level, final int temp, final int volt, final int chargeUAh,
1118 final int chargeFullUAh) {
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001119 enforceCallingPermission();
1120
1121 // BatteryService calls us here and we may update external state. It would be wrong
1122 // to block such a low level service like BatteryService on external stats like WiFi.
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001123 mWorker.scheduleRunnable(() -> {
1124 synchronized (mStats) {
Sudheer Shankac57729a2018-02-09 15:44:42 -08001125 final boolean onBattery = BatteryStatsImpl.isOnBattery(plugType, status);
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001126 if (mStats.isOnBattery() == onBattery) {
1127 // The battery state has not changed, so we don't need to sync external
1128 // stats immediately.
1129 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
1130 chargeUAh, chargeFullUAh);
1131 return;
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001132 }
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001133 }
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001134
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001135 // Sync external stats first as the battery has changed states. If we don't sync
1136 // before changing the state, we may not collect the relevant data later.
1137 // Order here is guaranteed since we're scheduling from the same thread and we are
1138 // using a single threaded executor.
1139 mWorker.scheduleSync("battery-state", BatteryExternalStatsWorker.UPDATE_ALL);
1140 mWorker.scheduleRunnable(() -> {
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001141 synchronized (mStats) {
Adam Lesinski926969b2016-04-28 17:31:12 -07001142 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
Adam Lesinski041d9172016-12-12 12:03:56 -08001143 chargeUAh, chargeFullUAh);
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001144 }
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001145 });
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001146 });
Evan Millar633a1742009-04-02 16:36:33 -07001147 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001148
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001149 public long getAwakeTimeBattery() {
1150 mContext.enforceCallingOrSelfPermission(
1151 android.Manifest.permission.BATTERY_STATS, null);
1152 return mStats.getAwakeTimeBattery();
1153 }
1154
1155 public long getAwakeTimePlugged() {
1156 mContext.enforceCallingOrSelfPermission(
1157 android.Manifest.permission.BATTERY_STATS, null);
1158 return mStats.getAwakeTimePlugged();
1159 }
1160
1161 public void enforceCallingPermission() {
1162 if (Binder.getCallingPid() == Process.myPid()) {
1163 return;
1164 }
1165 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
1166 Binder.getCallingPid(), Binder.getCallingUid(), null);
1167 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001168
1169 final class WakeupReasonThread extends Thread {
Adam Lesinski515702c2015-07-23 18:13:38 -07001170 private static final int MAX_REASON_SIZE = 512;
1171 private CharsetDecoder mDecoder;
1172 private ByteBuffer mUtf8Buffer;
1173 private CharBuffer mUtf16Buffer;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001174
1175 WakeupReasonThread() {
1176 super("BatteryStats_wakeupReason");
1177 }
1178
1179 public void run() {
1180 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
1181
Adam Lesinski515702c2015-07-23 18:13:38 -07001182 mDecoder = StandardCharsets.UTF_8
1183 .newDecoder()
1184 .onMalformedInput(CodingErrorAction.REPLACE)
1185 .onUnmappableCharacter(CodingErrorAction.REPLACE)
1186 .replaceWith("?");
1187
1188 mUtf8Buffer = ByteBuffer.allocateDirect(MAX_REASON_SIZE);
1189 mUtf16Buffer = CharBuffer.allocate(MAX_REASON_SIZE);
1190
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001191 try {
Adam Lesinski515702c2015-07-23 18:13:38 -07001192 String reason;
1193 while ((reason = waitWakeup()) != null) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001194 synchronized (mStats) {
Adam Lesinski515702c2015-07-23 18:13:38 -07001195 mStats.noteWakeupReasonLocked(reason);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001196 }
1197 }
1198 } catch (RuntimeException e) {
1199 Slog.e(TAG, "Failure reading wakeup reasons", e);
1200 }
1201 }
Adam Lesinski515702c2015-07-23 18:13:38 -07001202
1203 private String waitWakeup() {
1204 mUtf8Buffer.clear();
1205 mUtf16Buffer.clear();
1206 mDecoder.reset();
1207
1208 int bytesWritten = nativeWaitWakeup(mUtf8Buffer);
1209 if (bytesWritten < 0) {
1210 return null;
1211 } else if (bytesWritten == 0) {
1212 return "unknown";
1213 }
1214
1215 // Set the buffer's limit to the number of bytes written.
1216 mUtf8Buffer.limit(bytesWritten);
1217
1218 // Decode the buffer from UTF-8 to UTF-16.
1219 // Unmappable characters will be replaced.
1220 mDecoder.decode(mUtf8Buffer, mUtf16Buffer, true);
1221 mUtf16Buffer.flip();
1222
1223 // Create a String from the UTF-16 buffer.
1224 return mUtf16Buffer.toString();
1225 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001226 }
1227
Adam Lesinski515702c2015-07-23 18:13:38 -07001228 private static native int nativeWaitWakeup(ByteBuffer outBuffer);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001229
Dianne Hackbornae384452011-06-28 12:33:48 -07001230 private void dumpHelp(PrintWriter pw) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001231 pw.println("Battery stats (batterystats) dump options:");
Kweku Adams3d160912018-05-07 11:26:27 -07001232 pw.println(" [--checkin] [--proto] [--history] [--history-start] [--charged] [-c]");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001233 pw.println(" [--daily] [--reset] [--write] [--new-daily] [--read-daily] [-h] [<package.name>]");
Dianne Hackborn865b79b2015-08-18 17:33:00 -07001234 pw.println(" --checkin: generate output for a checkin report; will write (and clear) the");
1235 pw.println(" last old completed stats when they had been reset.");
Joe Onorato1476d322016-05-05 14:46:15 -07001236 pw.println(" -c: write the current stats in checkin format.");
Kweku Adams3d160912018-05-07 11:26:27 -07001237 pw.println(" --proto: write the current aggregate stats (without history) in proto format.");
Dianne Hackborn099bc622014-01-22 13:39:16 -08001238 pw.println(" --history: show only history data.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001239 pw.println(" --history-start <num>: show only history data starting at given time offset.");
Hui Yu0ed84f12018-06-20 19:07:56 -07001240 pw.println(" --history-create-events <num>: create <num> of battery history events.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001241 pw.println(" --charged: only output data since last charged.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001242 pw.println(" --daily: only output full daily data.");
Dianne Hackbornae384452011-06-28 12:33:48 -07001243 pw.println(" --reset: reset the stats, clearing all current data.");
1244 pw.println(" --write: force write current collected stats to disk.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001245 pw.println(" --new-daily: immediately create and write new daily stats record.");
1246 pw.println(" --read-daily: read-load last written daily stats.");
Sudheer Shanka5c19b892018-01-05 17:25:46 -08001247 pw.println(" --settings: dump the settings key/values related to batterystats");
Mike Ma234d1822018-03-13 18:53:21 -07001248 pw.println(" --cpu: dump cpu stats for debugging purpose");
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001249 pw.println(" <package.name>: optional name of package to filter output by.");
Dianne Hackbornfc064132014-06-02 12:42:12 -07001250 pw.println(" -h: print this help text.");
1251 pw.println("Battery stats (batterystats) commands:");
1252 pw.println(" enable|disable <option>");
1253 pw.println(" Enable or disable a running option. Option state is not saved across boots.");
1254 pw.println(" Options are:");
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001255 pw.println(" full-history: include additional detailed events in battery history:");
Dianne Hackborn1e383822015-04-10 14:02:33 -07001256 pw.println(" wake_lock_in, alarms and proc events");
Dianne Hackbornfc064132014-06-02 12:42:12 -07001257 pw.println(" no-auto-reset: don't automatically reset stats when unplugged");
Amith Yamasani674c9bb2017-02-01 09:45:17 -08001258 pw.println(" pretend-screen-off: pretend the screen is off, even if screen state changes");
Dianne Hackbornae384452011-06-28 12:33:48 -07001259 }
1260
Sudheer Shanka5c19b892018-01-05 17:25:46 -08001261 private void dumpSettings(PrintWriter pw) {
1262 synchronized (mStats) {
1263 mStats.dumpConstantsLocked(pw);
1264 }
1265 }
1266
Mike Ma234d1822018-03-13 18:53:21 -07001267 private void dumpCpuStats(PrintWriter pw) {
1268 synchronized (mStats) {
1269 mStats.dumpCpuStatsLocked(pw);
1270 }
1271 }
1272
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001273 private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
1274 i++;
1275 if (i >= args.length) {
1276 pw.println("Missing option argument for " + (enable ? "--enable" : "--disable"));
1277 dumpHelp(pw);
1278 return -1;
1279 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001280 if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001281 synchronized (mStats) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001282 mStats.setRecordAllHistoryLocked(enable);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001283 }
Dianne Hackborn9a755432014-05-15 17:05:22 -07001284 } else if ("no-auto-reset".equals(args[i])) {
1285 synchronized (mStats) {
1286 mStats.setNoAutoReset(enable);
1287 }
Amith Yamasani674c9bb2017-02-01 09:45:17 -08001288 } else if ("pretend-screen-off".equals(args[i])) {
1289 synchronized (mStats) {
1290 mStats.setPretendScreenOff(enable);
1291 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001292 } else {
1293 pw.println("Unknown enable/disable option: " + args[i]);
1294 dumpHelp(pw);
1295 return -1;
1296 }
1297 return i;
1298 }
1299
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 @Override
1302 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkey6df866a2017-03-31 14:08:23 -06001303 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
Kenny Root3abd75b2011-09-29 11:00:41 -07001304
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001305 int flags = 0;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001306 boolean useCheckinFormat = false;
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001307 boolean toProto = false;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001308 boolean isRealCheckin = false;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001309 boolean noOutput = false;
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001310 boolean writeData = false;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001311 long historyStart = -1;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001312 int reqUid = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001313 if (args != null) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001314 for (int i=0; i<args.length; i++) {
1315 String arg = args[i];
Dianne Hackborne4a59512010-12-07 11:08:07 -08001316 if ("--checkin".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001317 useCheckinFormat = true;
1318 isRealCheckin = true;
Dianne Hackborn099bc622014-01-22 13:39:16 -08001319 } else if ("--history".equals(arg)) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001320 flags |= BatteryStats.DUMP_HISTORY_ONLY;
1321 } else if ("--history-start".equals(arg)) {
1322 flags |= BatteryStats.DUMP_HISTORY_ONLY;
1323 i++;
1324 if (i >= args.length) {
1325 pw.println("Missing time argument for --history-since");
1326 dumpHelp(pw);
1327 return;
1328 }
Hui Yu0ed84f12018-06-20 19:07:56 -07001329 historyStart = ParseUtils.parseLong(args[i], 0);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001330 writeData = true;
Hui Yu0ed84f12018-06-20 19:07:56 -07001331 } else if ("--history-create-events".equals(arg)) {
1332 i++;
1333 if (i >= args.length) {
1334 pw.println("Missing events argument for --history-create-events");
1335 dumpHelp(pw);
1336 return;
1337 }
1338 final long events = ParseUtils.parseLong(args[i], 0);
1339 synchronized (mStats) {
1340 mStats.createFakeHistoryEvents(events);
1341 pw.println("Battery history create events started.");
1342 noOutput = true;
1343 }
Dianne Hackborn49021f52013-09-04 18:03:40 -07001344 } else if ("-c".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001345 useCheckinFormat = true;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001346 flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001347 } else if ("--proto".equals(arg)) {
1348 toProto = true;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001349 } else if ("--charged".equals(arg)) {
1350 flags |= BatteryStats.DUMP_CHARGED_ONLY;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001351 } else if ("--daily".equals(arg)) {
1352 flags |= BatteryStats.DUMP_DAILY_ONLY;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001353 } else if ("--reset".equals(arg)) {
1354 synchronized (mStats) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001355 mStats.resetAllStatsCmdLocked();
Dianne Hackborne4a59512010-12-07 11:08:07 -08001356 pw.println("Battery stats reset.");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001357 noOutput = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 }
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001359 mWorker.scheduleSync("dump", BatteryExternalStatsWorker.UPDATE_ALL);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001360 } else if ("--write".equals(arg)) {
Sudheer Shankab2f83c12017-11-13 19:25:01 -08001361 syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001362 synchronized (mStats) {
1363 mStats.writeSyncLocked();
1364 pw.println("Battery stats written.");
1365 noOutput = true;
1366 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001367 } else if ("--new-daily".equals(arg)) {
1368 synchronized (mStats) {
1369 mStats.recordDailyStatsLocked();
1370 pw.println("New daily stats written.");
1371 noOutput = true;
1372 }
1373 } else if ("--read-daily".equals(arg)) {
1374 synchronized (mStats) {
1375 mStats.readDailyStatsLocked();
1376 pw.println("Last daily stats read.");
1377 noOutput = true;
1378 }
Dianne Hackbornfc064132014-06-02 12:42:12 -07001379 } else if ("--enable".equals(arg) || "enable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001380 i = doEnableOrDisable(pw, i, args, true);
1381 if (i < 0) {
1382 return;
1383 }
1384 pw.println("Enabled: " + args[i]);
1385 return;
Dianne Hackbornfc064132014-06-02 12:42:12 -07001386 } else if ("--disable".equals(arg) || "disable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001387 i = doEnableOrDisable(pw, i, args, false);
1388 if (i < 0) {
1389 return;
1390 }
1391 pw.println("Disabled: " + args[i]);
1392 return;
Dianne Hackbornae384452011-06-28 12:33:48 -07001393 } else if ("-h".equals(arg)) {
1394 dumpHelp(pw);
1395 return;
Sudheer Shanka5c19b892018-01-05 17:25:46 -08001396 } else if ("--settings".equals(arg)) {
1397 dumpSettings(pw);
1398 return;
Mike Ma234d1822018-03-13 18:53:21 -07001399 } else if ("--cpu".equals(arg)) {
1400 dumpCpuStats(pw);
1401 return;
Mike Lockwoode8174042011-08-16 12:53:43 -07001402 } else if ("-a".equals(arg)) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001403 flags |= BatteryStats.DUMP_VERBOSE;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001404 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001405 pw.println("Unknown option: " + arg);
Dianne Hackbornae384452011-06-28 12:33:48 -07001406 dumpHelp(pw);
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001407 return;
1408 } else {
1409 // Not an option, last argument must be a package name.
1410 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07001411 reqUid = mContext.getPackageManager().getPackageUidAsUser(arg,
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001412 UserHandle.getCallingUserId());
1413 } catch (PackageManager.NameNotFoundException e) {
1414 pw.println("Unknown package: " + arg);
1415 dumpHelp(pw);
1416 return;
1417 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001418 }
1419 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001420 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001421 if (noOutput) {
1422 return;
1423 }
Dianne Hackborn13a6a9b2015-04-22 18:03:59 -07001424
1425 long ident = Binder.clearCallingIdentity();
1426 try {
1427 if (BatteryStatsHelper.checkWifiOnly(mContext)) {
1428 flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
1429 }
1430 // Fetch data from external sources and update the BatteryStatsImpl object with them.
Sudheer Shankab2f83c12017-11-13 19:25:01 -08001431 syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
Dianne Hackborn13a6a9b2015-04-22 18:03:59 -07001432 } finally {
1433 Binder.restoreCallingIdentity(ident);
Dianne Hackbornd953c532014-08-16 18:17:38 -07001434 }
Dianne Hackborn13a6a9b2015-04-22 18:03:59 -07001435
Dianne Hackbornab4a81b2014-10-09 17:59:38 -07001436 if (reqUid >= 0) {
1437 // By default, if the caller is only interested in a specific package, then
1438 // we only dump the aggregated data since charged.
Dianne Hackborn1e725a72015-03-24 18:23:19 -07001439 if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
Dianne Hackbornab4a81b2014-10-09 17:59:38 -07001440 flags |= BatteryStats.DUMP_CHARGED_ONLY;
1441 // Also if they are doing -c, we don't want history.
1442 flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY;
1443 }
1444 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001445
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001446 if (toProto) {
1447 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
1448 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL);
1449 if (isRealCheckin) {
1450 // For a real checkin, first we want to prefer to use the last complete checkin
1451 // file if there is one.
1452 synchronized (mStats.mCheckinFile) {
1453 if (mStats.mCheckinFile.exists()) {
1454 try {
1455 byte[] raw = mStats.mCheckinFile.readFully();
1456 if (raw != null) {
1457 Parcel in = Parcel.obtain();
1458 in.unmarshall(raw, 0, raw.length);
1459 in.setDataPosition(0);
1460 BatteryStatsImpl checkinStats = new BatteryStatsImpl(
1461 null, mStats.mHandler, null, mUserManagerUserInfoProvider);
1462 checkinStats.readSummaryFromParcel(in);
1463 in.recycle();
Kweku Adams3d160912018-05-07 11:26:27 -07001464 checkinStats.dumpProtoLocked(
1465 mContext, fd, apps, flags, historyStart);
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001466 mStats.mCheckinFile.delete();
1467 return;
1468 }
1469 } catch (IOException | ParcelFormatException e) {
1470 Slog.w(TAG, "Failure reading checkin file "
1471 + mStats.mCheckinFile.getBaseFile(), e);
1472 }
1473 }
1474 }
1475 }
1476 if (DBG) Slog.d(TAG, "begin dumpProtoLocked from UID " + Binder.getCallingUid());
1477 synchronized (mStats) {
Kweku Adams3d160912018-05-07 11:26:27 -07001478 mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart);
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001479 if (writeData) {
1480 mStats.writeAsyncLocked();
1481 }
1482 }
1483 if (DBG) Slog.d(TAG, "end dumpProtoLocked");
1484 } else if (useCheckinFormat) {
Dianne Hackborn9cfba352016-03-24 17:31:28 -07001485 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001486 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001487 if (isRealCheckin) {
1488 // For a real checkin, first we want to prefer to use the last complete checkin
1489 // file if there is one.
1490 synchronized (mStats.mCheckinFile) {
1491 if (mStats.mCheckinFile.exists()) {
1492 try {
1493 byte[] raw = mStats.mCheckinFile.readFully();
1494 if (raw != null) {
1495 Parcel in = Parcel.obtain();
1496 in.unmarshall(raw, 0, raw.length);
1497 in.setDataPosition(0);
1498 BatteryStatsImpl checkinStats = new BatteryStatsImpl(
Suprabh Shuklae6e723d2017-06-14 16:14:43 -07001499 null, mStats.mHandler, null, mUserManagerUserInfoProvider);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001500 checkinStats.readSummaryFromParcel(in);
1501 in.recycle();
1502 checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,
1503 historyStart);
1504 mStats.mCheckinFile.delete();
1505 return;
1506 }
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07001507 } catch (IOException | ParcelFormatException e) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001508 Slog.w(TAG, "Failure reading checkin file "
1509 + mStats.mCheckinFile.getBaseFile(), e);
1510 }
1511 }
1512 }
1513 }
Joe Onorato82ba91d2017-04-27 16:18:05 -07001514 if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
Dianne Hackborne4a59512010-12-07 11:08:07 -08001515 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001516 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001517 if (writeData) {
1518 mStats.writeAsyncLocked();
1519 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001520 }
Joe Onorato82ba91d2017-04-27 16:18:05 -07001521 if (DBG) Slog.d(TAG, "end dumpCheckinLocked");
Dianne Hackborne4a59512010-12-07 11:08:07 -08001522 } else {
Joe Onorato82ba91d2017-04-27 16:18:05 -07001523 if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
Dianne Hackborne4a59512010-12-07 11:08:07 -08001524 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001525 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001526 if (writeData) {
1527 mStats.writeAsyncLocked();
1528 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001529 }
Joe Onorato82ba91d2017-04-27 16:18:05 -07001530 if (DBG) Slog.d(TAG, "end dumpLocked");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001531 }
1532 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001533
Joe Onorato713fec82016-03-04 10:34:02 -08001534 /**
Siddharth Raya1fd0572017-11-13 14:20:47 -08001535 * Gets a snapshot of cellular stats
1536 * @hide
1537 */
1538 public CellularBatteryStats getCellularBatteryStats() {
1539 synchronized (mStats) {
1540 return mStats.getCellularBatteryStats();
1541 }
1542 }
1543
1544 /**
Siddharth Rayb50a6842017-12-14 15:15:28 -08001545 * Gets a snapshot of Wifi stats
1546 * @hide
1547 */
1548 public WifiBatteryStats getWifiBatteryStats() {
1549 synchronized (mStats) {
1550 return mStats.getWifiBatteryStats();
1551 }
1552 }
1553
1554 /**
Siddharth Ray78ccaf52017-12-23 16:16:21 -08001555 * Gets a snapshot of Gps stats
1556 * @hide
1557 */
1558 public GpsBatteryStats getGpsBatteryStats() {
1559 synchronized (mStats) {
1560 return mStats.getGpsBatteryStats();
1561 }
1562 }
1563
1564 /**
Joe Onorato713fec82016-03-04 10:34:02 -08001565 * Gets a snapshot of the system health for a particular uid.
1566 */
1567 @Override
1568 public HealthStatsParceler takeUidSnapshot(int requestUid) {
1569 if (requestUid != Binder.getCallingUid()) {
1570 mContext.enforceCallingOrSelfPermission(
1571 android.Manifest.permission.BATTERY_STATS, null);
1572 }
1573 long ident = Binder.clearCallingIdentity();
1574 try {
Sudheer Shankae56013a2018-04-23 11:22:15 -07001575 if (shouldCollectExternalStats()) {
1576 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
1577 }
Joe Onorato713fec82016-03-04 10:34:02 -08001578 synchronized (mStats) {
1579 return getHealthStatsForUidLocked(requestUid);
1580 }
1581 } catch (Exception ex) {
Joe Onorato82ba91d2017-04-27 16:18:05 -07001582 Slog.w(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex);
Joe Onorato713fec82016-03-04 10:34:02 -08001583 throw ex;
1584 } finally {
1585 Binder.restoreCallingIdentity(ident);
1586 }
1587 }
1588
1589 /**
1590 * Gets a snapshot of the system health for a number of uids.
1591 */
1592 @Override
1593 public HealthStatsParceler[] takeUidSnapshots(int[] requestUids) {
1594 if (!onlyCaller(requestUids)) {
1595 mContext.enforceCallingOrSelfPermission(
1596 android.Manifest.permission.BATTERY_STATS, null);
1597 }
1598 long ident = Binder.clearCallingIdentity();
1599 int i=-1;
1600 try {
Sudheer Shankae56013a2018-04-23 11:22:15 -07001601 if (shouldCollectExternalStats()) {
1602 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
1603 }
Joe Onorato713fec82016-03-04 10:34:02 -08001604 synchronized (mStats) {
1605 final int N = requestUids.length;
1606 final HealthStatsParceler[] results = new HealthStatsParceler[N];
1607 for (i=0; i<N; i++) {
1608 results[i] = getHealthStatsForUidLocked(requestUids[i]);
1609 }
1610 return results;
1611 }
1612 } catch (Exception ex) {
Joe Onorato82ba91d2017-04-27 16:18:05 -07001613 if (DBG) Slog.d(TAG, "Crashed while writing for takeUidSnapshots("
Joe Onorato713fec82016-03-04 10:34:02 -08001614 + Arrays.toString(requestUids) + ") i=" + i, ex);
1615 throw ex;
1616 } finally {
1617 Binder.restoreCallingIdentity(ident);
1618 }
1619 }
1620
Sudheer Shankae56013a2018-04-23 11:22:15 -07001621 private boolean shouldCollectExternalStats() {
1622 return (SystemClock.elapsedRealtime() - mWorker.getLastCollectionTimeStamp())
1623 > mStats.getExternalStatsCollectionRateLimitMs();
1624 }
1625
Joe Onorato713fec82016-03-04 10:34:02 -08001626 /**
1627 * Returns whether the Binder.getCallingUid is the only thing in requestUids.
1628 */
1629 private static boolean onlyCaller(int[] requestUids) {
1630 final int caller = Binder.getCallingUid();
1631 final int N = requestUids.length;
1632 for (int i=0; i<N; i++) {
1633 if (requestUids[i] != caller) {
1634 return false;
1635 }
1636 }
1637 return true;
1638 }
1639
1640 /**
1641 * Gets a HealthStatsParceler for the given uid. You should probably call
Adam Lesinski010bf372016-04-11 12:18:18 -07001642 * updateExternalStatsSync first.
Joe Onorato713fec82016-03-04 10:34:02 -08001643 */
1644 HealthStatsParceler getHealthStatsForUidLocked(int requestUid) {
1645 final HealthStatsBatteryStatsWriter writer = new HealthStatsBatteryStatsWriter();
1646 final HealthStatsWriter uidWriter = new HealthStatsWriter(UidHealthStats.CONSTANTS);
1647 final BatteryStats.Uid uid = mStats.getUidStats().get(requestUid);
1648 if (uid != null) {
1649 writer.writeUid(uidWriter, mStats, uid);
1650 }
1651 return new HealthStatsParceler(uidWriter);
1652 }
1653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654}