1 /* 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 17 package com.android.server.am; 18 19 import android.app.ActivityManager; 20 import android.app.job.JobProtoEnums; 21 import android.bluetooth.BluetoothActivityEnergyInfo; 22 import android.content.ContentResolver; 23 import android.content.Context; 24 import android.content.pm.ApplicationInfo; 25 import android.content.pm.PackageManager; 26 import android.net.wifi.WifiActivityEnergyInfo; 27 import android.os.BatteryStats; 28 import android.os.BatteryStatsInternal; 29 import android.os.Binder; 30 import android.os.Handler; 31 import android.os.IBinder; 32 import android.os.Parcel; 33 import android.os.ParcelFileDescriptor; 34 import android.os.ParcelFormatException; 35 import android.os.PowerManager.ServiceType; 36 import android.os.PowerManagerInternal; 37 import android.os.PowerSaveState; 38 import android.os.Process; 39 import android.os.ServiceManager; 40 import android.os.SystemClock; 41 import android.os.UserHandle; 42 import android.os.UserManagerInternal; 43 import android.os.WorkSource; 44 import android.os.connectivity.CellularBatteryStats; 45 import android.os.connectivity.GpsBatteryStats; 46 import android.os.connectivity.WifiBatteryStats; 47 import android.os.health.HealthStatsParceler; 48 import android.os.health.HealthStatsWriter; 49 import android.os.health.UidHealthStats; 50 import android.provider.Settings; 51 import android.telephony.DataConnectionRealTimeInfo; 52 import android.telephony.ModemActivityInfo; 53 import android.telephony.SignalStrength; 54 import android.telephony.TelephonyManager; 55 import android.util.Slog; 56 import android.util.StatsLog; 57 58 import com.android.internal.app.IBatteryStats; 59 import com.android.internal.os.BatteryStatsHelper; 60 import com.android.internal.os.BatteryStatsImpl; 61 import com.android.internal.os.PowerProfile; 62 import com.android.internal.os.RailStats; 63 import com.android.internal.os.RpmStats; 64 import com.android.internal.util.DumpUtils; 65 import com.android.internal.util.ParseUtils; 66 import com.android.server.LocalServices; 67 68 import java.io.File; 69 import java.io.FileDescriptor; 70 import java.io.IOException; 71 import java.io.PrintWriter; 72 import java.nio.ByteBuffer; 73 import java.nio.CharBuffer; 74 import java.nio.charset.CharsetDecoder; 75 import java.nio.charset.CodingErrorAction; 76 import java.nio.charset.StandardCharsets; 77 import java.util.Arrays; 78 import java.util.List; 79 import java.util.concurrent.ExecutionException; 80 import java.util.concurrent.Future; 81 82 /** 83 * All information we are collecting about things that can happen that impact 84 * battery life. 85 */ 86 public final class BatteryStatsService extends IBatteryStats.Stub 87 implements PowerManagerInternal.LowPowerModeListener, 88 BatteryStatsImpl.PlatformIdleStateCallback, 89 BatteryStatsImpl.RailEnergyDataCallback { 90 static final String TAG = "BatteryStatsService"; 91 static final boolean DBG = false; 92 93 private static IBatteryStats sService; 94 95 final BatteryStatsImpl mStats; 96 private final BatteryStatsImpl.UserInfoProvider mUserManagerUserInfoProvider; 97 private final Context mContext; 98 private final BatteryExternalStatsWorker mWorker; 99 getLowPowerStats(RpmStats rpmStats)100 private native void getLowPowerStats(RpmStats rpmStats); getPlatformLowPowerStats(ByteBuffer outBuffer)101 private native int getPlatformLowPowerStats(ByteBuffer outBuffer); getSubsystemLowPowerStats(ByteBuffer outBuffer)102 private native int getSubsystemLowPowerStats(ByteBuffer outBuffer); getRailEnergyPowerStats(RailStats railStats)103 private native void getRailEnergyPowerStats(RailStats railStats); 104 private CharsetDecoder mDecoderStat = StandardCharsets.UTF_8 105 .newDecoder() 106 .onMalformedInput(CodingErrorAction.REPLACE) 107 .onUnmappableCharacter(CodingErrorAction.REPLACE) 108 .replaceWith("?"); 109 private ByteBuffer mUtf8BufferStat = ByteBuffer.allocateDirect(MAX_LOW_POWER_STATS_SIZE); 110 private CharBuffer mUtf16BufferStat = CharBuffer.allocate(MAX_LOW_POWER_STATS_SIZE); 111 private static final int MAX_LOW_POWER_STATS_SIZE = 2048; 112 113 /** 114 * Replaces the information in the given rpmStats with up-to-date information. 115 */ 116 @Override fillLowPowerStats(RpmStats rpmStats)117 public void fillLowPowerStats(RpmStats rpmStats) { 118 if (DBG) Slog.d(TAG, "begin getLowPowerStats"); 119 try { 120 getLowPowerStats(rpmStats); 121 } finally { 122 if (DBG) Slog.d(TAG, "end getLowPowerStats"); 123 } 124 } 125 126 @Override fillRailDataStats(RailStats railStats)127 public void fillRailDataStats(RailStats railStats) { 128 if (DBG) Slog.d(TAG, "begin getRailEnergyPowerStats"); 129 try { 130 getRailEnergyPowerStats(railStats); 131 } finally { 132 if (DBG) Slog.d(TAG, "end getRailEnergyPowerStats"); 133 } 134 } 135 136 @Override getPlatformLowPowerStats()137 public String getPlatformLowPowerStats() { 138 if (DBG) Slog.d(TAG, "begin getPlatformLowPowerStats"); 139 try { 140 mUtf8BufferStat.clear(); 141 mUtf16BufferStat.clear(); 142 mDecoderStat.reset(); 143 int bytesWritten = getPlatformLowPowerStats(mUtf8BufferStat); 144 if (bytesWritten < 0) { 145 return null; 146 } else if (bytesWritten == 0) { 147 return "Empty"; 148 } 149 mUtf8BufferStat.limit(bytesWritten); 150 mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true); 151 mUtf16BufferStat.flip(); 152 return mUtf16BufferStat.toString(); 153 } finally { 154 if (DBG) Slog.d(TAG, "end getPlatformLowPowerStats"); 155 } 156 } 157 158 @Override getSubsystemLowPowerStats()159 public String getSubsystemLowPowerStats() { 160 if (DBG) Slog.d(TAG, "begin getSubsystemLowPowerStats"); 161 try { 162 mUtf8BufferStat.clear(); 163 mUtf16BufferStat.clear(); 164 mDecoderStat.reset(); 165 int bytesWritten = getSubsystemLowPowerStats(mUtf8BufferStat); 166 if (bytesWritten < 0) { 167 return null; 168 } else if (bytesWritten == 0) { 169 return "Empty"; 170 } 171 mUtf8BufferStat.limit(bytesWritten); 172 mDecoderStat.decode(mUtf8BufferStat, mUtf16BufferStat, true); 173 mUtf16BufferStat.flip(); 174 return mUtf16BufferStat.toString(); 175 } finally { 176 if (DBG) Slog.d(TAG, "end getSubsystemLowPowerStats"); 177 } 178 } 179 BatteryStatsService(Context context, File systemDir, Handler handler)180 BatteryStatsService(Context context, File systemDir, Handler handler) { 181 // BatteryStatsImpl expects the ActivityManagerService handler, so pass that one through. 182 mContext = context; 183 mUserManagerUserInfoProvider = new BatteryStatsImpl.UserInfoProvider() { 184 private UserManagerInternal umi; 185 @Override 186 public int[] getUserIds() { 187 if (umi == null) { 188 umi = LocalServices.getService(UserManagerInternal.class); 189 } 190 return (umi != null) ? umi.getUserIds() : null; 191 } 192 }; 193 mStats = new BatteryStatsImpl(systemDir, handler, this, 194 this, mUserManagerUserInfoProvider); 195 mWorker = new BatteryExternalStatsWorker(context, mStats); 196 mStats.setExternalStatsSyncLocked(mWorker); 197 mStats.setRadioScanningTimeoutLocked(mContext.getResources().getInteger( 198 com.android.internal.R.integer.config_radioScanningTimeout) * 1000L); 199 mStats.setPowerProfileLocked(new PowerProfile(context)); 200 } 201 publish()202 public void publish() { 203 LocalServices.addService(BatteryStatsInternal.class, new LocalService()); 204 ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder()); 205 } 206 systemServicesReady()207 public void systemServicesReady() { 208 mStats.systemServicesReady(mContext); 209 } 210 211 private final class LocalService extends BatteryStatsInternal { 212 @Override getWifiIfaces()213 public String[] getWifiIfaces() { 214 return mStats.getWifiIfaces().clone(); 215 } 216 217 @Override getMobileIfaces()218 public String[] getMobileIfaces() { 219 return mStats.getMobileIfaces().clone(); 220 } 221 222 @Override noteJobsDeferred(int uid, int numDeferred, long sinceLast)223 public void noteJobsDeferred(int uid, int numDeferred, long sinceLast) { 224 if (DBG) Slog.d(TAG, "Jobs deferred " + uid + ": " + numDeferred + " " + sinceLast); 225 BatteryStatsService.this.noteJobsDeferred(uid, numDeferred, sinceLast); 226 } 227 } 228 awaitUninterruptibly(Future<?> future)229 private static void awaitUninterruptibly(Future<?> future) { 230 while (true) { 231 try { 232 future.get(); 233 return; 234 } catch (ExecutionException e) { 235 return; 236 } catch (InterruptedException e) { 237 // Keep looping 238 } 239 } 240 } 241 syncStats(String reason, int flags)242 private void syncStats(String reason, int flags) { 243 awaitUninterruptibly(mWorker.scheduleSync(reason, flags)); 244 } 245 246 /** 247 * At the time when the constructor runs, the power manager has not yet been 248 * initialized. So we initialize the low power observer later. 249 */ initPowerManagement()250 public void initPowerManagement() { 251 final PowerManagerInternal powerMgr = LocalServices.getService(PowerManagerInternal.class); 252 powerMgr.registerLowPowerModeObserver(this); 253 synchronized (mStats) { 254 mStats.notePowerSaveModeLocked( 255 powerMgr.getLowPowerState(ServiceType.BATTERY_STATS) 256 .batterySaverEnabled); 257 } 258 (new WakeupReasonThread()).start(); 259 } 260 shutdown()261 public void shutdown() { 262 Slog.w("BatteryStats", "Writing battery stats before shutdown..."); 263 264 syncStats("shutdown", BatteryExternalStatsWorker.UPDATE_ALL); 265 266 synchronized (mStats) { 267 mStats.shutdownLocked(); 268 } 269 270 // Shutdown the thread we made. 271 mWorker.shutdown(); 272 } 273 getService()274 public static IBatteryStats getService() { 275 if (sService != null) { 276 return sService; 277 } 278 IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME); 279 sService = asInterface(b); 280 return sService; 281 } 282 283 @Override getServiceType()284 public int getServiceType() { 285 return ServiceType.BATTERY_STATS; 286 } 287 288 @Override onLowPowerModeChanged(PowerSaveState result)289 public void onLowPowerModeChanged(PowerSaveState result) { 290 synchronized (mStats) { 291 mStats.notePowerSaveModeLocked(result.batterySaverEnabled); 292 } 293 } 294 295 /** 296 * @return the current statistics object, which may be modified 297 * to reflect events that affect battery usage. You must lock the 298 * stats object before doing anything with it. 299 */ getActiveStatistics()300 public BatteryStatsImpl getActiveStatistics() { 301 return mStats; 302 } 303 304 /** 305 * Schedules a write to disk to occur. This will cause the BatteryStatsImpl 306 * object to update with the latest info, then write to disk. 307 */ scheduleWriteToDisk()308 public void scheduleWriteToDisk() { 309 mWorker.scheduleWrite(); 310 } 311 312 // These are for direct use by the activity manager... 313 314 /** 315 * Remove a UID from the BatteryStats and BatteryStats' external dependencies. 316 */ removeUid(int uid)317 void removeUid(int uid) { 318 synchronized (mStats) { 319 mStats.removeUidStatsLocked(uid); 320 } 321 } 322 onCleanupUser(int userId)323 void onCleanupUser(int userId) { 324 synchronized (mStats) { 325 mStats.onCleanupUserLocked(userId); 326 } 327 } 328 onUserRemoved(int userId)329 void onUserRemoved(int userId) { 330 synchronized (mStats) { 331 mStats.onUserRemovedLocked(userId); 332 } 333 } 334 addIsolatedUid(int isolatedUid, int appUid)335 void addIsolatedUid(int isolatedUid, int appUid) { 336 synchronized (mStats) { 337 mStats.addIsolatedUidLocked(isolatedUid, appUid); 338 } 339 } 340 removeIsolatedUid(int isolatedUid, int appUid)341 void removeIsolatedUid(int isolatedUid, int appUid) { 342 synchronized (mStats) { 343 mStats.scheduleRemoveIsolatedUidLocked(isolatedUid, appUid); 344 } 345 } 346 noteProcessStart(String name, int uid)347 void noteProcessStart(String name, int uid) { 348 synchronized (mStats) { 349 mStats.noteProcessStartLocked(name, uid); 350 StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, 351 StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__STARTED); 352 } 353 } 354 noteProcessCrash(String name, int uid)355 void noteProcessCrash(String name, int uid) { 356 synchronized (mStats) { 357 mStats.noteProcessCrashLocked(name, uid); 358 StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, 359 StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__CRASHED); 360 } 361 } 362 noteProcessAnr(String name, int uid)363 void noteProcessAnr(String name, int uid) { 364 synchronized (mStats) { 365 mStats.noteProcessAnrLocked(name, uid); 366 } 367 } 368 noteProcessFinish(String name, int uid)369 void noteProcessFinish(String name, int uid) { 370 synchronized (mStats) { 371 mStats.noteProcessFinishLocked(name, uid); 372 StatsLog.write(StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED, uid, name, 373 StatsLog.PROCESS_LIFE_CYCLE_STATE_CHANGED__STATE__FINISHED); 374 } 375 } 376 377 /** @param state Process state from ActivityManager.java. */ noteUidProcessState(int uid, int state)378 void noteUidProcessState(int uid, int state) { 379 synchronized (mStats) { 380 StatsLog.write(StatsLog.UID_PROCESS_STATE_CHANGED, uid, 381 ActivityManager.processStateAmToProto(state)); 382 383 mStats.noteUidProcessStateLocked(uid, state); 384 } 385 } 386 387 // Public interface... 388 getStatistics()389 public byte[] getStatistics() { 390 mContext.enforceCallingPermission( 391 android.Manifest.permission.BATTERY_STATS, null); 392 //Slog.i("foo", "SENDING BATTERY INFO:"); 393 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM)); 394 Parcel out = Parcel.obtain(); 395 syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL); 396 synchronized (mStats) { 397 mStats.writeToParcel(out, 0); 398 } 399 byte[] data = out.marshall(); 400 out.recycle(); 401 return data; 402 } 403 getStatisticsStream()404 public ParcelFileDescriptor getStatisticsStream() { 405 mContext.enforceCallingPermission( 406 android.Manifest.permission.BATTERY_STATS, null); 407 //Slog.i("foo", "SENDING BATTERY INFO:"); 408 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM)); 409 Parcel out = Parcel.obtain(); 410 syncStats("get-stats", BatteryExternalStatsWorker.UPDATE_ALL); 411 synchronized (mStats) { 412 mStats.writeToParcel(out, 0); 413 } 414 byte[] data = out.marshall(); 415 if (DBG) Slog.d(TAG, "getStatisticsStream parcel size is:" + data.length); 416 out.recycle(); 417 try { 418 return ParcelFileDescriptor.fromData(data, "battery-stats"); 419 } catch (IOException e) { 420 Slog.w(TAG, "Unable to create shared memory", e); 421 return null; 422 } 423 } 424 isCharging()425 public boolean isCharging() { 426 synchronized (mStats) { 427 return mStats.isCharging(); 428 } 429 } 430 computeBatteryTimeRemaining()431 public long computeBatteryTimeRemaining() { 432 synchronized (mStats) { 433 long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime()); 434 return time >= 0 ? (time/1000) : time; 435 } 436 } 437 computeChargeTimeRemaining()438 public long computeChargeTimeRemaining() { 439 synchronized (mStats) { 440 long time = mStats.computeChargeTimeRemaining(SystemClock.elapsedRealtime()); 441 return time >= 0 ? (time/1000) : time; 442 } 443 } 444 noteEvent(int code, String name, int uid)445 public void noteEvent(int code, String name, int uid) { 446 enforceCallingPermission(); 447 synchronized (mStats) { 448 mStats.noteEventLocked(code, name, uid); 449 } 450 } 451 noteSyncStart(String name, int uid)452 public void noteSyncStart(String name, int uid) { 453 enforceCallingPermission(); 454 synchronized (mStats) { 455 mStats.noteSyncStartLocked(name, uid); 456 StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, uid, null, name, 457 StatsLog.SYNC_STATE_CHANGED__STATE__ON); 458 } 459 } 460 noteSyncFinish(String name, int uid)461 public void noteSyncFinish(String name, int uid) { 462 enforceCallingPermission(); 463 synchronized (mStats) { 464 mStats.noteSyncFinishLocked(name, uid); 465 StatsLog.write_non_chained(StatsLog.SYNC_STATE_CHANGED, uid, null, name, 466 StatsLog.SYNC_STATE_CHANGED__STATE__OFF); 467 } 468 } 469 470 /** A scheduled job was started. */ noteJobStart(String name, int uid, int standbyBucket, int jobid)471 public void noteJobStart(String name, int uid, int standbyBucket, int jobid) { 472 enforceCallingPermission(); 473 synchronized (mStats) { 474 mStats.noteJobStartLocked(name, uid); 475 StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, uid, null, 476 name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__STARTED, 477 JobProtoEnums.STOP_REASON_UNKNOWN, standbyBucket, jobid); 478 } 479 } 480 481 /** A scheduled job was finished. */ noteJobFinish(String name, int uid, int stopReason, int standbyBucket, int jobid)482 public void noteJobFinish(String name, int uid, int stopReason, int standbyBucket, int jobid) { 483 enforceCallingPermission(); 484 synchronized (mStats) { 485 mStats.noteJobFinishLocked(name, uid, stopReason); 486 StatsLog.write_non_chained(StatsLog.SCHEDULED_JOB_STATE_CHANGED, uid, null, 487 name, StatsLog.SCHEDULED_JOB_STATE_CHANGED__STATE__FINISHED, 488 stopReason, standbyBucket, jobid); 489 } 490 } 491 noteJobsDeferred(int uid, int numDeferred, long sinceLast)492 void noteJobsDeferred(int uid, int numDeferred, long sinceLast) { 493 // No need to enforce calling permission, as it is called from an internal interface 494 synchronized (mStats) { 495 mStats.noteJobsDeferredLocked(uid, numDeferred, sinceLast); 496 } 497 } 498 noteWakupAlarm(String name, int uid, WorkSource workSource, String tag)499 public void noteWakupAlarm(String name, int uid, WorkSource workSource, String tag) { 500 enforceCallingPermission(); 501 synchronized (mStats) { 502 mStats.noteWakupAlarmLocked(name, uid, workSource, tag); 503 } 504 } 505 noteAlarmStart(String name, WorkSource workSource, int uid)506 public void noteAlarmStart(String name, WorkSource workSource, int uid) { 507 enforceCallingPermission(); 508 synchronized (mStats) { 509 mStats.noteAlarmStartLocked(name, workSource, uid); 510 } 511 } 512 noteAlarmFinish(String name, WorkSource workSource, int uid)513 public void noteAlarmFinish(String name, WorkSource workSource, int uid) { 514 enforceCallingPermission(); 515 synchronized (mStats) { 516 mStats.noteAlarmFinishLocked(name, workSource, uid); 517 } 518 } 519 noteStartWakelock(int uid, int pid, String name, String historyName, int type, boolean unimportantForLogging)520 public void noteStartWakelock(int uid, int pid, String name, String historyName, int type, 521 boolean unimportantForLogging) { 522 enforceCallingPermission(); 523 synchronized (mStats) { 524 mStats.noteStartWakeLocked(uid, pid, null, name, historyName, type, 525 unimportantForLogging, SystemClock.elapsedRealtime(), 526 SystemClock.uptimeMillis()); 527 } 528 } 529 noteStopWakelock(int uid, int pid, String name, String historyName, int type)530 public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) { 531 enforceCallingPermission(); 532 synchronized (mStats) { 533 mStats.noteStopWakeLocked(uid, pid, null, name, historyName, type, 534 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); 535 } 536 } 537 noteStartWakelockFromSource(WorkSource ws, int pid, String name, String historyName, int type, boolean unimportantForLogging)538 public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, 539 String historyName, int type, boolean unimportantForLogging) { 540 enforceCallingPermission(); 541 synchronized (mStats) { 542 mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName, 543 type, unimportantForLogging); 544 } 545 } 546 noteChangeWakelockFromSource(WorkSource ws, int pid, String name, String historyName, int type, WorkSource newWs, int newPid, String newName, String newHistoryName, int newType, boolean newUnimportantForLogging)547 public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name, 548 String historyName, int type, WorkSource newWs, int newPid, String newName, 549 String newHistoryName, int newType, boolean newUnimportantForLogging) { 550 enforceCallingPermission(); 551 synchronized (mStats) { 552 mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, 553 newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging); 554 } 555 } 556 noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName, int type)557 public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName, 558 int type) { 559 enforceCallingPermission(); 560 synchronized (mStats) { 561 mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type); 562 } 563 } 564 565 @Override noteLongPartialWakelockStart(String name, String historyName, int uid)566 public void noteLongPartialWakelockStart(String name, String historyName, int uid) { 567 enforceCallingPermission(); 568 synchronized (mStats) { 569 mStats.noteLongPartialWakelockStart(name, historyName, uid); 570 } 571 } 572 573 @Override noteLongPartialWakelockStartFromSource(String name, String historyName, WorkSource workSource)574 public void noteLongPartialWakelockStartFromSource(String name, String historyName, 575 WorkSource workSource) { 576 enforceCallingPermission(); 577 synchronized (mStats) { 578 mStats.noteLongPartialWakelockStartFromSource(name, historyName, workSource); 579 } 580 } 581 582 @Override noteLongPartialWakelockFinish(String name, String historyName, int uid)583 public void noteLongPartialWakelockFinish(String name, String historyName, int uid) { 584 enforceCallingPermission(); 585 synchronized (mStats) { 586 mStats.noteLongPartialWakelockFinish(name, historyName, uid); 587 } 588 } 589 590 @Override noteLongPartialWakelockFinishFromSource(String name, String historyName, WorkSource workSource)591 public void noteLongPartialWakelockFinishFromSource(String name, String historyName, 592 WorkSource workSource) { 593 enforceCallingPermission(); 594 synchronized (mStats) { 595 mStats.noteLongPartialWakelockFinishFromSource(name, historyName, workSource); 596 } 597 } 598 noteStartSensor(int uid, int sensor)599 public void noteStartSensor(int uid, int sensor) { 600 enforceCallingPermission(); 601 synchronized (mStats) { 602 mStats.noteStartSensorLocked(uid, sensor); 603 StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, uid, null, sensor, 604 StatsLog.SENSOR_STATE_CHANGED__STATE__ON); 605 } 606 } 607 noteStopSensor(int uid, int sensor)608 public void noteStopSensor(int uid, int sensor) { 609 enforceCallingPermission(); 610 synchronized (mStats) { 611 mStats.noteStopSensorLocked(uid, sensor); 612 StatsLog.write_non_chained(StatsLog.SENSOR_STATE_CHANGED, uid, null, 613 sensor, StatsLog.SENSOR_STATE_CHANGED__STATE__OFF); 614 } 615 } 616 noteVibratorOn(int uid, long durationMillis)617 public void noteVibratorOn(int uid, long durationMillis) { 618 enforceCallingPermission(); 619 synchronized (mStats) { 620 mStats.noteVibratorOnLocked(uid, durationMillis); 621 } 622 } 623 noteVibratorOff(int uid)624 public void noteVibratorOff(int uid) { 625 enforceCallingPermission(); 626 synchronized (mStats) { 627 mStats.noteVibratorOffLocked(uid); 628 } 629 } 630 631 @Override noteGpsChanged(WorkSource oldWs, WorkSource newWs)632 public void noteGpsChanged(WorkSource oldWs, WorkSource newWs) { 633 enforceCallingPermission(); 634 synchronized (mStats) { 635 mStats.noteGpsChangedLocked(oldWs, newWs); 636 } 637 } 638 noteGpsSignalQuality(int signalLevel)639 public void noteGpsSignalQuality(int signalLevel) { 640 synchronized (mStats) { 641 mStats.noteGpsSignalQualityLocked(signalLevel); 642 } 643 } 644 noteScreenState(int state)645 public void noteScreenState(int state) { 646 enforceCallingPermission(); 647 if (DBG) Slog.d(TAG, "begin noteScreenState"); 648 synchronized (mStats) { 649 StatsLog.write(StatsLog.SCREEN_STATE_CHANGED, state); 650 651 mStats.noteScreenStateLocked(state); 652 } 653 if (DBG) Slog.d(TAG, "end noteScreenState"); 654 } 655 noteScreenBrightness(int brightness)656 public void noteScreenBrightness(int brightness) { 657 enforceCallingPermission(); 658 synchronized (mStats) { 659 StatsLog.write(StatsLog.SCREEN_BRIGHTNESS_CHANGED, brightness); 660 mStats.noteScreenBrightnessLocked(brightness); 661 } 662 } 663 noteUserActivity(int uid, int event)664 public void noteUserActivity(int uid, int event) { 665 enforceCallingPermission(); 666 synchronized (mStats) { 667 mStats.noteUserActivityLocked(uid, event); 668 } 669 } 670 noteWakeUp(String reason, int reasonUid)671 public void noteWakeUp(String reason, int reasonUid) { 672 enforceCallingPermission(); 673 synchronized (mStats) { 674 mStats.noteWakeUpLocked(reason, reasonUid); 675 } 676 } 677 noteInteractive(boolean interactive)678 public void noteInteractive(boolean interactive) { 679 enforceCallingPermission(); 680 synchronized (mStats) { 681 mStats.noteInteractiveLocked(interactive); 682 } 683 } 684 noteConnectivityChanged(int type, String extra)685 public void noteConnectivityChanged(int type, String extra) { 686 enforceCallingPermission(); 687 synchronized (mStats) { 688 mStats.noteConnectivityChangedLocked(type, extra); 689 } 690 } 691 noteMobileRadioPowerState(int powerState, long timestampNs, int uid)692 public void noteMobileRadioPowerState(int powerState, long timestampNs, int uid) { 693 enforceCallingPermission(); 694 final boolean update; 695 synchronized (mStats) { 696 update = mStats.noteMobileRadioPowerStateLocked(powerState, timestampNs, uid); 697 } 698 699 if (update) { 700 mWorker.scheduleSync("modem-data", BatteryExternalStatsWorker.UPDATE_RADIO); 701 } 702 } 703 notePhoneOn()704 public void notePhoneOn() { 705 enforceCallingPermission(); 706 synchronized (mStats) { 707 mStats.notePhoneOnLocked(); 708 } 709 } 710 notePhoneOff()711 public void notePhoneOff() { 712 enforceCallingPermission(); 713 synchronized (mStats) { 714 mStats.notePhoneOffLocked(); 715 } 716 } 717 notePhoneSignalStrength(SignalStrength signalStrength)718 public void notePhoneSignalStrength(SignalStrength signalStrength) { 719 enforceCallingPermission(); 720 synchronized (mStats) { 721 mStats.notePhoneSignalStrengthLocked(signalStrength); 722 } 723 } 724 notePhoneDataConnectionState(int dataType, boolean hasData)725 public void notePhoneDataConnectionState(int dataType, boolean hasData) { 726 enforceCallingPermission(); 727 synchronized (mStats) { 728 mStats.notePhoneDataConnectionStateLocked(dataType, hasData); 729 } 730 } 731 notePhoneState(int state)732 public void notePhoneState(int state) { 733 enforceCallingPermission(); 734 int simState = TelephonyManager.getDefault().getSimState(); 735 synchronized (mStats) { 736 mStats.notePhoneStateLocked(state, simState); 737 } 738 } 739 noteWifiOn()740 public void noteWifiOn() { 741 enforceCallingPermission(); 742 synchronized (mStats) { 743 mStats.noteWifiOnLocked(); 744 } 745 StatsLog.write(StatsLog.WIFI_ENABLED_STATE_CHANGED, 746 StatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__ON); 747 } 748 noteWifiOff()749 public void noteWifiOff() { 750 enforceCallingPermission(); 751 synchronized (mStats) { 752 mStats.noteWifiOffLocked(); 753 } 754 StatsLog.write(StatsLog.WIFI_ENABLED_STATE_CHANGED, 755 StatsLog.WIFI_ENABLED_STATE_CHANGED__STATE__OFF); 756 } 757 noteStartAudio(int uid)758 public void noteStartAudio(int uid) { 759 enforceSelfOrCallingPermission(uid); 760 synchronized (mStats) { 761 mStats.noteAudioOnLocked(uid); 762 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null, 763 StatsLog.AUDIO_STATE_CHANGED__STATE__ON); 764 } 765 } 766 noteStopAudio(int uid)767 public void noteStopAudio(int uid) { 768 enforceSelfOrCallingPermission(uid); 769 synchronized (mStats) { 770 mStats.noteAudioOffLocked(uid); 771 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, uid, null, 772 StatsLog.AUDIO_STATE_CHANGED__STATE__OFF); 773 } 774 } 775 noteStartVideo(int uid)776 public void noteStartVideo(int uid) { 777 enforceSelfOrCallingPermission(uid); 778 synchronized (mStats) { 779 mStats.noteVideoOnLocked(uid); 780 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid, null, 781 StatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__ON); 782 } 783 } 784 noteStopVideo(int uid)785 public void noteStopVideo(int uid) { 786 enforceSelfOrCallingPermission(uid); 787 synchronized (mStats) { 788 mStats.noteVideoOffLocked(uid); 789 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, uid, 790 null, StatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__OFF); 791 } 792 } 793 noteResetAudio()794 public void noteResetAudio() { 795 enforceCallingPermission(); 796 synchronized (mStats) { 797 mStats.noteResetAudioLocked(); 798 StatsLog.write_non_chained(StatsLog.AUDIO_STATE_CHANGED, -1, null, 799 StatsLog.AUDIO_STATE_CHANGED__STATE__RESET); 800 } 801 } 802 noteResetVideo()803 public void noteResetVideo() { 804 enforceCallingPermission(); 805 synchronized (mStats) { 806 mStats.noteResetVideoLocked(); 807 StatsLog.write_non_chained(StatsLog.MEDIA_CODEC_STATE_CHANGED, -1, null, 808 StatsLog.MEDIA_CODEC_STATE_CHANGED__STATE__RESET); 809 } 810 } 811 noteFlashlightOn(int uid)812 public void noteFlashlightOn(int uid) { 813 enforceCallingPermission(); 814 synchronized (mStats) { 815 mStats.noteFlashlightOnLocked(uid); 816 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, uid, null, 817 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__ON); 818 } 819 } 820 noteFlashlightOff(int uid)821 public void noteFlashlightOff(int uid) { 822 enforceCallingPermission(); 823 synchronized (mStats) { 824 mStats.noteFlashlightOffLocked(uid); 825 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, uid, null, 826 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__OFF); 827 } 828 } 829 noteStartCamera(int uid)830 public void noteStartCamera(int uid) { 831 enforceCallingPermission(); 832 if (DBG) Slog.d(TAG, "begin noteStartCamera"); 833 synchronized (mStats) { 834 mStats.noteCameraOnLocked(uid); 835 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, uid, null, 836 StatsLog.CAMERA_STATE_CHANGED__STATE__ON); 837 } 838 if (DBG) Slog.d(TAG, "end noteStartCamera"); 839 } 840 noteStopCamera(int uid)841 public void noteStopCamera(int uid) { 842 enforceCallingPermission(); 843 synchronized (mStats) { 844 mStats.noteCameraOffLocked(uid); 845 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, uid, null, 846 StatsLog.CAMERA_STATE_CHANGED__STATE__OFF); 847 } 848 } 849 noteResetCamera()850 public void noteResetCamera() { 851 enforceCallingPermission(); 852 synchronized (mStats) { 853 mStats.noteResetCameraLocked(); 854 StatsLog.write_non_chained(StatsLog.CAMERA_STATE_CHANGED, -1, null, 855 StatsLog.CAMERA_STATE_CHANGED__STATE__RESET); 856 } 857 } 858 noteResetFlashlight()859 public void noteResetFlashlight() { 860 enforceCallingPermission(); 861 synchronized (mStats) { 862 mStats.noteResetFlashlightLocked(); 863 StatsLog.write_non_chained(StatsLog.FLASHLIGHT_STATE_CHANGED, -1, null, 864 StatsLog.FLASHLIGHT_STATE_CHANGED__STATE__RESET); 865 } 866 } 867 868 @Override noteWifiRadioPowerState(int powerState, long tsNanos, int uid)869 public void noteWifiRadioPowerState(int powerState, long tsNanos, int uid) { 870 enforceCallingPermission(); 871 872 // There was a change in WiFi power state. 873 // Collect data now for the past activity. 874 synchronized (mStats) { 875 if (mStats.isOnBattery()) { 876 final String type = (powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_HIGH || 877 powerState == DataConnectionRealTimeInfo.DC_POWER_STATE_MEDIUM) ? "active" 878 : "inactive"; 879 mWorker.scheduleSync("wifi-data: " + type, BatteryExternalStatsWorker.UPDATE_WIFI); 880 } 881 mStats.noteWifiRadioPowerState(powerState, tsNanos, uid); 882 } 883 } 884 noteWifiRunning(WorkSource ws)885 public void noteWifiRunning(WorkSource ws) { 886 enforceCallingPermission(); 887 synchronized (mStats) { 888 mStats.noteWifiRunningLocked(ws); 889 } 890 // TODO: Log WIFI_RUNNING_STATE_CHANGED in a better spot to include Hotspot too. 891 StatsLog.write(StatsLog.WIFI_RUNNING_STATE_CHANGED, 892 ws, StatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON); 893 } 894 noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs)895 public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) { 896 enforceCallingPermission(); 897 synchronized (mStats) { 898 mStats.noteWifiRunningChangedLocked(oldWs, newWs); 899 } 900 StatsLog.write(StatsLog.WIFI_RUNNING_STATE_CHANGED, 901 newWs, StatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__ON); 902 StatsLog.write(StatsLog.WIFI_RUNNING_STATE_CHANGED, 903 oldWs, StatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF); 904 } 905 noteWifiStopped(WorkSource ws)906 public void noteWifiStopped(WorkSource ws) { 907 enforceCallingPermission(); 908 synchronized (mStats) { 909 mStats.noteWifiStoppedLocked(ws); 910 } 911 StatsLog.write(StatsLog.WIFI_RUNNING_STATE_CHANGED, 912 ws, StatsLog.WIFI_RUNNING_STATE_CHANGED__STATE__OFF); 913 } 914 noteWifiState(int wifiState, String accessPoint)915 public void noteWifiState(int wifiState, String accessPoint) { 916 enforceCallingPermission(); 917 synchronized (mStats) { 918 mStats.noteWifiStateLocked(wifiState, accessPoint); 919 } 920 } 921 noteWifiSupplicantStateChanged(int supplState, boolean failedAuth)922 public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) { 923 enforceCallingPermission(); 924 synchronized (mStats) { 925 mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth); 926 } 927 } 928 noteWifiRssiChanged(int newRssi)929 public void noteWifiRssiChanged(int newRssi) { 930 enforceCallingPermission(); 931 synchronized (mStats) { 932 mStats.noteWifiRssiChangedLocked(newRssi); 933 } 934 } 935 noteFullWifiLockAcquired(int uid)936 public void noteFullWifiLockAcquired(int uid) { 937 enforceCallingPermission(); 938 synchronized (mStats) { 939 mStats.noteFullWifiLockAcquiredLocked(uid); 940 } 941 } 942 noteFullWifiLockReleased(int uid)943 public void noteFullWifiLockReleased(int uid) { 944 enforceCallingPermission(); 945 synchronized (mStats) { 946 mStats.noteFullWifiLockReleasedLocked(uid); 947 } 948 } 949 noteWifiScanStarted(int uid)950 public void noteWifiScanStarted(int uid) { 951 enforceCallingPermission(); 952 synchronized (mStats) { 953 mStats.noteWifiScanStartedLocked(uid); 954 } 955 } 956 noteWifiScanStopped(int uid)957 public void noteWifiScanStopped(int uid) { 958 enforceCallingPermission(); 959 synchronized (mStats) { 960 mStats.noteWifiScanStoppedLocked(uid); 961 } 962 } 963 noteWifiMulticastEnabled(int uid)964 public void noteWifiMulticastEnabled(int uid) { 965 enforceCallingPermission(); 966 synchronized (mStats) { 967 mStats.noteWifiMulticastEnabledLocked(uid); 968 } 969 } 970 noteWifiMulticastDisabled(int uid)971 public void noteWifiMulticastDisabled(int uid) { 972 enforceCallingPermission(); 973 synchronized (mStats) { 974 mStats.noteWifiMulticastDisabledLocked(uid); 975 } 976 } 977 noteFullWifiLockAcquiredFromSource(WorkSource ws)978 public void noteFullWifiLockAcquiredFromSource(WorkSource ws) { 979 enforceCallingPermission(); 980 synchronized (mStats) { 981 mStats.noteFullWifiLockAcquiredFromSourceLocked(ws); 982 } 983 } 984 noteFullWifiLockReleasedFromSource(WorkSource ws)985 public void noteFullWifiLockReleasedFromSource(WorkSource ws) { 986 enforceCallingPermission(); 987 synchronized (mStats) { 988 mStats.noteFullWifiLockReleasedFromSourceLocked(ws); 989 } 990 } 991 noteWifiScanStartedFromSource(WorkSource ws)992 public void noteWifiScanStartedFromSource(WorkSource ws) { 993 enforceCallingPermission(); 994 synchronized (mStats) { 995 mStats.noteWifiScanStartedFromSourceLocked(ws); 996 } 997 } 998 noteWifiScanStoppedFromSource(WorkSource ws)999 public void noteWifiScanStoppedFromSource(WorkSource ws) { 1000 enforceCallingPermission(); 1001 synchronized (mStats) { 1002 mStats.noteWifiScanStoppedFromSourceLocked(ws); 1003 } 1004 } 1005 noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph)1006 public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) { 1007 enforceCallingPermission(); 1008 synchronized (mStats) { 1009 mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph); 1010 } 1011 } 1012 noteWifiBatchedScanStoppedFromSource(WorkSource ws)1013 public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) { 1014 enforceCallingPermission(); 1015 synchronized (mStats) { 1016 mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws); 1017 } 1018 } 1019 1020 @Override noteNetworkInterfaceType(String iface, int networkType)1021 public void noteNetworkInterfaceType(String iface, int networkType) { 1022 enforceCallingPermission(); 1023 synchronized (mStats) { 1024 mStats.noteNetworkInterfaceTypeLocked(iface, networkType); 1025 } 1026 } 1027 1028 @Override noteNetworkStatsEnabled()1029 public void noteNetworkStatsEnabled() { 1030 enforceCallingPermission(); 1031 // During device boot, qtaguid isn't enabled until after the inital 1032 // loading of battery stats. Now that they're enabled, take our initial 1033 // snapshot for future delta calculation. 1034 mWorker.scheduleSync("network-stats-enabled", 1035 BatteryExternalStatsWorker.UPDATE_RADIO | BatteryExternalStatsWorker.UPDATE_WIFI); 1036 } 1037 1038 @Override noteDeviceIdleMode(int mode, String activeReason, int activeUid)1039 public void noteDeviceIdleMode(int mode, String activeReason, int activeUid) { 1040 enforceCallingPermission(); 1041 synchronized (mStats) { 1042 mStats.noteDeviceIdleModeLocked(mode, activeReason, activeUid); 1043 } 1044 } 1045 notePackageInstalled(String pkgName, long versionCode)1046 public void notePackageInstalled(String pkgName, long versionCode) { 1047 enforceCallingPermission(); 1048 synchronized (mStats) { 1049 mStats.notePackageInstalledLocked(pkgName, versionCode); 1050 } 1051 } 1052 notePackageUninstalled(String pkgName)1053 public void notePackageUninstalled(String pkgName) { 1054 enforceCallingPermission(); 1055 synchronized (mStats) { 1056 mStats.notePackageUninstalledLocked(pkgName); 1057 } 1058 } 1059 1060 @Override noteBleScanStarted(WorkSource ws, boolean isUnoptimized)1061 public void noteBleScanStarted(WorkSource ws, boolean isUnoptimized) { 1062 enforceCallingPermission(); 1063 synchronized (mStats) { 1064 mStats.noteBluetoothScanStartedFromSourceLocked(ws, isUnoptimized); 1065 } 1066 } 1067 1068 @Override noteBleScanStopped(WorkSource ws, boolean isUnoptimized)1069 public void noteBleScanStopped(WorkSource ws, boolean isUnoptimized) { 1070 enforceCallingPermission(); 1071 synchronized (mStats) { 1072 mStats.noteBluetoothScanStoppedFromSourceLocked(ws, isUnoptimized); 1073 } 1074 } 1075 1076 @Override noteResetBleScan()1077 public void noteResetBleScan() { 1078 enforceCallingPermission(); 1079 synchronized (mStats) { 1080 mStats.noteResetBluetoothScanLocked(); 1081 } 1082 } 1083 1084 @Override noteBleScanResults(WorkSource ws, int numNewResults)1085 public void noteBleScanResults(WorkSource ws, int numNewResults) { 1086 enforceCallingPermission(); 1087 synchronized (mStats) { 1088 mStats.noteBluetoothScanResultsFromSourceLocked(ws, numNewResults); 1089 } 1090 } 1091 1092 @Override noteWifiControllerActivity(WifiActivityEnergyInfo info)1093 public void noteWifiControllerActivity(WifiActivityEnergyInfo info) { 1094 enforceCallingPermission(); 1095 1096 if (info == null || !info.isValid()) { 1097 Slog.e(TAG, "invalid wifi data given: " + info); 1098 return; 1099 } 1100 1101 mStats.updateWifiState(info); 1102 } 1103 1104 @Override noteBluetoothControllerActivity(BluetoothActivityEnergyInfo info)1105 public void noteBluetoothControllerActivity(BluetoothActivityEnergyInfo info) { 1106 enforceCallingPermission(); 1107 if (info == null || !info.isValid()) { 1108 Slog.e(TAG, "invalid bluetooth data given: " + info); 1109 return; 1110 } 1111 1112 synchronized (mStats) { 1113 mStats.updateBluetoothStateLocked(info); 1114 } 1115 } 1116 1117 @Override noteModemControllerActivity(ModemActivityInfo info)1118 public void noteModemControllerActivity(ModemActivityInfo info) { 1119 enforceCallingPermission(); 1120 1121 if (info == null || !info.isValid()) { 1122 Slog.e(TAG, "invalid modem data given: " + info); 1123 return; 1124 } 1125 1126 mStats.updateMobileRadioState(info); 1127 } 1128 isOnBattery()1129 public boolean isOnBattery() { 1130 return mStats.isOnBattery(); 1131 } 1132 1133 @Override setBatteryState(final int status, final int health, final int plugType, final int level, final int temp, final int volt, final int chargeUAh, final int chargeFullUAh)1134 public void setBatteryState(final int status, final int health, final int plugType, 1135 final int level, final int temp, final int volt, final int chargeUAh, 1136 final int chargeFullUAh) { 1137 enforceCallingPermission(); 1138 1139 // BatteryService calls us here and we may update external state. It would be wrong 1140 // to block such a low level service like BatteryService on external stats like WiFi. 1141 mWorker.scheduleRunnable(() -> { 1142 synchronized (mStats) { 1143 final boolean onBattery = BatteryStatsImpl.isOnBattery(plugType, status); 1144 if (mStats.isOnBattery() == onBattery) { 1145 // The battery state has not changed, so we don't need to sync external 1146 // stats immediately. 1147 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt, 1148 chargeUAh, chargeFullUAh); 1149 return; 1150 } 1151 } 1152 1153 // Sync external stats first as the battery has changed states. If we don't sync 1154 // before changing the state, we may not collect the relevant data later. 1155 // Order here is guaranteed since we're scheduling from the same thread and we are 1156 // using a single threaded executor. 1157 mWorker.scheduleSync("battery-state", BatteryExternalStatsWorker.UPDATE_ALL); 1158 mWorker.scheduleRunnable(() -> { 1159 synchronized (mStats) { 1160 mStats.setBatteryStateLocked(status, health, plugType, level, temp, volt, 1161 chargeUAh, chargeFullUAh); 1162 } 1163 }); 1164 }); 1165 } 1166 getAwakeTimeBattery()1167 public long getAwakeTimeBattery() { 1168 mContext.enforceCallingOrSelfPermission( 1169 android.Manifest.permission.BATTERY_STATS, null); 1170 return mStats.getAwakeTimeBattery(); 1171 } 1172 getAwakeTimePlugged()1173 public long getAwakeTimePlugged() { 1174 mContext.enforceCallingOrSelfPermission( 1175 android.Manifest.permission.BATTERY_STATS, null); 1176 return mStats.getAwakeTimePlugged(); 1177 } 1178 enforceCallingPermission()1179 public void enforceCallingPermission() { 1180 if (Binder.getCallingPid() == Process.myPid()) { 1181 return; 1182 } 1183 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS, 1184 Binder.getCallingPid(), Binder.getCallingUid(), null); 1185 } 1186 enforceSelfOrCallingPermission(int uid)1187 private void enforceSelfOrCallingPermission(int uid) { 1188 if (Binder.getCallingUid() == uid) { 1189 return; 1190 } 1191 enforceCallingPermission(); 1192 } 1193 1194 final class WakeupReasonThread extends Thread { 1195 private static final int MAX_REASON_SIZE = 512; 1196 private CharsetDecoder mDecoder; 1197 private ByteBuffer mUtf8Buffer; 1198 private CharBuffer mUtf16Buffer; 1199 WakeupReasonThread()1200 WakeupReasonThread() { 1201 super("BatteryStats_wakeupReason"); 1202 } 1203 run()1204 public void run() { 1205 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); 1206 1207 mDecoder = StandardCharsets.UTF_8 1208 .newDecoder() 1209 .onMalformedInput(CodingErrorAction.REPLACE) 1210 .onUnmappableCharacter(CodingErrorAction.REPLACE) 1211 .replaceWith("?"); 1212 1213 mUtf8Buffer = ByteBuffer.allocateDirect(MAX_REASON_SIZE); 1214 mUtf16Buffer = CharBuffer.allocate(MAX_REASON_SIZE); 1215 1216 try { 1217 String reason; 1218 while ((reason = waitWakeup()) != null) { 1219 synchronized (mStats) { 1220 mStats.noteWakeupReasonLocked(reason); 1221 } 1222 } 1223 } catch (RuntimeException e) { 1224 Slog.e(TAG, "Failure reading wakeup reasons", e); 1225 } 1226 } 1227 waitWakeup()1228 private String waitWakeup() { 1229 mUtf8Buffer.clear(); 1230 mUtf16Buffer.clear(); 1231 mDecoder.reset(); 1232 1233 int bytesWritten = nativeWaitWakeup(mUtf8Buffer); 1234 if (bytesWritten < 0) { 1235 return null; 1236 } else if (bytesWritten == 0) { 1237 return "unknown"; 1238 } 1239 1240 // Set the buffer's limit to the number of bytes written. 1241 mUtf8Buffer.limit(bytesWritten); 1242 1243 // Decode the buffer from UTF-8 to UTF-16. 1244 // Unmappable characters will be replaced. 1245 mDecoder.decode(mUtf8Buffer, mUtf16Buffer, true); 1246 mUtf16Buffer.flip(); 1247 1248 // Create a String from the UTF-16 buffer. 1249 return mUtf16Buffer.toString(); 1250 } 1251 } 1252 nativeWaitWakeup(ByteBuffer outBuffer)1253 private static native int nativeWaitWakeup(ByteBuffer outBuffer); 1254 dumpHelp(PrintWriter pw)1255 private void dumpHelp(PrintWriter pw) { 1256 pw.println("Battery stats (batterystats) dump options:"); 1257 pw.println(" [--checkin] [--proto] [--history] [--history-start] [--charged] [-c]"); 1258 pw.println(" [--daily] [--reset] [--write] [--new-daily] [--read-daily] [-h] [<package.name>]"); 1259 pw.println(" --checkin: generate output for a checkin report; will write (and clear) the"); 1260 pw.println(" last old completed stats when they had been reset."); 1261 pw.println(" -c: write the current stats in checkin format."); 1262 pw.println(" --proto: write the current aggregate stats (without history) in proto format."); 1263 pw.println(" --history: show only history data."); 1264 pw.println(" --history-start <num>: show only history data starting at given time offset."); 1265 pw.println(" --history-create-events <num>: create <num> of battery history events."); 1266 pw.println(" --charged: only output data since last charged."); 1267 pw.println(" --daily: only output full daily data."); 1268 pw.println(" --reset: reset the stats, clearing all current data."); 1269 pw.println(" --write: force write current collected stats to disk."); 1270 pw.println(" --new-daily: immediately create and write new daily stats record."); 1271 pw.println(" --read-daily: read-load last written daily stats."); 1272 pw.println(" --settings: dump the settings key/values related to batterystats"); 1273 pw.println(" --cpu: dump cpu stats for debugging purpose"); 1274 pw.println(" <package.name>: optional name of package to filter output by."); 1275 pw.println(" -h: print this help text."); 1276 pw.println("Battery stats (batterystats) commands:"); 1277 pw.println(" enable|disable <option>"); 1278 pw.println(" Enable or disable a running option. Option state is not saved across boots."); 1279 pw.println(" Options are:"); 1280 pw.println(" full-history: include additional detailed events in battery history:"); 1281 pw.println(" wake_lock_in, alarms and proc events"); 1282 pw.println(" no-auto-reset: don't automatically reset stats when unplugged"); 1283 pw.println(" pretend-screen-off: pretend the screen is off, even if screen state changes"); 1284 } 1285 dumpSettings(PrintWriter pw)1286 private void dumpSettings(PrintWriter pw) { 1287 synchronized (mStats) { 1288 mStats.dumpConstantsLocked(pw); 1289 } 1290 } 1291 dumpCpuStats(PrintWriter pw)1292 private void dumpCpuStats(PrintWriter pw) { 1293 synchronized (mStats) { 1294 mStats.dumpCpuStatsLocked(pw); 1295 } 1296 } 1297 doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable)1298 private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) { 1299 i++; 1300 if (i >= args.length) { 1301 pw.println("Missing option argument for " + (enable ? "--enable" : "--disable")); 1302 dumpHelp(pw); 1303 return -1; 1304 } 1305 if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) { 1306 synchronized (mStats) { 1307 mStats.setRecordAllHistoryLocked(enable); 1308 } 1309 } else if ("no-auto-reset".equals(args[i])) { 1310 synchronized (mStats) { 1311 mStats.setNoAutoReset(enable); 1312 } 1313 } else if ("pretend-screen-off".equals(args[i])) { 1314 synchronized (mStats) { 1315 mStats.setPretendScreenOff(enable); 1316 } 1317 } else { 1318 pw.println("Unknown enable/disable option: " + args[i]); 1319 dumpHelp(pw); 1320 return -1; 1321 } 1322 return i; 1323 } 1324 1325 1326 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1327 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1328 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; 1329 1330 int flags = 0; 1331 boolean useCheckinFormat = false; 1332 boolean toProto = false; 1333 boolean isRealCheckin = false; 1334 boolean noOutput = false; 1335 boolean writeData = false; 1336 long historyStart = -1; 1337 int reqUid = -1; 1338 if (args != null) { 1339 for (int i=0; i<args.length; i++) { 1340 String arg = args[i]; 1341 if ("--checkin".equals(arg)) { 1342 useCheckinFormat = true; 1343 isRealCheckin = true; 1344 } else if ("--history".equals(arg)) { 1345 flags |= BatteryStats.DUMP_HISTORY_ONLY; 1346 } else if ("--history-start".equals(arg)) { 1347 flags |= BatteryStats.DUMP_HISTORY_ONLY; 1348 i++; 1349 if (i >= args.length) { 1350 pw.println("Missing time argument for --history-since"); 1351 dumpHelp(pw); 1352 return; 1353 } 1354 historyStart = ParseUtils.parseLong(args[i], 0); 1355 writeData = true; 1356 } else if ("--history-create-events".equals(arg)) { 1357 i++; 1358 if (i >= args.length) { 1359 pw.println("Missing events argument for --history-create-events"); 1360 dumpHelp(pw); 1361 return; 1362 } 1363 final long events = ParseUtils.parseLong(args[i], 0); 1364 synchronized (mStats) { 1365 mStats.createFakeHistoryEvents(events); 1366 pw.println("Battery history create events started."); 1367 noOutput = true; 1368 } 1369 } else if ("-c".equals(arg)) { 1370 useCheckinFormat = true; 1371 flags |= BatteryStats.DUMP_INCLUDE_HISTORY; 1372 } else if ("--proto".equals(arg)) { 1373 toProto = true; 1374 } else if ("--charged".equals(arg)) { 1375 flags |= BatteryStats.DUMP_CHARGED_ONLY; 1376 } else if ("--daily".equals(arg)) { 1377 flags |= BatteryStats.DUMP_DAILY_ONLY; 1378 } else if ("--reset".equals(arg)) { 1379 synchronized (mStats) { 1380 mStats.resetAllStatsCmdLocked(); 1381 pw.println("Battery stats reset."); 1382 noOutput = true; 1383 } 1384 mWorker.scheduleSync("dump", BatteryExternalStatsWorker.UPDATE_ALL); 1385 } else if ("--write".equals(arg)) { 1386 syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL); 1387 synchronized (mStats) { 1388 mStats.writeSyncLocked(); 1389 pw.println("Battery stats written."); 1390 noOutput = true; 1391 } 1392 } else if ("--new-daily".equals(arg)) { 1393 synchronized (mStats) { 1394 mStats.recordDailyStatsLocked(); 1395 pw.println("New daily stats written."); 1396 noOutput = true; 1397 } 1398 } else if ("--read-daily".equals(arg)) { 1399 synchronized (mStats) { 1400 mStats.readDailyStatsLocked(); 1401 pw.println("Last daily stats read."); 1402 noOutput = true; 1403 } 1404 } else if ("--enable".equals(arg) || "enable".equals(arg)) { 1405 i = doEnableOrDisable(pw, i, args, true); 1406 if (i < 0) { 1407 return; 1408 } 1409 pw.println("Enabled: " + args[i]); 1410 return; 1411 } else if ("--disable".equals(arg) || "disable".equals(arg)) { 1412 i = doEnableOrDisable(pw, i, args, false); 1413 if (i < 0) { 1414 return; 1415 } 1416 pw.println("Disabled: " + args[i]); 1417 return; 1418 } else if ("-h".equals(arg)) { 1419 dumpHelp(pw); 1420 return; 1421 } else if ("--settings".equals(arg)) { 1422 dumpSettings(pw); 1423 return; 1424 } else if ("--cpu".equals(arg)) { 1425 dumpCpuStats(pw); 1426 return; 1427 } else if ("-a".equals(arg)) { 1428 flags |= BatteryStats.DUMP_VERBOSE; 1429 } else if (arg.length() > 0 && arg.charAt(0) == '-'){ 1430 pw.println("Unknown option: " + arg); 1431 dumpHelp(pw); 1432 return; 1433 } else { 1434 // Not an option, last argument must be a package name. 1435 try { 1436 reqUid = mContext.getPackageManager().getPackageUidAsUser(arg, 1437 UserHandle.getCallingUserId()); 1438 } catch (PackageManager.NameNotFoundException e) { 1439 pw.println("Unknown package: " + arg); 1440 dumpHelp(pw); 1441 return; 1442 } 1443 } 1444 } 1445 } 1446 if (noOutput) { 1447 return; 1448 } 1449 1450 long ident = Binder.clearCallingIdentity(); 1451 try { 1452 if (BatteryStatsHelper.checkWifiOnly(mContext)) { 1453 flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY; 1454 } 1455 // Fetch data from external sources and update the BatteryStatsImpl object with them. 1456 syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL); 1457 } finally { 1458 Binder.restoreCallingIdentity(ident); 1459 } 1460 1461 if (reqUid >= 0) { 1462 // By default, if the caller is only interested in a specific package, then 1463 // we only dump the aggregated data since charged. 1464 if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_CHARGED_ONLY)) == 0) { 1465 flags |= BatteryStats.DUMP_CHARGED_ONLY; 1466 // Also if they are doing -c, we don't want history. 1467 flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY; 1468 } 1469 } 1470 1471 if (toProto) { 1472 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications( 1473 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL); 1474 if (isRealCheckin) { 1475 // For a real checkin, first we want to prefer to use the last complete checkin 1476 // file if there is one. 1477 synchronized (mStats.mCheckinFile) { 1478 if (mStats.mCheckinFile.exists()) { 1479 try { 1480 byte[] raw = mStats.mCheckinFile.readFully(); 1481 if (raw != null) { 1482 Parcel in = Parcel.obtain(); 1483 in.unmarshall(raw, 0, raw.length); 1484 in.setDataPosition(0); 1485 BatteryStatsImpl checkinStats = new BatteryStatsImpl( 1486 null, mStats.mHandler, null, null, 1487 mUserManagerUserInfoProvider); 1488 checkinStats.readSummaryFromParcel(in); 1489 in.recycle(); 1490 checkinStats.dumpProtoLocked( 1491 mContext, fd, apps, flags, historyStart); 1492 mStats.mCheckinFile.delete(); 1493 return; 1494 } 1495 } catch (IOException | ParcelFormatException e) { 1496 Slog.w(TAG, "Failure reading checkin file " 1497 + mStats.mCheckinFile.getBaseFile(), e); 1498 } 1499 } 1500 } 1501 } 1502 if (DBG) Slog.d(TAG, "begin dumpProtoLocked from UID " + Binder.getCallingUid()); 1503 synchronized (mStats) { 1504 mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart); 1505 if (writeData) { 1506 mStats.writeAsyncLocked(); 1507 } 1508 } 1509 if (DBG) Slog.d(TAG, "end dumpProtoLocked"); 1510 } else if (useCheckinFormat) { 1511 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications( 1512 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL); 1513 if (isRealCheckin) { 1514 // For a real checkin, first we want to prefer to use the last complete checkin 1515 // file if there is one. 1516 synchronized (mStats.mCheckinFile) { 1517 if (mStats.mCheckinFile.exists()) { 1518 try { 1519 byte[] raw = mStats.mCheckinFile.readFully(); 1520 if (raw != null) { 1521 Parcel in = Parcel.obtain(); 1522 in.unmarshall(raw, 0, raw.length); 1523 in.setDataPosition(0); 1524 BatteryStatsImpl checkinStats = new BatteryStatsImpl( 1525 null, mStats.mHandler, null, null, 1526 mUserManagerUserInfoProvider); 1527 checkinStats.readSummaryFromParcel(in); 1528 in.recycle(); 1529 checkinStats.dumpCheckinLocked(mContext, pw, apps, flags, 1530 historyStart); 1531 mStats.mCheckinFile.delete(); 1532 return; 1533 } 1534 } catch (IOException | ParcelFormatException e) { 1535 Slog.w(TAG, "Failure reading checkin file " 1536 + mStats.mCheckinFile.getBaseFile(), e); 1537 } 1538 } 1539 } 1540 } 1541 if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid()); 1542 synchronized (mStats) { 1543 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart); 1544 if (writeData) { 1545 mStats.writeAsyncLocked(); 1546 } 1547 } 1548 if (DBG) Slog.d(TAG, "end dumpCheckinLocked"); 1549 } else { 1550 if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid()); 1551 synchronized (mStats) { 1552 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart); 1553 if (writeData) { 1554 mStats.writeAsyncLocked(); 1555 } 1556 } 1557 if (DBG) Slog.d(TAG, "end dumpLocked"); 1558 } 1559 } 1560 1561 /** 1562 * Gets a snapshot of cellular stats 1563 * @hide 1564 */ getCellularBatteryStats()1565 public CellularBatteryStats getCellularBatteryStats() { 1566 synchronized (mStats) { 1567 return mStats.getCellularBatteryStats(); 1568 } 1569 } 1570 1571 /** 1572 * Gets a snapshot of Wifi stats 1573 * @hide 1574 */ getWifiBatteryStats()1575 public WifiBatteryStats getWifiBatteryStats() { 1576 synchronized (mStats) { 1577 return mStats.getWifiBatteryStats(); 1578 } 1579 } 1580 1581 /** 1582 * Gets a snapshot of Gps stats 1583 * @hide 1584 */ getGpsBatteryStats()1585 public GpsBatteryStats getGpsBatteryStats() { 1586 synchronized (mStats) { 1587 return mStats.getGpsBatteryStats(); 1588 } 1589 } 1590 1591 /** 1592 * Gets a snapshot of the system health for a particular uid. 1593 */ 1594 @Override takeUidSnapshot(int requestUid)1595 public HealthStatsParceler takeUidSnapshot(int requestUid) { 1596 if (requestUid != Binder.getCallingUid()) { 1597 mContext.enforceCallingOrSelfPermission( 1598 android.Manifest.permission.BATTERY_STATS, null); 1599 } 1600 long ident = Binder.clearCallingIdentity(); 1601 try { 1602 if (shouldCollectExternalStats()) { 1603 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL); 1604 } 1605 synchronized (mStats) { 1606 return getHealthStatsForUidLocked(requestUid); 1607 } 1608 } catch (Exception ex) { 1609 Slog.w(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex); 1610 throw ex; 1611 } finally { 1612 Binder.restoreCallingIdentity(ident); 1613 } 1614 } 1615 1616 /** 1617 * Gets a snapshot of the system health for a number of uids. 1618 */ 1619 @Override takeUidSnapshots(int[] requestUids)1620 public HealthStatsParceler[] takeUidSnapshots(int[] requestUids) { 1621 if (!onlyCaller(requestUids)) { 1622 mContext.enforceCallingOrSelfPermission( 1623 android.Manifest.permission.BATTERY_STATS, null); 1624 } 1625 long ident = Binder.clearCallingIdentity(); 1626 int i=-1; 1627 try { 1628 if (shouldCollectExternalStats()) { 1629 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL); 1630 } 1631 synchronized (mStats) { 1632 final int N = requestUids.length; 1633 final HealthStatsParceler[] results = new HealthStatsParceler[N]; 1634 for (i=0; i<N; i++) { 1635 results[i] = getHealthStatsForUidLocked(requestUids[i]); 1636 } 1637 return results; 1638 } 1639 } catch (Exception ex) { 1640 if (DBG) Slog.d(TAG, "Crashed while writing for takeUidSnapshots(" 1641 + Arrays.toString(requestUids) + ") i=" + i, ex); 1642 throw ex; 1643 } finally { 1644 Binder.restoreCallingIdentity(ident); 1645 } 1646 } 1647 shouldCollectExternalStats()1648 private boolean shouldCollectExternalStats() { 1649 return (SystemClock.elapsedRealtime() - mWorker.getLastCollectionTimeStamp()) 1650 > mStats.getExternalStatsCollectionRateLimitMs(); 1651 } 1652 1653 /** 1654 * Returns whether the Binder.getCallingUid is the only thing in requestUids. 1655 */ onlyCaller(int[] requestUids)1656 private static boolean onlyCaller(int[] requestUids) { 1657 final int caller = Binder.getCallingUid(); 1658 final int N = requestUids.length; 1659 for (int i=0; i<N; i++) { 1660 if (requestUids[i] != caller) { 1661 return false; 1662 } 1663 } 1664 return true; 1665 } 1666 1667 /** 1668 * Gets a HealthStatsParceler for the given uid. You should probably call 1669 * updateExternalStatsSync first. 1670 */ getHealthStatsForUidLocked(int requestUid)1671 HealthStatsParceler getHealthStatsForUidLocked(int requestUid) { 1672 final HealthStatsBatteryStatsWriter writer = new HealthStatsBatteryStatsWriter(); 1673 final HealthStatsWriter uidWriter = new HealthStatsWriter(UidHealthStats.CONSTANTS); 1674 final BatteryStats.Uid uid = mStats.getUidStats().get(requestUid); 1675 if (uid != null) { 1676 writer.writeUid(uidWriter, mStats, uid); 1677 } 1678 return new HealthStatsParceler(uidWriter); 1679 } 1680 1681 /** 1682 * Delay for sending ACTION_CHARGING after device is plugged in. 1683 * 1684 * @hide 1685 */ setChargingStateUpdateDelayMillis(int delayMillis)1686 public boolean setChargingStateUpdateDelayMillis(int delayMillis) { 1687 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER, null); 1688 final long ident = Binder.clearCallingIdentity(); 1689 1690 try { 1691 final ContentResolver contentResolver = mContext.getContentResolver(); 1692 return Settings.Global.putLong(contentResolver, 1693 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 1694 delayMillis); 1695 } finally { 1696 Binder.restoreCallingIdentity(ident); 1697 } 1698 } 1699 1700 } 1701