blob: 9c2b1a5d17aac2ae51c30a258d7b6f310f713859 [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;
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070062import com.android.server.LocalServices;
Amith Yamasani32dbefd2009-06-19 09:21:17 -070063
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070064import java.io.File;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import java.io.FileDescriptor;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -070066import java.io.IOException;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import java.io.PrintWriter;
Adam Lesinski515702c2015-07-23 18:13:38 -070068import java.nio.ByteBuffer;
69import java.nio.CharBuffer;
70import java.nio.charset.CharsetDecoder;
71import java.nio.charset.CodingErrorAction;
72import java.nio.charset.StandardCharsets;
Joe Onorato713fec82016-03-04 10:34:02 -080073import java.util.Arrays;
Dianne Hackborne4a59512010-12-07 11:08:07 -080074import java.util.List;
Adam Lesinskib3a1bad2017-05-26 11:50:40 -070075import java.util.concurrent.ExecutionException;
76import java.util.concurrent.Future;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080077
78/**
79 * All information we are collecting about things that can happen that impact
80 * battery life.
81 */
Dianne Hackborncbefd8d2014-05-14 11:42:00 -070082public final class BatteryStatsService extends IBatteryStats.Stub
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -070083 implements PowerManagerInternal.LowPowerModeListener,
84 BatteryStatsImpl.PlatformIdleStateCallback {
Dianne Hackbornc51cf032014-03-02 19:08:15 -080085 static final String TAG = "BatteryStatsService";
Joe Onorato82ba91d2017-04-27 16:18:05 -070086 static final boolean DBG = false;
Dianne Hackbornc51cf032014-03-02 19:08:15 -080087
Adam Lesinski010bf372016-04-11 12:18:18 -070088 private static IBatteryStats sService;
89
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 final BatteryStatsImpl mStats;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -070091 private final BatteryStatsImpl.UserInfoProvider mUserManagerUserInfoProvider;
Adam Lesinskib3a1bad2017-05-26 11:50:40 -070092 private final Context mContext;
93 private final BatteryExternalStatsWorker mWorker;
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -070094
Bookatz50df7112017-08-04 14:53:26 -070095 private native void getLowPowerStats(RpmStats rpmStats);
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -070096 private native int getPlatformLowPowerStats(ByteBuffer outBuffer);
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +000097 private native int getSubsystemLowPowerStats(ByteBuffer outBuffer);
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -070098 private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8
99 .newDecoder()
100 .onMalformedInput(CodingErrorAction.REPLACE)
101 .onUnmappableCharacter(CodingErrorAction.REPLACE)
102 .replaceWith("?");
103 private ByteBuffer mUtf8BufferStat = ByteBuffer.allocateDirect(MAX_LOW_POWER_STATS_SIZE);
104 private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE);
Kelly Rossmoyer03ad13e2018-03-13 13:10:14 -0700105 private static final int MAX_LOW_POWER_STATS_SIZE = 2048;
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700106
Bookatz50df7112017-08-04 14:53:26 -0700107 /**
108 * Replaces the information in the given rpmStats with up-to-date information.
109 */
110 @Override
111 public void fillLowPowerStats(RpmStats rpmStats) {
112 if (DBG) Slog.d(TAG, "begin getLowPowerStats");
113 try {
114 getLowPowerStats(rpmStats);
115 } finally {
116 if (DBG) Slog.d(TAG, "end getLowPowerStats");
117 }
118 }
119
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700120 @Override
121 public String getPlatformLowPowerStats() {
Joe Onorato82ba91d2017-04-27 16:18:05 -0700122 if (DBG) Slog.d(TAG, "begin getPlatformLowPowerStats");
Adam Lesinskicd722082017-03-30 13:54:09 -0700123 try {
124 mUtf8BufferStat.clear();
125 mUtf16BufferStat.clear();
126 mDecoderStat.reset();
127 int bytesWritten = getPlatformLowPowerStats(mUtf8BufferStat);
128 if (bytesWritten < 0) {
129 return null;
130 } else if (bytesWritten == 0) {
131 return "Empty";
132 }
133 mUtf8BufferStat.limit(bytesWritten);
134 mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
135 mUtf16BufferStat.flip();
136 return mUtf16BufferStat.toString();
137 } finally {
Joe Onorato82ba91d2017-04-27 16:18:05 -0700138 if (DBG) Slog.d(TAG, "end getPlatformLowPowerStats");
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700139 }
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700140 }
141
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +0000142 @Override
143 public String getSubsystemLowPowerStats() {
Bookatz50df7112017-08-04 14:53:26 -0700144 if (DBG) Slog.d(TAG, "begin getSubsystemLowPowerStats");
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +0000145 try {
146 mUtf8BufferStat.clear();
147 mUtf16BufferStat.clear();
148 mDecoderStat.reset();
149 int bytesWritten = getSubsystemLowPowerStats(mUtf8BufferStat);
150 if (bytesWritten < 0) {
151 return null;
152 } else if (bytesWritten == 0) {
153 return "Empty";
154 }
155 mUtf8BufferStat.limit(bytesWritten);
156 mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true);
157 mUtf16BufferStat.flip();
158 return mUtf16BufferStat.toString();
159 } finally {
Bookatz50df7112017-08-04 14:53:26 -0700160 if (DBG) Slog.d(TAG, "end getSubsystemLowPowerStats");
Ahmed ElArabawyd8b44112017-05-23 21:25:02 +0000161 }
162 }
163
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700164 BatteryStatsService(Context context, File systemDir, Handler handler) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700165 // BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through.
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700166 mContext = context;
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700167 mUserManagerUserInfoProvider = new BatteryStatsImpl.UserInfoProvider() {
168 private UserManagerInternal umi;
169 @Override
170 public int[] getUserIds() {
171 if (umi == null) {
172 umi = LocalServices.getService(UserManagerInternal.class);
173 }
174 return (umi != null) ? umi.getUserIds() : null;
175 }
176 };
177 mStats = new BatteryStatsImpl(systemDir, handler, this, mUserManagerUserInfoProvider);
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700178 mWorker = new BatteryExternalStatsWorker(context, mStats);
179 mStats.setExternalStatsSyncLocked(mWorker);
180 mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger(
181 com.android.internal.R.integer.config_radioScanningTimeout) * 1000L);
182 mStats.setPowerProfileLocked(new PowerProfile(context));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800183 }
Badhri Jagan Sridharan68cdf192016-04-03 21:57:15 -0700184
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700185 public void publish() {
David Chenc8a43242017-10-17 16:23:28 -0700186 LocalServices.addService(BatteryStatsInternal.class, new LocalService());
Adam Lesinski6832f392015-09-05 18:05:40 -0700187 ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
Jeff Brown2c43c332014-06-12 22:38:59 -0700188 }
189
Sudheer Shanka5c19b892018-01-05 17:25:46 -0800190 public void systemServicesReady() {
191 mStats.systemServicesReady(mContext);
192 }
193
David Chenc8a43242017-10-17 16:23:28 -0700194 private final class LocalService extends BatteryStatsInternal {
195 @Override
196 public String[] getWifiIfaces() {
197 return mStats.getWifiIfaces().clone();
198 }
199
200 @Override
201 public String[] getMobileIfaces() {
202 return mStats.getMobileIfaces().clone();
203 }
Amith Yamasani977e11f2018-02-16 11:29:54 -0800204
205 @Override
206 public void noteJobsDeferred(int uid, int numDeferred, long sinceLast) {
207 if (DBG) Slog.d(TAG, "Jobs deferred " + uid + ": " + numDeferred + " " + sinceLast);
208 BatteryStatsService.this.noteJobsDeferred(uid, numDeferred, sinceLast);
209 }
David Chenc8a43242017-10-17 16:23:28 -0700210 }
211
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700212 private static void awaitUninterruptibly(Future<?> future) {
213 while (true) {
214 try {
215 future.get();
216 return;
217 } catch (ExecutionException e) {
218 return;
219 } catch (InterruptedException e) {
220 // Keep looping
221 }
222 }
223 }
224
Sudheer Shankab2f83c12017-11-13 19:25:01 -0800225 private void syncStats(String reason, int flags) {
226 awaitUninterruptibly(mWorker.scheduleSync(reason, flags));
227 }
228
Jeff Brown2c43c332014-06-12 22:38:59 -0700229 /**
230 * At the time when the constructor runs, the power manager has not yet been
231 * initialized. So we initialize the low power observer later.
232 */
233 public void initPowerManagement() {
Adam Lesinski010bf372016-04-11 12:18:18 -0700234 final PowerManagerInternal powerMgr = LocalServices.getService(PowerManagerInternal.class);
235 powerMgr.registerLowPowerModeObserver(this);
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700236 synchronized (mStats) {
237 mStats.notePowerSaveModeLocked(
238 powerMgr.getLowPowerState(ServiceType.BATTERY_STATS)
239 .batterySaverEnabled);
240 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -0800241 (new WakeupReasonThread()).start();
Jeff Brown2c43c332014-06-12 22:38:59 -0700242 }
243
Dianne Hackborn55280a92009-05-07 15:53:46 -0700244 public void shutdown() {
Joe Onorato8a9b2202010-02-26 18:56:32 -0800245 Slog.w("BatteryStats", "Writing battery stats before shutdown...");
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700246
Sudheer Shankab2f83c12017-11-13 19:25:01 -0800247 syncStats("shutdown", BatteryExternalStatsWorker.UPDATE_ALL);
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700248
Dianne Hackborn55280a92009-05-07 15:53:46 -0700249 synchronized (mStats) {
Dianne Hackborn6b7b4842010-06-14 17:17:44 -0700250 mStats.shutdownLocked();
Dianne Hackborn55280a92009-05-07 15:53:46 -0700251 }
Adam Lesinski20b84df2016-04-19 17:33:33 -0700252
253 // Shutdown the thread we made.
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700254 mWorker.shutdown();
Dianne Hackborn55280a92009-05-07 15:53:46 -0700255 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700256
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800257 public static IBatteryStats getService() {
258 if (sService != null) {
259 return sService;
260 }
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700261 IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800262 sService = asInterface(b);
263 return sService;
264 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700265
266 @Override
jackqdyulei455e90a2017-02-09 15:29:16 -0800267 public int getServiceType() {
268 return ServiceType.BATTERY_STATS;
269 }
270
271 @Override
272 public void onLowPowerModeChanged(PowerSaveState result) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700273 synchronized (mStats) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700274 mStats.notePowerSaveModeLocked(result.batterySaverEnabled);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700275 }
276 }
277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 /**
279 * @return the current statistics object, which may be modified
280 * to reflect events that affect battery usage. You must lock the
281 * stats object before doing anything with it.
282 */
283 public BatteryStatsImpl getActiveStatistics() {
284 return mStats;
285 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700286
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700287 /**
288 * Schedules a write to disk to occur. This will cause the BatteryStatsImpl
289 * object to update with the latest info, then write to disk.
290 */
291 public void scheduleWriteToDisk() {
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700292 mWorker.scheduleWrite();
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700293 }
294
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700295 // These are for direct use by the activity manager...
296
Adam Lesinskib83ffee2015-05-12 14:43:47 -0700297 /**
298 * Remove a UID from the BatteryStats and BatteryStats' external dependencies.
299 */
300 void removeUid(int uid) {
301 synchronized (mStats) {
302 mStats.removeUidStatsLocked(uid);
303 }
304 }
305
Suprabh Shuklae6e723d2017-06-14 16:14:43 -0700306 void onCleanupUser(int userId) {
307 synchronized (mStats) {
308 mStats.onCleanupUserLocked(userId);
309 }
310 }
311
312 void onUserRemoved(int userId) {
313 synchronized (mStats) {
314 mStats.onUserRemovedLocked(userId);
315 }
316 }
317
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700318 void addIsolatedUid(int isolatedUid, int appUid) {
319 synchronized (mStats) {
320 mStats.addIsolatedUidLocked(isolatedUid, appUid);
321 }
322 }
323
324 void removeIsolatedUid(int isolatedUid, int appUid) {
325 synchronized (mStats) {
Adam Lesinski61db88f2015-07-01 15:05:07 -0700326 mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid);
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700327 }
328 }
329
330 void noteProcessStart(String name, int uid) {
331 synchronized (mStats) {
332 mStats.noteProcessStartLocked(name, uid);
Bookatz90867622018-01-31 15:05:57 -0800333 StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800334 StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__STARTED);
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700335 }
336 }
337
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800338 void noteProcessCrash(String name, int uid) {
339 synchronized (mStats) {
340 mStats.noteProcessCrashLocked(name, uid);
Bookatz90867622018-01-31 15:05:57 -0800341 StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800342 StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__CRASHED);
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800343 }
344 }
345
346 void noteProcessAnr(String name, int uid) {
347 synchronized (mStats) {
348 mStats.noteProcessAnrLocked(name, uid);
349 }
350 }
351
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700352 void noteProcessFinish(String name, int uid) {
353 synchronized (mStats) {
354 mStats.noteProcessFinishLocked(name, uid);
Bookatz90867622018-01-31 15:05:57 -0800355 StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name,
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800356 StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__FINISHED);
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700357 }
358 }
359
Bookatzdb026a22018-01-10 19:01:56 -0800360 /** @param state Process state from ActivityManager.java. */
Dianne Hackborna8d10942015-11-19 17:55:19 -0800361 void noteUidProcessState(int uid, int state) {
362 synchronized (mStats) {
Bookatzdb026a22018-01-10 19:01:56 -0800363 StatsLog.write(StatsLog.UID_PROCESS_STATE_CHANGED, uid,
364 ActivityManager.processStateAmToProto(state));
Yao Chend54f9dd2017-10-17 17:37:48 +0000365
Dianne Hackborna8d10942015-11-19 17:55:19 -0800366 mStats.noteUidProcessStateLocked(uid, state);
367 }
368 }
369
Dianne Hackborn2f1993e2014-09-26 11:28:01 -0700370 // Public interface...
371
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372 public byte[] getStatistics() {
373 mContext.enforceCallingPermission(
374 android.Manifest.permission.BATTERY_STATS, null);
Joe Onorato8a9b2202010-02-26 18:56:32 -0800375 //Slog.i("foo", "SENDING BATTERY INFO:");
376 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800377 Parcel out = Parcel.obtain();
Sudheer Shankab2f83c12017-11-13 19:25:01 -0800378 syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700379 synchronized (mStats) {
380 mStats.writeToParcel(out, 0);
381 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 byte[] data = out.marshall();
383 out.recycle();
384 return data;
385 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700386
387 public ParcelFileDescriptor getStatisticsStream() {
388 mContext.enforceCallingPermission(
389 android.Manifest.permission.BATTERY_STATS, null);
390 //Slog.i("foo", "SENDING BATTERY INFO:");
391 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
392 Parcel out = Parcel.obtain();
Sudheer Shankab2f83c12017-11-13 19:25:01 -0800393 syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL);
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700394 synchronized (mStats) {
395 mStats.writeToParcel(out, 0);
396 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -0700397 byte[] data = out.marshall();
398 out.recycle();
399 try {
400 return ParcelFileDescriptor.fromData(data, "battery-stats");
401 } catch (IOException e) {
402 Slog.w(TAG, "Unable to create shared memory", e);
403 return null;
404 }
405 }
406
Dianne Hackborn4870e9d2015-04-08 16:55:47 -0700407 public boolean isCharging() {
408 synchronized (mStats) {
409 return mStats.isCharging();
410 }
411 }
412
Dianne Hackbornab5c0ea2014-04-29 14:53:32 -0700413 public long computeBatteryTimeRemaining() {
414 synchronized (mStats) {
415 long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
416 return time >= 0 ? (time/1000) : time;
417 }
418 }
419
420 public long computeChargeTimeRemaining() {
421 synchronized (mStats) {
422 long time = mStats.computeChargeTimeRemaining(SystemClock.elapsedRealtime());
423 return time >= 0 ? (time/1000) : time;
424 }
425 }
426
Dianne Hackborn099bc622014-01-22 13:39:16 -0800427 public void noteEvent(int code, String name, int uid) {
428 enforceCallingPermission();
429 synchronized (mStats) {
430 mStats.noteEventLocked(code, name, uid);
431 }
432 }
433
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700434 public void noteSyncStart(String name, int uid) {
435 enforceCallingPermission();
436 synchronized (mStats) {
437 mStats.noteSyncStartLocked(name, uid);
Bookatz235343d2018-03-26 13:03:50 -0700438 StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, uid, null, name,
439 StatsLog.SYNC_STATE_CHANGED__STATE__ON);
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700440 }
441 }
442
443 public void noteSyncFinish(String name, int uid) {
444 enforceCallingPermission();
445 synchronized (mStats) {
446 mStats.noteSyncFinishLocked(name, uid);
Bookatz235343d2018-03-26 13:03:50 -0700447 StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, uid, null, name,
448 StatsLog.SYNC_STATE_CHANGED__STATE__OFF);
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700449 }
450 }
451
452 public void noteJobStart(String name, int uid) {
453 enforceCallingPermission();
454 synchronized (mStats) {
455 mStats.noteJobStartLocked(name, uid);
Bookatz235343d2018-03-26 13:03:50 -0700456 StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, uid, null,
457 name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED,
458 JobProtoEnums.STOP_REASON_UNKNOWN);
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700459 }
460 }
461
Dianne Hackborn94326cb2017-06-28 16:17:20 -0700462 public void noteJobFinish(String name, int uid, int stopReason) {
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700463 enforceCallingPermission();
464 synchronized (mStats) {
Dianne Hackborn94326cb2017-06-28 16:17:20 -0700465 mStats.noteJobFinishLocked(name, uid, stopReason);
Bookatz235343d2018-03-26 13:03:50 -0700466 StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, uid, null,
467 name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED,
468 stopReason);
Dianne Hackbornfdb19562014-07-11 16:03:36 -0700469 }
470 }
471
Amith Yamasani977e11f2018-02-16 11:29:54 -0800472 void noteJobsDeferred(int uid, int numDeferred, long sinceLast) {
473 // No need to enforce calling permission, as it is called from an internal interface
474 synchronized (mStats) {
475 mStats.noteJobsDeferredLocked(uid, numDeferred, sinceLast);
476 }
477 }
478
Narayan Kamath695cf722017-12-21 18:32:47 +0000479 public void noteWakupAlarm(String name, int uid, WorkSource workSource, String tag) {
Dianne Hackborn1e383822015-04-10 14:02:33 -0700480 enforceCallingPermission();
481 synchronized (mStats) {
Narayan Kamath695cf722017-12-21 18:32:47 +0000482 mStats.noteWakupAlarmLocked(name, uid, workSource, tag);
Dianne Hackborn1e383822015-04-10 14:02:33 -0700483 }
484 }
485
Narayan Kamath695cf722017-12-21 18:32:47 +0000486 public void noteAlarmStart(String name, WorkSource workSource, int uid) {
Dianne Hackborn1e383822015-04-10 14:02:33 -0700487 enforceCallingPermission();
488 synchronized (mStats) {
Narayan Kamath695cf722017-12-21 18:32:47 +0000489 mStats.noteAlarmStartLocked(name, workSource, uid);
490 }
491 }
492
493 public void noteAlarmFinish(String name, WorkSource workSource, int uid) {
494 enforceCallingPermission();
495 synchronized (mStats) {
496 mStats.noteAlarmFinishLocked(name, workSource, uid);
Dianne Hackborn1e383822015-04-10 14:02:33 -0700497 }
498 }
499
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800500 public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
Dianne Hackborn3d658bf2014-02-05 13:38:56 -0800501 boolean unimportantForLogging) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800502 enforceCallingPermission();
503 synchronized (mStats) {
Narayan Kamath81822022017-12-08 11:56:01 +0000504 mStats.noteStartWakeLocked(uid, pid, null, name, historyName, type,
505 unimportantForLogging, SystemClock.elapsedRealtime(),
506 SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800507 }
508 }
509
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700510 public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800511 enforceCallingPermission();
512 synchronized (mStats) {
Narayan Kamath81822022017-12-08 11:56:01 +0000513 mStats.noteStopWakeLocked(uid, pid, null, name, historyName, type,
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700514 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800515 }
516 }
517
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800518 public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
519 String historyName, int type, boolean unimportantForLogging) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700520 enforceCallingPermission();
521 synchronized (mStats) {
Dianne Hackborna1f1a3c2014-02-24 18:12:28 -0800522 mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
523 type, unimportantForLogging);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700524 }
525 }
526
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700527 public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name,
528 String historyName, int type, WorkSource newWs, int newPid, String newName,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800529 String newHistoryName, int newType, boolean newUnimportantForLogging) {
530 enforceCallingPermission();
531 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700532 mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type,
Dianne Hackborne5167ca2014-03-08 14:39:10 -0800533 newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
534 }
535 }
536
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700537 public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName,
538 int type) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700539 enforceCallingPermission();
540 synchronized (mStats) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -0700541 mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700542 }
543 }
544
Narayan Kamath96a92562018-01-02 18:57:17 +0000545 @Override
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700546 public void noteLongPartialWakelockStart(String name, String historyName, int uid) {
547 enforceCallingPermission();
548 synchronized (mStats) {
549 mStats.noteLongPartialWakelockStart(name, historyName, uid);
550 }
551 }
552
Narayan Kamath96a92562018-01-02 18:57:17 +0000553 @Override
554 public void noteLongPartialWakelockStartFromSource(String name, String historyName,
555 WorkSource workSource) {
556 enforceCallingPermission();
557 synchronized (mStats) {
558 mStats.noteLongPartialWakelockStartFromSource(name, historyName, workSource);
559 }
560 }
561
562 @Override
Dianne Hackbornd0db6f02016-07-18 14:14:20 -0700563 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) {
564 enforceCallingPermission();
565 synchronized (mStats) {
566 mStats.noteLongPartialWakelockFinish(name, historyName, uid);
567 }
568 }
569
Narayan Kamath96a92562018-01-02 18:57:17 +0000570 @Override
571 public void noteLongPartialWakelockFinishFromSource(String name, String historyName,
572 WorkSource workSource) {
573 enforceCallingPermission();
574 synchronized (mStats) {
575 mStats.noteLongPartialWakelockFinishFromSource(name, historyName, workSource);
576 }
577 }
578
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800579 public void noteStartSensor(int uid, int sensor) {
580 enforceCallingPermission();
581 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700582 mStats.noteStartSensorLocked(uid, sensor);
Bookatz235343d2018-03-26 13:03:50 -0700583 StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, uid, null, sensor,
584 StatsLog.SENSOR_STATE_CHANGED__STATE__ON);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800585 }
586 }
Chenjie Yu29fb1f72017-09-13 12:18:50 -0700587
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800588 public void noteStopSensor(int uid, int sensor) {
589 enforceCallingPermission();
590 synchronized (mStats) {
Dianne Hackborn9adb9c32010-08-13 14:09:56 -0700591 mStats.noteStopSensorLocked(uid, sensor);
Bookatz235343d2018-03-26 13:03:50 -0700592 StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, uid, null,
593 sensor, StatsLog.SENSOR_STATE_CHANGED__STATE__OFF);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800594 }
595 }
Chenjie Yu29fb1f72017-09-13 12:18:50 -0700596
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800597 public void noteVibratorOn(int uid, long durationMillis) {
598 enforceCallingPermission();
599 synchronized (mStats) {
600 mStats.noteVibratorOnLocked(uid, durationMillis);
601 }
602 }
603
604 public void noteVibratorOff(int uid) {
605 enforceCallingPermission();
606 synchronized (mStats) {
607 mStats.noteVibratorOffLocked(uid);
608 }
609 }
610
Narayan Kamath32684dd2018-01-08 17:32:51 +0000611 @Override
612 public void noteGpsChanged(WorkSource oldWs, WorkSource newWs) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800613 enforceCallingPermission();
614 synchronized (mStats) {
Narayan Kamath32684dd2018-01-08 17:32:51 +0000615 mStats.noteGpsChangedLocked(oldWs, newWs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800616 }
617 }
Chenjie Yu29fb1f72017-09-13 12:18:50 -0700618
Siddharth Ray78ccaf52017-12-23 16:16:21 -0800619 public void noteGpsSignalQuality(int signalLevel) {
620 synchronized (mStats) {
621 mStats.noteGpsSignalQualityLocked(signalLevel);
622 }
623 }
624
Jeff Browne95c3cd2014-05-02 16:59:26 -0700625 public void noteScreenState(int state) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800626 enforceCallingPermission();
Joe Onorato82ba91d2017-04-27 16:18:05 -0700627 if (DBG) Slog.d(TAG, "begin noteScreenState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800628 synchronized (mStats) {
Yao Chend54f9dd2017-10-17 17:37:48 +0000629 StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, state);
630
631 mStats.noteScreenStateLocked(state);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800632 }
Joe Onorato82ba91d2017-04-27 16:18:05 -0700633 if (DBG) Slog.d(TAG, "end noteScreenState");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800634 }
Chenjie Yu29fb1f72017-09-13 12:18:50 -0700635
Dianne Hackborn617f8772009-03-31 15:04:46 -0700636 public void noteScreenBrightness(int brightness) {
637 enforceCallingPermission();
638 synchronized (mStats) {
Bookatzc1a050a2017-10-10 15:49:28 -0700639 StatsLog.write(StatsLog.SCREEN_BRIGHTNESS_CHANGED, brightness);
Dianne Hackborn617f8772009-03-31 15:04:46 -0700640 mStats.noteScreenBrightnessLocked(brightness);
641 }
642 }
yroe03583e2017-09-20 22:51:26 -0700643
Dianne Hackborn617f8772009-03-31 15:04:46 -0700644 public void noteUserActivity(int uid, int event) {
645 enforceCallingPermission();
646 synchronized (mStats) {
647 mStats.noteUserActivityLocked(uid, event);
648 }
649 }
yroe03583e2017-09-20 22:51:26 -0700650
Dianne Hackborn280a64e2015-07-13 14:48:08 -0700651 public void noteWakeUp(String reason, int reasonUid) {
652 enforceCallingPermission();
653 synchronized (mStats) {
654 mStats.noteWakeUpLocked(reason, reasonUid);
655 }
656 }
657
Jeff Browne95c3cd2014-05-02 16:59:26 -0700658 public void noteInteractive(boolean interactive) {
659 enforceCallingPermission();
660 synchronized (mStats) {
661 mStats.noteInteractiveLocked(interactive);
662 }
663 }
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800664
Dianne Hackborn1e01d162014-12-04 17:46:42 -0800665 public void noteConnectivityChanged(int type, String extra) {
666 enforceCallingPermission();
667 synchronized (mStats) {
668 mStats.noteConnectivityChangedLocked(type, extra);
669 }
670 }
671
Ruchi Kandoifa97fcf2016-05-13 15:10:39 -0700672 public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) {
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800673 enforceCallingPermission();
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700674 final boolean update;
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800675 synchronized (mStats) {
Adam Lesinski14ae39a2017-05-26 11:50:40 -0700676 update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid);
677 }
678
679 if (update) {
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700680 mWorker.scheduleSync("modem-data", BatteryExternalStatsWorker.UPDATE_RADIO);
Dianne Hackborne13c4c02014-02-11 17:18:35 -0800681 }
682 }
683
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800684 public void notePhoneOn() {
685 enforceCallingPermission();
686 synchronized (mStats) {
687 mStats.notePhoneOnLocked();
688 }
689 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700690
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800691 public void notePhoneOff() {
692 enforceCallingPermission();
693 synchronized (mStats) {
694 mStats.notePhoneOffLocked();
695 }
696 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700697
Wink Savillee9b06d72009-05-18 21:47:50 -0700698 public void notePhoneSignalStrength(SignalStrength signalStrength) {
Dianne Hackborn627bba72009-03-24 22:32:56 -0700699 enforceCallingPermission();
700 synchronized (mStats) {
Wink Savillee9b06d72009-05-18 21:47:50 -0700701 mStats.notePhoneSignalStrengthLocked(signalStrength);
Dianne Hackborn627bba72009-03-24 22:32:56 -0700702 }
703 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700704
Dianne Hackborn627bba72009-03-24 22:32:56 -0700705 public void notePhoneDataConnectionState(int dataType, boolean hasData) {
706 enforceCallingPermission();
707 synchronized (mStats) {
708 mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
709 }
710 }
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700711
Amith Yamasanif37447b2009-10-08 18:28:01 -0700712 public void notePhoneState(int state) {
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700713 enforceCallingPermission();
Dianne Hackborne4a59512010-12-07 11:08:07 -0800714 int simState = TelephonyManager.getDefault().getSimState();
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700715 synchronized (mStats) {
Dianne Hackborne4a59512010-12-07 11:08:07 -0800716 mStats.notePhoneStateLocked(state, simState);
Amith Yamasani32dbefd2009-06-19 09:21:17 -0700717 }
718 }
719
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700720 public void noteWifiOn() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700721 enforceCallingPermission();
722 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700723 mStats.noteWifiOnLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700724 }
725 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700726
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700727 public void noteWifiOff() {
The Android Open Source Project10592532009-03-18 17:39:46 -0700728 enforceCallingPermission();
729 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700730 mStats.noteWifiOffLocked();
The Android Open Source Project10592532009-03-18 17:39:46 -0700731 }
732 }
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700733
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700734 public void noteStartAudio(int uid) {
735 enforceCallingPermission();
736 synchronized (mStats) {
737 mStats.noteAudioOnLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700738 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null,
739 StatsLog.AUDIO_STATE_CHANGED__STATE__ON);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700740 }
741 }
742
743 public void noteStopAudio(int uid) {
744 enforceCallingPermission();
745 synchronized (mStats) {
746 mStats.noteAudioOffLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700747 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null,
748 StatsLog.AUDIO_STATE_CHANGED__STATE__OFF);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700749 }
750 }
751
752 public void noteStartVideo(int uid) {
753 enforceCallingPermission();
754 synchronized (mStats) {
755 mStats.noteVideoOnLocked(uid);
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800756 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid, null,
757 StatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__ON);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700758 }
759 }
760
761 public void noteStopVideo(int uid) {
762 enforceCallingPermission();
763 synchronized (mStats) {
764 mStats.noteVideoOffLocked(uid);
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800765 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid,
766 null, StatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__OFF);
Amith Yamasani244fa5c2009-05-22 14:36:07 -0700767 }
768 }
769
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700770 public void noteResetAudio() {
771 enforceCallingPermission();
772 synchronized (mStats) {
773 mStats.noteResetAudioLocked();
Bookatz235343d2018-03-26 13:03:50 -0700774 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, -1, null,
775 StatsLog.AUDIO_STATE_CHANGED__STATE__RESET);
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700776 }
777 }
778
779 public void noteResetVideo() {
780 enforceCallingPermission();
781 synchronized (mStats) {
782 mStats.noteResetVideoLocked();
Chenjie Yu5caaa9d2018-03-06 15:48:54 -0800783 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, -1, null,
784 StatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__RESET);
Dianne Hackborn10eaa852014-07-22 22:54:55 -0700785 }
786 }
787
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700788 public void noteFlashlightOn(int uid) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700789 enforceCallingPermission();
790 synchronized (mStats) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700791 mStats.noteFlashlightOnLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700792 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, uid, null,
793 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON);
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700794 }
795 }
796
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700797 public void noteFlashlightOff(int uid) {
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700798 enforceCallingPermission();
799 synchronized (mStats) {
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700800 mStats.noteFlashlightOffLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700801 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, uid, null,
802 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF);
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700803 }
804 }
805
806 public void noteStartCamera(int uid) {
807 enforceCallingPermission();
Joe Onorato82ba91d2017-04-27 16:18:05 -0700808 if (DBG) Slog.d(TAG, "begin noteStartCamera");
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700809 synchronized (mStats) {
810 mStats.noteCameraOnLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700811 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, uid, null,
812 StatsLog.CAMERA_STATE_CHANGED__STATE__ON);
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700813 }
Joe Onorato82ba91d2017-04-27 16:18:05 -0700814 if (DBG) Slog.d(TAG, "end noteStartCamera");
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700815 }
816
817 public void noteStopCamera(int uid) {
818 enforceCallingPermission();
819 synchronized (mStats) {
820 mStats.noteCameraOffLocked(uid);
Bookatz235343d2018-03-26 13:03:50 -0700821 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, uid, null,
822 StatsLog.CAMERA_STATE_CHANGED__STATE__OFF);
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700823 }
824 }
825
826 public void noteResetCamera() {
827 enforceCallingPermission();
828 synchronized (mStats) {
829 mStats.noteResetCameraLocked();
Bookatz235343d2018-03-26 13:03:50 -0700830 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, -1, null,
831 StatsLog.CAMERA_STATE_CHANGED__STATE__RESET);
Ruben Brunk6d2c3632015-05-26 17:32:16 -0700832 }
833 }
834
835 public void noteResetFlashlight() {
836 enforceCallingPermission();
837 synchronized (mStats) {
838 mStats.noteResetFlashlightLocked();
Bookatz235343d2018-03-26 13:03:50 -0700839 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, -1, null,
840 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__RESET);
Dianne Hackbornabc7c492014-06-30 16:57:46 -0700841 }
842 }
843
Adam Lesinskie08af192015-03-25 16:42:59 -0700844 @Override
Adam Lesinski5f056f62016-07-14 16:56:08 -0700845 public void noteWifiRadioPowerState(int powerState, long tsNanos, int uid) {
Adam Lesinskie08af192015-03-25 16:42:59 -0700846 enforceCallingPermission();
847
848 // There was a change in WiFi power state.
849 // Collect data now for the past activity.
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700850 synchronized (mStats) {
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700851 if (mStats.isOnBattery()) {
Adam Lesinski06f46cb2015-06-23 13:42:53 -0700852 final String type = (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH ||
853 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active"
854 : "inactive";
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700855 mWorker.scheduleSync("wifi-data: " + type, BatteryExternalStatsWorker.UPDATE_WIFI);
Adam Lesinskia7c90c82015-06-18 14:52:24 -0700856 }
Adam Lesinski5f056f62016-07-14 16:56:08 -0700857 mStats.noteWifiRadioPowerState(powerState, tsNanos, uid);
Dianne Hackborn0c820db2015-04-14 17:47:34 -0700858 }
Adam Lesinskie08af192015-03-25 16:42:59 -0700859 }
860
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700861 public void noteWifiRunning(WorkSource ws) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700862 enforceCallingPermission();
863 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700864 mStats.noteWifiRunningLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700865 }
866 }
867
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700868 public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) {
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700869 enforceCallingPermission();
870 synchronized (mStats) {
Dianne Hackborn58e0eef2010-09-16 01:22:10 -0700871 mStats.noteWifiRunningChangedLocked(oldWs, newWs);
872 }
873 }
874
875 public void noteWifiStopped(WorkSource ws) {
876 enforceCallingPermission();
877 synchronized (mStats) {
878 mStats.noteWifiStoppedLocked(ws);
Eric Shienbroodd4c5f892009-03-24 18:13:20 -0700879 }
880 }
881
Dianne Hackbornca1bf212014-02-14 14:18:36 -0800882 public void noteWifiState(int wifiState, String accessPoint) {
883 enforceCallingPermission();
884 synchronized (mStats) {
885 mStats.noteWifiStateLocked(wifiState, accessPoint);
886 }
887 }
888
Dianne Hackborn3251b902014-06-20 14:40:53 -0700889 public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) {
890 enforceCallingPermission();
891 synchronized (mStats) {
892 mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth);
893 }
894 }
895
896 public void noteWifiRssiChanged(int newRssi) {
897 enforceCallingPermission();
898 synchronized (mStats) {
899 mStats.noteWifiRssiChangedLocked(newRssi);
900 }
901 }
902
The Android Open Source Project10592532009-03-18 17:39:46 -0700903 public void noteFullWifiLockAcquired(int uid) {
904 enforceCallingPermission();
905 synchronized (mStats) {
906 mStats.noteFullWifiLockAcquiredLocked(uid);
907 }
908 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -0700909
The Android Open Source Project10592532009-03-18 17:39:46 -0700910 public void noteFullWifiLockReleased(int uid) {
911 enforceCallingPermission();
912 synchronized (mStats) {
913 mStats.noteFullWifiLockReleasedLocked(uid);
914 }
915 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700916
917 public void noteWifiScanStarted(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700918 enforceCallingPermission();
919 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700920 mStats.noteWifiScanStartedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700921 }
922 }
Nick Pelly6ccaa542012-06-15 15:22:47 -0700923
924 public void noteWifiScanStopped(int uid) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700925 enforceCallingPermission();
926 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700927 mStats.noteWifiScanStoppedLocked(uid);
The Android Open Source Project10592532009-03-18 17:39:46 -0700928 }
929 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800930
Robert Greenwalt5347bd42009-05-13 15:10:16 -0700931 public void noteWifiMulticastEnabled(int uid) {
932 enforceCallingPermission();
933 synchronized (mStats) {
934 mStats.noteWifiMulticastEnabledLocked(uid);
935 }
936 }
937
938 public void noteWifiMulticastDisabled(int uid) {
939 enforceCallingPermission();
940 synchronized (mStats) {
941 mStats.noteWifiMulticastDisabledLocked(uid);
942 }
943 }
944
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700945 public void noteFullWifiLockAcquiredFromSource(WorkSource ws) {
946 enforceCallingPermission();
947 synchronized (mStats) {
948 mStats.noteFullWifiLockAcquiredFromSourceLocked(ws);
949 }
950 }
951
952 public void noteFullWifiLockReleasedFromSource(WorkSource ws) {
953 enforceCallingPermission();
954 synchronized (mStats) {
955 mStats.noteFullWifiLockReleasedFromSourceLocked(ws);
956 }
957 }
958
Nick Pelly6ccaa542012-06-15 15:22:47 -0700959 public void noteWifiScanStartedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700960 enforceCallingPermission();
961 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700962 mStats.noteWifiScanStartedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700963 }
964 }
965
Nick Pelly6ccaa542012-06-15 15:22:47 -0700966 public void noteWifiScanStoppedFromSource(WorkSource ws) {
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700967 enforceCallingPermission();
968 synchronized (mStats) {
Nick Pelly6ccaa542012-06-15 15:22:47 -0700969 mStats.noteWifiScanStoppedFromSourceLocked(ws);
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -0700970 }
971 }
972
Robert Greenwalta029ea12013-09-25 16:38:12 -0700973 public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) {
974 enforceCallingPermission();
975 synchronized (mStats) {
976 mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph);
977 }
978 }
979
980 public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) {
981 enforceCallingPermission();
982 synchronized (mStats) {
983 mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws);
984 }
985 }
986
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700987 @Override
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700988 public void noteNetworkInterfaceType(String iface, int networkType) {
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700989 enforceCallingPermission();
990 synchronized (mStats) {
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -0700991 mStats.noteNetworkInterfaceTypeLocked(iface, networkType);
Jeff Sharkey1059c3c2011-10-04 16:54:49 -0700992 }
993 }
994
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -0700995 @Override
996 public void noteNetworkStatsEnabled() {
997 enforceCallingPermission();
Adam Lesinskib3a1bad2017-05-26 11:50:40 -0700998 // During device boot, qtaguid isn't enabled until after the inital
999 // loading of battery stats. Now that they're enabled, take our initial
1000 // snapshot for future delta calculation.
1001 mWorker.scheduleSync("network-stats-enabled",
1002 BatteryExternalStatsWorker.UPDATE_RADIO | BatteryExternalStatsWorker.UPDATE_WIFI);
Jeff Sharkey7a1c3fc2013-06-04 12:29:00 -07001003 }
1004
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07001005 @Override
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001006 public void noteDeviceIdleMode(int mode, String activeReason, int activeUid) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07001007 enforceCallingPermission();
1008 synchronized (mStats) {
Dianne Hackborn08c47a52015-10-15 12:38:14 -07001009 mStats.noteDeviceIdleModeLocked(mode, activeReason, activeUid);
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07001010 }
1011 }
1012
Dianne Hackborn3accca02013-09-20 09:32:11 -07001013 public void notePackageInstalled(String pkgName, long versionCode) {
Dianne Hackborn8ad2af72015-03-17 17:00:24 -07001014 enforceCallingPermission();
1015 synchronized (mStats) {
1016 mStats.notePackageInstalledLocked(pkgName, versionCode);
1017 }
1018 }
1019
1020 public void notePackageUninstalled(String pkgName) {
1021 enforceCallingPermission();
1022 synchronized (mStats) {
1023 mStats.notePackageUninstalledLocked(pkgName);
1024 }
1025 }
1026
Adam Lesinski6771d622016-01-15 18:14:47 -08001027 @Override
Bookatzb1f04f32017-05-19 13:57:32 -07001028 public void noteBleScanStarted(WorkSource ws, boolean isUnoptimized) {
Adam Lesinski6771d622016-01-15 18:14:47 -08001029 enforceCallingPermission();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001030 synchronized (mStats) {
Bookatzb1f04f32017-05-19 13:57:32 -07001031 mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001032 }
Adam Lesinski6771d622016-01-15 18:14:47 -08001033 }
1034
1035 @Override
Bookatz94c5a312017-07-11 16:49:17 -07001036 public void noteBleScanStopped(WorkSource ws, boolean isUnoptimized) {
Adam Lesinski6771d622016-01-15 18:14:47 -08001037 enforceCallingPermission();
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001038 synchronized (mStats) {
Bookatz94c5a312017-07-11 16:49:17 -07001039 mStats.noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized);
Adam Lesinski9f55cc72016-01-27 20:42:14 -08001040 }
1041 }
1042
1043 @Override
1044 public void noteResetBleScan() {
1045 enforceCallingPermission();
1046 synchronized (mStats) {
1047 mStats.noteResetBluetoothScanLocked();
1048 }
Adam Lesinski6771d622016-01-15 18:14:47 -08001049 }
1050
Adam Lesinski010bf372016-04-11 12:18:18 -07001051 @Override
Bookatz4ebc0642017-05-11 12:21:19 -07001052 public void noteBleScanResults(WorkSource ws, int numNewResults) {
Bookatz956f36bf2017-04-28 09:48:17 -07001053 enforceCallingPermission();
1054 synchronized (mStats) {
Bookatz4ebc0642017-05-11 12:21:19 -07001055 mStats.noteBluetoothScanResultsFromSourceLocked(ws, numNewResults);
Bookatz956f36bf2017-04-28 09:48:17 -07001056 }
1057 }
1058
1059 @Override
Adam Lesinski010bf372016-04-11 12:18:18 -07001060 public void noteWifiControllerActivity(WifiActivityEnergyInfo info) {
1061 enforceCallingPermission();
1062
1063 if (info == null || !info.isValid()) {
1064 Slog.e(TAG, "invalid wifi data given: " + info);
1065 return;
1066 }
1067
Adam Lesinski14ae39a2017-05-26 11:50:40 -07001068 mStats.updateWifiState(info);
Adam Lesinski010bf372016-04-11 12:18:18 -07001069 }
1070
1071 @Override
1072 public void noteBluetoothControllerActivity(BluetoothActivityEnergyInfo info) {
1073 enforceCallingPermission();
1074 if (info == null || !info.isValid()) {
1075 Slog.e(TAG, "invalid bluetooth data given: " + info);
1076 return;
1077 }
1078
Adam Lesinskic357e682018-02-28 12:55:39 -08001079 synchronized (mStats) {
1080 mStats.updateBluetoothStateLocked(info);
1081 }
Adam Lesinski010bf372016-04-11 12:18:18 -07001082 }
1083
1084 @Override
1085 public void noteModemControllerActivity(ModemActivityInfo info) {
1086 enforceCallingPermission();
1087
1088 if (info == null || !info.isValid()) {
1089 Slog.e(TAG, "invalid modem data given: " + info);
1090 return;
1091 }
1092
Adam Lesinski14ae39a2017-05-26 11:50:40 -07001093 mStats.updateMobileRadioState(info);
Adam Lesinski010bf372016-04-11 12:18:18 -07001094 }
1095
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001096 public boolean isOnBattery() {
1097 return mStats.isOnBattery();
1098 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001099
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001100 @Override
1101 public void setBatteryState(final int status, final int health, final int plugType,
Adam Lesinski041d9172016-12-12 12:03:56 -08001102 final int level, final int temp, final int volt, final int chargeUAh,
1103 final int chargeFullUAh) {
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001104 enforceCallingPermission();
1105
1106 // BatteryService calls us here and we may update external state. It would be wrong
1107 // to block such a low level service like BatteryService on external stats like WiFi.
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001108 mWorker.scheduleRunnable(() -> {
1109 synchronized (mStats) {
Sudheer Shankac57729a2018-02-09 15:44:42 -08001110 final boolean onBattery = BatteryStatsImpl.isOnBattery(plugType, status);
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001111 if (mStats.isOnBattery() == onBattery) {
1112 // The battery state has not changed, so we don't need to sync external
1113 // stats immediately.
1114 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
1115 chargeUAh, chargeFullUAh);
1116 return;
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001117 }
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001118 }
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001119
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001120 // Sync external stats first as the battery has changed states. If we don't sync
1121 // before changing the state, we may not collect the relevant data later.
1122 // Order here is guaranteed since we're scheduling from the same thread and we are
1123 // using a single threaded executor.
1124 mWorker.scheduleSync("battery-state", BatteryExternalStatsWorker.UPDATE_ALL);
1125 mWorker.scheduleRunnable(() -> {
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001126 synchronized (mStats) {
Adam Lesinski926969b2016-04-28 17:31:12 -07001127 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt,
Adam Lesinski041d9172016-12-12 12:03:56 -08001128 chargeUAh, chargeFullUAh);
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001129 }
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001130 });
Adam Lesinskid7616ef2015-07-27 11:43:05 -07001131 });
Evan Millar633a1742009-04-02 16:36:33 -07001132 }
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001133
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 public long getAwakeTimeBattery() {
1135 mContext.enforceCallingOrSelfPermission(
1136 android.Manifest.permission.BATTERY_STATS, null);
1137 return mStats.getAwakeTimeBattery();
1138 }
1139
1140 public long getAwakeTimePlugged() {
1141 mContext.enforceCallingOrSelfPermission(
1142 android.Manifest.permission.BATTERY_STATS, null);
1143 return mStats.getAwakeTimePlugged();
1144 }
1145
1146 public void enforceCallingPermission() {
1147 if (Binder.getCallingPid() == Process.myPid()) {
1148 return;
1149 }
1150 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
1151 Binder.getCallingPid(), Binder.getCallingUid(), null);
1152 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001153
1154 final class WakeupReasonThread extends Thread {
Adam Lesinski515702c2015-07-23 18:13:38 -07001155 private static final int MAX_REASON_SIZE = 512;
1156 private CharsetDecoder mDecoder;
1157 private ByteBuffer mUtf8Buffer;
1158 private CharBuffer mUtf16Buffer;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001159
1160 WakeupReasonThread() {
1161 super("BatteryStats_wakeupReason");
1162 }
1163
1164 public void run() {
1165 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
1166
Adam Lesinski515702c2015-07-23 18:13:38 -07001167 mDecoder = StandardCharsets.UTF_8
1168 .newDecoder()
1169 .onMalformedInput(CodingErrorAction.REPLACE)
1170 .onUnmappableCharacter(CodingErrorAction.REPLACE)
1171 .replaceWith("?");
1172
1173 mUtf8Buffer = ByteBuffer.allocateDirect(MAX_REASON_SIZE);
1174 mUtf16Buffer = CharBuffer.allocate(MAX_REASON_SIZE);
1175
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001176 try {
Adam Lesinski515702c2015-07-23 18:13:38 -07001177 String reason;
1178 while ((reason = waitWakeup()) != null) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001179 synchronized (mStats) {
Adam Lesinski515702c2015-07-23 18:13:38 -07001180 mStats.noteWakeupReasonLocked(reason);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001181 }
1182 }
1183 } catch (RuntimeException e) {
1184 Slog.e(TAG, "Failure reading wakeup reasons", e);
1185 }
1186 }
Adam Lesinski515702c2015-07-23 18:13:38 -07001187
1188 private String waitWakeup() {
1189 mUtf8Buffer.clear();
1190 mUtf16Buffer.clear();
1191 mDecoder.reset();
1192
1193 int bytesWritten = nativeWaitWakeup(mUtf8Buffer);
1194 if (bytesWritten < 0) {
1195 return null;
1196 } else if (bytesWritten == 0) {
1197 return "unknown";
1198 }
1199
1200 // Set the buffer's limit to the number of bytes written.
1201 mUtf8Buffer.limit(bytesWritten);
1202
1203 // Decode the buffer from UTF-8 to UTF-16.
1204 // Unmappable characters will be replaced.
1205 mDecoder.decode(mUtf8Buffer, mUtf16Buffer, true);
1206 mUtf16Buffer.flip();
1207
1208 // Create a String from the UTF-16 buffer.
1209 return mUtf16Buffer.toString();
1210 }
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001211 }
1212
Adam Lesinski515702c2015-07-23 18:13:38 -07001213 private static native int nativeWaitWakeup(ByteBuffer outBuffer);
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001214
Dianne Hackbornae384452011-06-28 12:33:48 -07001215 private void dumpHelp(PrintWriter pw) {
Dianne Hackborn91268cf2013-06-13 19:06:50 -07001216 pw.println("Battery stats (batterystats) dump options:");
Dianne Hackborn1e725a72015-03-24 18:23:19 -07001217 pw.println(" [--checkin] [--history] [--history-start] [--charged] [-c]");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001218 pw.println(" [--daily] [--reset] [--write] [--new-daily] [--read-daily] [-h] [<package.name>]");
Dianne Hackborn865b79b2015-08-18 17:33:00 -07001219 pw.println(" --checkin: generate output for a checkin report; will write (and clear) the");
1220 pw.println(" last old completed stats when they had been reset.");
Joe Onorato1476d322016-05-05 14:46:15 -07001221 pw.println(" -c: write the current stats in checkin format.");
Dianne Hackborn099bc622014-01-22 13:39:16 -08001222 pw.println(" --history: show only history data.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001223 pw.println(" --history-start <num>: show only history data starting at given time offset.");
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001224 pw.println(" --charged: only output data since last charged.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001225 pw.println(" --daily: only output full daily data.");
Dianne Hackbornae384452011-06-28 12:33:48 -07001226 pw.println(" --reset: reset the stats, clearing all current data.");
1227 pw.println(" --write: force write current collected stats to disk.");
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001228 pw.println(" --new-daily: immediately create and write new daily stats record.");
1229 pw.println(" --read-daily: read-load last written daily stats.");
Sudheer Shanka5c19b892018-01-05 17:25:46 -08001230 pw.println(" --settings: dump the settings key/values related to batterystats");
Mike Ma234d1822018-03-13 18:53:21 -07001231 pw.println(" --cpu: dump cpu stats for debugging purpose");
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001232 pw.println(" <package.name>: optional name of package to filter output by.");
Dianne Hackbornfc064132014-06-02 12:42:12 -07001233 pw.println(" -h: print this help text.");
1234 pw.println("Battery stats (batterystats) commands:");
1235 pw.println(" enable|disable <option>");
1236 pw.println(" Enable or disable a running option. Option state is not saved across boots.");
1237 pw.println(" Options are:");
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001238 pw.println(" full-history: include additional detailed events in battery history:");
Dianne Hackborn1e383822015-04-10 14:02:33 -07001239 pw.println(" wake_lock_in, alarms and proc events");
Dianne Hackbornfc064132014-06-02 12:42:12 -07001240 pw.println(" no-auto-reset: don't automatically reset stats when unplugged");
Amith Yamasani674c9bb2017-02-01 09:45:17 -08001241 pw.println(" pretend-screen-off: pretend the screen is off, even if screen state changes");
Dianne Hackbornae384452011-06-28 12:33:48 -07001242 }
1243
Sudheer Shanka5c19b892018-01-05 17:25:46 -08001244 private void dumpSettings(PrintWriter pw) {
1245 synchronized (mStats) {
1246 mStats.dumpConstantsLocked(pw);
1247 }
1248 }
1249
Mike Ma234d1822018-03-13 18:53:21 -07001250 private void dumpCpuStats(PrintWriter pw) {
1251 synchronized (mStats) {
1252 mStats.dumpCpuStatsLocked(pw);
1253 }
1254 }
1255
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001256 private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
1257 i++;
1258 if (i >= args.length) {
1259 pw.println("Missing option argument for " + (enable ? "--enable" : "--disable"));
1260 dumpHelp(pw);
1261 return -1;
1262 }
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001263 if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001264 synchronized (mStats) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001265 mStats.setRecordAllHistoryLocked(enable);
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001266 }
Dianne Hackborn9a755432014-05-15 17:05:22 -07001267 } else if ("no-auto-reset".equals(args[i])) {
1268 synchronized (mStats) {
1269 mStats.setNoAutoReset(enable);
1270 }
Amith Yamasani674c9bb2017-02-01 09:45:17 -08001271 } else if ("pretend-screen-off".equals(args[i])) {
1272 synchronized (mStats) {
1273 mStats.setPretendScreenOff(enable);
1274 }
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001275 } else {
1276 pw.println("Unknown enable/disable option: " + args[i]);
1277 dumpHelp(pw);
1278 return -1;
1279 }
1280 return i;
1281 }
1282
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 @Override
1285 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
Jeff Sharkey6df866a2017-03-31 14:08:23 -06001286 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return;
Kenny Root3abd75b2011-09-29 11:00:41 -07001287
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001288 int flags = 0;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001289 boolean useCheckinFormat = false;
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001290 boolean toProto = false;
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001291 boolean isRealCheckin = false;
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001292 boolean noOutput = false;
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001293 boolean writeData = false;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001294 long historyStart = -1;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001295 int reqUid = -1;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001296 if (args != null) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001297 for (int i=0; i<args.length; i++) {
1298 String arg = args[i];
Dianne Hackborne4a59512010-12-07 11:08:07 -08001299 if ("--checkin".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001300 useCheckinFormat = true;
1301 isRealCheckin = true;
Dianne Hackborn099bc622014-01-22 13:39:16 -08001302 } else if ("--history".equals(arg)) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001303 flags |= BatteryStats.DUMP_HISTORY_ONLY;
1304 } else if ("--history-start".equals(arg)) {
1305 flags |= BatteryStats.DUMP_HISTORY_ONLY;
1306 i++;
1307 if (i >= args.length) {
1308 pw.println("Missing time argument for --history-since");
1309 dumpHelp(pw);
1310 return;
1311 }
1312 historyStart = Long.parseLong(args[i]);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001313 writeData = true;
Dianne Hackborn49021f52013-09-04 18:03:40 -07001314 } else if ("-c".equals(arg)) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001315 useCheckinFormat = true;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001316 flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001317 } else if ("--proto".equals(arg)) {
1318 toProto = true;
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001319 } else if ("--charged".equals(arg)) {
1320 flags |= BatteryStats.DUMP_CHARGED_ONLY;
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001321 } else if ("--daily".equals(arg)) {
1322 flags |= BatteryStats.DUMP_DAILY_ONLY;
Dianne Hackborne4a59512010-12-07 11:08:07 -08001323 } else if ("--reset".equals(arg)) {
1324 synchronized (mStats) {
Dianne Hackborn3d658bf2014-02-05 13:38:56 -08001325 mStats.resetAllStatsCmdLocked();
Dianne Hackborne4a59512010-12-07 11:08:07 -08001326 pw.println("Battery stats reset.");
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001327 noOutput = true;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001328 }
Adam Lesinskib3a1bad2017-05-26 11:50:40 -07001329 mWorker.scheduleSync("dump", BatteryExternalStatsWorker.UPDATE_ALL);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001330 } else if ("--write".equals(arg)) {
Sudheer Shankab2f83c12017-11-13 19:25:01 -08001331 syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001332 synchronized (mStats) {
1333 mStats.writeSyncLocked();
1334 pw.println("Battery stats written.");
1335 noOutput = true;
1336 }
Dianne Hackbornd4a8af72015-03-03 10:06:15 -08001337 } else if ("--new-daily".equals(arg)) {
1338 synchronized (mStats) {
1339 mStats.recordDailyStatsLocked();
1340 pw.println("New daily stats written.");
1341 noOutput = true;
1342 }
1343 } else if ("--read-daily".equals(arg)) {
1344 synchronized (mStats) {
1345 mStats.readDailyStatsLocked();
1346 pw.println("Last daily stats read.");
1347 noOutput = true;
1348 }
Dianne Hackbornfc064132014-06-02 12:42:12 -07001349 } else if ("--enable".equals(arg) || "enable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001350 i = doEnableOrDisable(pw, i, args, true);
1351 if (i < 0) {
1352 return;
1353 }
1354 pw.println("Enabled: " + args[i]);
1355 return;
Dianne Hackbornfc064132014-06-02 12:42:12 -07001356 } else if ("--disable".equals(arg) || "disable".equals(arg)) {
Dianne Hackborncbefd8d2014-05-14 11:42:00 -07001357 i = doEnableOrDisable(pw, i, args, false);
1358 if (i < 0) {
1359 return;
1360 }
1361 pw.println("Disabled: " + args[i]);
1362 return;
Dianne Hackbornae384452011-06-28 12:33:48 -07001363 } else if ("-h".equals(arg)) {
1364 dumpHelp(pw);
1365 return;
Sudheer Shanka5c19b892018-01-05 17:25:46 -08001366 } else if ("--settings".equals(arg)) {
1367 dumpSettings(pw);
1368 return;
Mike Ma234d1822018-03-13 18:53:21 -07001369 } else if ("--cpu".equals(arg)) {
1370 dumpCpuStats(pw);
1371 return;
Mike Lockwoode8174042011-08-16 12:53:43 -07001372 } else if ("-a".equals(arg)) {
Dianne Hackborna1bd7922014-03-21 11:07:11 -07001373 flags |= BatteryStats.DUMP_VERBOSE;
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001374 } else if (arg.length() > 0 && arg.charAt(0) == '-'){
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001375 pw.println("Unknown option: " + arg);
Dianne Hackbornae384452011-06-28 12:33:48 -07001376 dumpHelp(pw);
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001377 return;
1378 } else {
1379 // Not an option, last argument must be a package name.
1380 try {
Jeff Sharkeye06b4d12016-01-06 14:51:50 -07001381 reqUid = mContext.getPackageManager().getPackageUidAsUser(arg,
Dianne Hackborncbfd23e2013-06-11 14:26:53 -07001382 UserHandle.getCallingUserId());
1383 } catch (PackageManager.NameNotFoundException e) {
1384 pw.println("Unknown package: " + arg);
1385 dumpHelp(pw);
1386 return;
1387 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 }
1389 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001390 }
Dianne Hackborn0ffc9882011-04-13 18:15:56 -07001391 if (noOutput) {
1392 return;
1393 }
Dianne Hackborn13a6a9b2015-04-22 18:03:59 -07001394
1395 long ident = Binder.clearCallingIdentity();
1396 try {
1397 if (BatteryStatsHelper.checkWifiOnly(mContext)) {
1398 flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY;
1399 }
1400 // Fetch data from external sources and update the BatteryStatsImpl object with them.
Sudheer Shankab2f83c12017-11-13 19:25:01 -08001401 syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL);
Dianne Hackborn13a6a9b2015-04-22 18:03:59 -07001402 } finally {
1403 Binder.restoreCallingIdentity(ident);
Dianne Hackbornd953c532014-08-16 18:17:38 -07001404 }
Dianne Hackborn13a6a9b2015-04-22 18:03:59 -07001405
Dianne Hackbornab4a81b2014-10-09 17:59:38 -07001406 if (reqUid >= 0) {
1407 // By default, if the caller is only interested in a specific package, then
1408 // we only dump the aggregated data since charged.
Dianne Hackborn1e725a72015-03-24 18:23:19 -07001409 if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_CHARGED_ONLY)) == 0) {
Dianne Hackbornab4a81b2014-10-09 17:59:38 -07001410 flags |= BatteryStats.DUMP_CHARGED_ONLY;
1411 // Also if they are doing -c, we don't want history.
1412 flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY;
1413 }
1414 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001415
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001416 if (toProto) {
1417 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
1418 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL);
1419 if (isRealCheckin) {
1420 // For a real checkin, first we want to prefer to use the last complete checkin
1421 // file if there is one.
1422 synchronized (mStats.mCheckinFile) {
1423 if (mStats.mCheckinFile.exists()) {
1424 try {
1425 byte[] raw = mStats.mCheckinFile.readFully();
1426 if (raw != null) {
1427 Parcel in = Parcel.obtain();
1428 in.unmarshall(raw, 0, raw.length);
1429 in.setDataPosition(0);
1430 BatteryStatsImpl checkinStats = new BatteryStatsImpl(
1431 null, mStats.mHandler, null, mUserManagerUserInfoProvider);
1432 checkinStats.readSummaryFromParcel(in);
1433 in.recycle();
Kweku Adams6ccebf22017-12-11 12:30:35 -08001434 checkinStats.dumpProtoLocked(mContext, fd, apps, flags);
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001435 mStats.mCheckinFile.delete();
1436 return;
1437 }
1438 } catch (IOException | ParcelFormatException e) {
1439 Slog.w(TAG, "Failure reading checkin file "
1440 + mStats.mCheckinFile.getBaseFile(), e);
1441 }
1442 }
1443 }
1444 }
1445 if (DBG) Slog.d(TAG, "begin dumpProtoLocked from UID " + Binder.getCallingUid());
1446 synchronized (mStats) {
Kweku Adams6ccebf22017-12-11 12:30:35 -08001447 mStats.dumpProtoLocked(mContext, fd, apps, flags);
Kweku Adams2f73ecd2017-09-27 16:59:19 -07001448 if (writeData) {
1449 mStats.writeAsyncLocked();
1450 }
1451 }
1452 if (DBG) Slog.d(TAG, "end dumpProtoLocked");
1453 } else if (useCheckinFormat) {
Dianne Hackborn9cfba352016-03-24 17:31:28 -07001454 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(
Amith Yamasani0d1fd8d2016-10-12 14:21:51 -07001455 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001456 if (isRealCheckin) {
1457 // For a real checkin, first we want to prefer to use the last complete checkin
1458 // file if there is one.
1459 synchronized (mStats.mCheckinFile) {
1460 if (mStats.mCheckinFile.exists()) {
1461 try {
1462 byte[] raw = mStats.mCheckinFile.readFully();
1463 if (raw != null) {
1464 Parcel in = Parcel.obtain();
1465 in.unmarshall(raw, 0, raw.length);
1466 in.setDataPosition(0);
1467 BatteryStatsImpl checkinStats = new BatteryStatsImpl(
Suprabh Shuklae6e723d2017-06-14 16:14:43 -07001468 null, mStats.mHandler, null, mUserManagerUserInfoProvider);
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001469 checkinStats.readSummaryFromParcel(in);
1470 in.recycle();
1471 checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,
1472 historyStart);
1473 mStats.mCheckinFile.delete();
1474 return;
1475 }
Adam Lesinski9ae9cba2015-07-08 17:09:34 -07001476 } catch (IOException | ParcelFormatException e) {
Dianne Hackborn0068d3dc2014-08-06 19:20:25 -07001477 Slog.w(TAG, "Failure reading checkin file "
1478 + mStats.mCheckinFile.getBaseFile(), e);
1479 }
1480 }
1481 }
1482 }
Joe Onorato82ba91d2017-04-27 16:18:05 -07001483 if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid());
Dianne Hackborne4a59512010-12-07 11:08:07 -08001484 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001485 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001486 if (writeData) {
1487 mStats.writeAsyncLocked();
1488 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001489 }
Joe Onorato82ba91d2017-04-27 16:18:05 -07001490 if (DBG) Slog.d(TAG, "end dumpCheckinLocked");
Dianne Hackborne4a59512010-12-07 11:08:07 -08001491 } else {
Joe Onorato82ba91d2017-04-27 16:18:05 -07001492 if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid());
Dianne Hackborne4a59512010-12-07 11:08:07 -08001493 synchronized (mStats) {
Dianne Hackbornc51cf032014-03-02 19:08:15 -08001494 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
Dianne Hackborn16b0b562014-06-03 17:24:42 -07001495 if (writeData) {
1496 mStats.writeAsyncLocked();
1497 }
Dianne Hackborne4a59512010-12-07 11:08:07 -08001498 }
Joe Onorato82ba91d2017-04-27 16:18:05 -07001499 if (DBG) Slog.d(TAG, "end dumpLocked");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001500 }
1501 }
Adam Lesinski4b6bd8d2015-03-19 14:35:45 -07001502
Joe Onorato713fec82016-03-04 10:34:02 -08001503 /**
Siddharth Raya1fd0572017-11-13 14:20:47 -08001504 * Gets a snapshot of cellular stats
1505 * @hide
1506 */
1507 public CellularBatteryStats getCellularBatteryStats() {
1508 synchronized (mStats) {
1509 return mStats.getCellularBatteryStats();
1510 }
1511 }
1512
1513 /**
Siddharth Rayb50a6842017-12-14 15:15:28 -08001514 * Gets a snapshot of Wifi stats
1515 * @hide
1516 */
1517 public WifiBatteryStats getWifiBatteryStats() {
1518 synchronized (mStats) {
1519 return mStats.getWifiBatteryStats();
1520 }
1521 }
1522
1523 /**
Siddharth Ray78ccaf52017-12-23 16:16:21 -08001524 * Gets a snapshot of Gps stats
1525 * @hide
1526 */
1527 public GpsBatteryStats getGpsBatteryStats() {
1528 synchronized (mStats) {
1529 return mStats.getGpsBatteryStats();
1530 }
1531 }
1532
1533 /**
Joe Onorato713fec82016-03-04 10:34:02 -08001534 * Gets a snapshot of the system health for a particular uid.
1535 */
1536 @Override
1537 public HealthStatsParceler takeUidSnapshot(int requestUid) {
1538 if (requestUid != Binder.getCallingUid()) {
1539 mContext.enforceCallingOrSelfPermission(
1540 android.Manifest.permission.BATTERY_STATS, null);
1541 }
1542 long ident = Binder.clearCallingIdentity();
1543 try {
Sudheer Shankab2f83c12017-11-13 19:25:01 -08001544 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
Joe Onorato713fec82016-03-04 10:34:02 -08001545 synchronized (mStats) {
1546 return getHealthStatsForUidLocked(requestUid);
1547 }
1548 } catch (Exception ex) {
Joe Onorato82ba91d2017-04-27 16:18:05 -07001549 Slog.w(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex);
Joe Onorato713fec82016-03-04 10:34:02 -08001550 throw ex;
1551 } finally {
1552 Binder.restoreCallingIdentity(ident);
1553 }
1554 }
1555
1556 /**
1557 * Gets a snapshot of the system health for a number of uids.
1558 */
1559 @Override
1560 public HealthStatsParceler[] takeUidSnapshots(int[] requestUids) {
1561 if (!onlyCaller(requestUids)) {
1562 mContext.enforceCallingOrSelfPermission(
1563 android.Manifest.permission.BATTERY_STATS, null);
1564 }
1565 long ident = Binder.clearCallingIdentity();
1566 int i=-1;
1567 try {
Sudheer Shankab2f83c12017-11-13 19:25:01 -08001568 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL);
Joe Onorato713fec82016-03-04 10:34:02 -08001569 synchronized (mStats) {
1570 final int N = requestUids.length;
1571 final HealthStatsParceler[] results = new HealthStatsParceler[N];
1572 for (i=0; i<N; i++) {
1573 results[i] = getHealthStatsForUidLocked(requestUids[i]);
1574 }
1575 return results;
1576 }
1577 } catch (Exception ex) {
Joe Onorato82ba91d2017-04-27 16:18:05 -07001578 if (DBG) Slog.d(TAG, "Crashed while writing for takeUidSnapshots("
Joe Onorato713fec82016-03-04 10:34:02 -08001579 + Arrays.toString(requestUids) + ") i=" + i, ex);
1580 throw ex;
1581 } finally {
1582 Binder.restoreCallingIdentity(ident);
1583 }
1584 }
1585
1586 /**
1587 * Returns whether the Binder.getCallingUid is the only thing in requestUids.
1588 */
1589 private static boolean onlyCaller(int[] requestUids) {
1590 final int caller = Binder.getCallingUid();
1591 final int N = requestUids.length;
1592 for (int i=0; i<N; i++) {
1593 if (requestUids[i] != caller) {
1594 return false;
1595 }
1596 }
1597 return true;
1598 }
1599
1600 /**
1601 * Gets a HealthStatsParceler for the given uid. You should probably call
Adam Lesinski010bf372016-04-11 12:18:18 -07001602 * updateExternalStatsSync first.
Joe Onorato713fec82016-03-04 10:34:02 -08001603 */
1604 HealthStatsParceler getHealthStatsForUidLocked(int requestUid) {
1605 final HealthStatsBatteryStatsWriter writer = new HealthStatsBatteryStatsWriter();
1606 final HealthStatsWriter uidWriter = new HealthStatsWriter(UidHealthStats.CONSTANTS);
1607 final BatteryStats.Uid uid = mStats.getUidStats().get(requestUid);
1608 if (uid != null) {
1609 writer.writeUid(uidWriter, mStats, uid);
1610 }
1611 return new HealthStatsParceler(uidWriter);
1612 }
1613
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614}