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 = 4096; 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, int serviceType)725 public void notePhoneDataConnectionState(int dataType, boolean hasData, int serviceType) { 726 enforceCallingPermission(); 727 synchronized (mStats) { 728 mStats.notePhoneDataConnectionStateLocked(dataType, hasData, serviceType); 729 } 730 } 731 notePhoneState(int state)732 public void notePhoneState(int state) { 733 enforceCallingPermission(); 734 int simState = mContext.getSystemService(TelephonyManager.class).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 enforceCallingPermission(); 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 enforceCallingPermission(); 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 enforceCallingPermission(); 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 enforceCallingPermission(); 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, final long chargeTimeToFullSeconds)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, final long chargeTimeToFullSeconds) { 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, chargeTimeToFullSeconds); 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, chargeTimeToFullSeconds); 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 1187 final class WakeupReasonThread extends Thread { 1188 private static final int MAX_REASON_SIZE = 512; 1189 private CharsetDecoder mDecoder; 1190 private ByteBuffer mUtf8Buffer; 1191 private CharBuffer mUtf16Buffer; 1192 WakeupReasonThread()1193 WakeupReasonThread() { 1194 super("BatteryStats_wakeupReason"); 1195 } 1196 run()1197 public void run() { 1198 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); 1199 1200 mDecoder = StandardCharsets.UTF_8 1201 .newDecoder() 1202 .onMalformedInput(CodingErrorAction.REPLACE) 1203 .onUnmappableCharacter(CodingErrorAction.REPLACE) 1204 .replaceWith("?"); 1205 1206 mUtf8Buffer = ByteBuffer.allocateDirect(MAX_REASON_SIZE); 1207 mUtf16Buffer = CharBuffer.allocate(MAX_REASON_SIZE); 1208 1209 try { 1210 String reason; 1211 while ((reason = waitWakeup()) != null) { 1212 synchronized (mStats) { 1213 mStats.noteWakeupReasonLocked(reason); 1214 } 1215 } 1216 } catch (RuntimeException e) { 1217 Slog.e(TAG, "Failure reading wakeup reasons", e); 1218 } 1219 } 1220 waitWakeup()1221 private String waitWakeup() { 1222 mUtf8Buffer.clear(); 1223 mUtf16Buffer.clear(); 1224 mDecoder.reset(); 1225 1226 int bytesWritten = nativeWaitWakeup(mUtf8Buffer); 1227 if (bytesWritten < 0) { 1228 return null; 1229 } else if (bytesWritten == 0) { 1230 return "unknown"; 1231 } 1232 1233 // Set the buffer's limit to the number of bytes written. 1234 mUtf8Buffer.limit(bytesWritten); 1235 1236 // Decode the buffer from UTF-8 to UTF-16. 1237 // Unmappable characters will be replaced. 1238 mDecoder.decode(mUtf8Buffer, mUtf16Buffer, true); 1239 mUtf16Buffer.flip(); 1240 1241 // Create a String from the UTF-16 buffer. 1242 return mUtf16Buffer.toString(); 1243 } 1244 } 1245 nativeWaitWakeup(ByteBuffer outBuffer)1246 private static native int nativeWaitWakeup(ByteBuffer outBuffer); 1247 dumpHelp(PrintWriter pw)1248 private void dumpHelp(PrintWriter pw) { 1249 pw.println("Battery stats (batterystats) dump options:"); 1250 pw.println(" [--checkin] [--proto] [--history] [--history-start] [--charged] [-c]"); 1251 pw.println(" [--daily] [--reset] [--write] [--new-daily] [--read-daily] [-h] [<package.name>]"); 1252 pw.println(" --checkin: generate output for a checkin report; will write (and clear) the"); 1253 pw.println(" last old completed stats when they had been reset."); 1254 pw.println(" -c: write the current stats in checkin format."); 1255 pw.println(" --proto: write the current aggregate stats (without history) in proto format."); 1256 pw.println(" --history: show only history data."); 1257 pw.println(" --history-start <num>: show only history data starting at given time offset."); 1258 pw.println(" --history-create-events <num>: create <num> of battery history events."); 1259 pw.println(" --charged: only output data since last charged."); 1260 pw.println(" --daily: only output full daily data."); 1261 pw.println(" --reset: reset the stats, clearing all current data."); 1262 pw.println(" --write: force write current collected stats to disk."); 1263 pw.println(" --new-daily: immediately create and write new daily stats record."); 1264 pw.println(" --read-daily: read-load last written daily stats."); 1265 pw.println(" --settings: dump the settings key/values related to batterystats"); 1266 pw.println(" --cpu: dump cpu stats for debugging purpose"); 1267 pw.println(" <package.name>: optional name of package to filter output by."); 1268 pw.println(" -h: print this help text."); 1269 pw.println("Battery stats (batterystats) commands:"); 1270 pw.println(" enable|disable <option>"); 1271 pw.println(" Enable or disable a running option. Option state is not saved across boots."); 1272 pw.println(" Options are:"); 1273 pw.println(" full-history: include additional detailed events in battery history:"); 1274 pw.println(" wake_lock_in, alarms and proc events"); 1275 pw.println(" no-auto-reset: don't automatically reset stats when unplugged"); 1276 pw.println(" pretend-screen-off: pretend the screen is off, even if screen state changes"); 1277 } 1278 dumpSettings(PrintWriter pw)1279 private void dumpSettings(PrintWriter pw) { 1280 synchronized (mStats) { 1281 mStats.dumpConstantsLocked(pw); 1282 } 1283 } 1284 dumpCpuStats(PrintWriter pw)1285 private void dumpCpuStats(PrintWriter pw) { 1286 synchronized (mStats) { 1287 mStats.dumpCpuStatsLocked(pw); 1288 } 1289 } 1290 doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable)1291 private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) { 1292 i++; 1293 if (i >= args.length) { 1294 pw.println("Missing option argument for " + (enable ? "--enable" : "--disable")); 1295 dumpHelp(pw); 1296 return -1; 1297 } 1298 if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) { 1299 synchronized (mStats) { 1300 mStats.setRecordAllHistoryLocked(enable); 1301 } 1302 } else if ("no-auto-reset".equals(args[i])) { 1303 synchronized (mStats) { 1304 mStats.setNoAutoReset(enable); 1305 } 1306 } else if ("pretend-screen-off".equals(args[i])) { 1307 synchronized (mStats) { 1308 mStats.setPretendScreenOff(enable); 1309 } 1310 } else { 1311 pw.println("Unknown enable/disable option: " + args[i]); 1312 dumpHelp(pw); 1313 return -1; 1314 } 1315 return i; 1316 } 1317 1318 1319 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)1320 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 1321 if (!DumpUtils.checkDumpAndUsageStatsPermission(mContext, TAG, pw)) return; 1322 1323 int flags = 0; 1324 boolean useCheckinFormat = false; 1325 boolean toProto = false; 1326 boolean isRealCheckin = false; 1327 boolean noOutput = false; 1328 boolean writeData = false; 1329 long historyStart = -1; 1330 int reqUid = -1; 1331 if (args != null) { 1332 for (int i=0; i<args.length; i++) { 1333 String arg = args[i]; 1334 if ("--checkin".equals(arg)) { 1335 useCheckinFormat = true; 1336 isRealCheckin = true; 1337 } else if ("--history".equals(arg)) { 1338 flags |= BatteryStats.DUMP_HISTORY_ONLY; 1339 } else if ("--history-start".equals(arg)) { 1340 flags |= BatteryStats.DUMP_HISTORY_ONLY; 1341 i++; 1342 if (i >= args.length) { 1343 pw.println("Missing time argument for --history-since"); 1344 dumpHelp(pw); 1345 return; 1346 } 1347 historyStart = ParseUtils.parseLong(args[i], 0); 1348 writeData = true; 1349 } else if ("--history-create-events".equals(arg)) { 1350 i++; 1351 if (i >= args.length) { 1352 pw.println("Missing events argument for --history-create-events"); 1353 dumpHelp(pw); 1354 return; 1355 } 1356 final long events = ParseUtils.parseLong(args[i], 0); 1357 synchronized (mStats) { 1358 mStats.createFakeHistoryEvents(events); 1359 pw.println("Battery history create events started."); 1360 noOutput = true; 1361 } 1362 } else if ("-c".equals(arg)) { 1363 useCheckinFormat = true; 1364 flags |= BatteryStats.DUMP_INCLUDE_HISTORY; 1365 } else if ("--proto".equals(arg)) { 1366 toProto = true; 1367 } else if ("--charged".equals(arg)) { 1368 flags |= BatteryStats.DUMP_CHARGED_ONLY; 1369 } else if ("--daily".equals(arg)) { 1370 flags |= BatteryStats.DUMP_DAILY_ONLY; 1371 } else if ("--reset".equals(arg)) { 1372 synchronized (mStats) { 1373 mStats.resetAllStatsCmdLocked(); 1374 pw.println("Battery stats reset."); 1375 noOutput = true; 1376 } 1377 mWorker.scheduleSync("dump", BatteryExternalStatsWorker.UPDATE_ALL); 1378 } else if ("--write".equals(arg)) { 1379 syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL); 1380 synchronized (mStats) { 1381 mStats.writeSyncLocked(); 1382 pw.println("Battery stats written."); 1383 noOutput = true; 1384 } 1385 } else if ("--new-daily".equals(arg)) { 1386 synchronized (mStats) { 1387 mStats.recordDailyStatsLocked(); 1388 pw.println("New daily stats written."); 1389 noOutput = true; 1390 } 1391 } else if ("--read-daily".equals(arg)) { 1392 synchronized (mStats) { 1393 mStats.readDailyStatsLocked(); 1394 pw.println("Last daily stats read."); 1395 noOutput = true; 1396 } 1397 } else if ("--enable".equals(arg) || "enable".equals(arg)) { 1398 i = doEnableOrDisable(pw, i, args, true); 1399 if (i < 0) { 1400 return; 1401 } 1402 pw.println("Enabled: " + args[i]); 1403 return; 1404 } else if ("--disable".equals(arg) || "disable".equals(arg)) { 1405 i = doEnableOrDisable(pw, i, args, false); 1406 if (i < 0) { 1407 return; 1408 } 1409 pw.println("Disabled: " + args[i]); 1410 return; 1411 } else if ("-h".equals(arg)) { 1412 dumpHelp(pw); 1413 return; 1414 } else if ("--settings".equals(arg)) { 1415 dumpSettings(pw); 1416 return; 1417 } else if ("--cpu".equals(arg)) { 1418 dumpCpuStats(pw); 1419 return; 1420 } else if ("-a".equals(arg)) { 1421 flags |= BatteryStats.DUMP_VERBOSE; 1422 } else if (arg.length() > 0 && arg.charAt(0) == '-'){ 1423 pw.println("Unknown option: " + arg); 1424 dumpHelp(pw); 1425 return; 1426 } else { 1427 // Not an option, last argument must be a package name. 1428 try { 1429 reqUid = mContext.getPackageManager().getPackageUidAsUser(arg, 1430 UserHandle.getCallingUserId()); 1431 } catch (PackageManager.NameNotFoundException e) { 1432 pw.println("Unknown package: " + arg); 1433 dumpHelp(pw); 1434 return; 1435 } 1436 } 1437 } 1438 } 1439 if (noOutput) { 1440 return; 1441 } 1442 1443 long ident = Binder.clearCallingIdentity(); 1444 try { 1445 if (BatteryStatsHelper.checkWifiOnly(mContext)) { 1446 flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY; 1447 } 1448 // Fetch data from external sources and update the BatteryStatsImpl object with them. 1449 syncStats("dump", BatteryExternalStatsWorker.UPDATE_ALL); 1450 } finally { 1451 Binder.restoreCallingIdentity(ident); 1452 } 1453 1454 if (reqUid >= 0) { 1455 // By default, if the caller is only interested in a specific package, then 1456 // we only dump the aggregated data since charged. 1457 if ((flags&(BatteryStats.DUMP_HISTORY_ONLY|BatteryStats.DUMP_CHARGED_ONLY)) == 0) { 1458 flags |= BatteryStats.DUMP_CHARGED_ONLY; 1459 // Also if they are doing -c, we don't want history. 1460 flags &= ~BatteryStats.DUMP_INCLUDE_HISTORY; 1461 } 1462 } 1463 1464 if (toProto) { 1465 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications( 1466 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL); 1467 if (isRealCheckin) { 1468 // For a real checkin, first we want to prefer to use the last complete checkin 1469 // file if there is one. 1470 synchronized (mStats.mCheckinFile) { 1471 if (mStats.mCheckinFile.exists()) { 1472 try { 1473 byte[] raw = mStats.mCheckinFile.readFully(); 1474 if (raw != null) { 1475 Parcel in = Parcel.obtain(); 1476 in.unmarshall(raw, 0, raw.length); 1477 in.setDataPosition(0); 1478 BatteryStatsImpl checkinStats = new BatteryStatsImpl( 1479 null, mStats.mHandler, null, null, 1480 mUserManagerUserInfoProvider); 1481 checkinStats.readSummaryFromParcel(in); 1482 in.recycle(); 1483 checkinStats.dumpProtoLocked( 1484 mContext, fd, apps, flags, historyStart); 1485 mStats.mCheckinFile.delete(); 1486 return; 1487 } 1488 } catch (IOException | ParcelFormatException e) { 1489 Slog.w(TAG, "Failure reading checkin file " 1490 + mStats.mCheckinFile.getBaseFile(), e); 1491 } 1492 } 1493 } 1494 } 1495 if (DBG) Slog.d(TAG, "begin dumpProtoLocked from UID " + Binder.getCallingUid()); 1496 synchronized (mStats) { 1497 mStats.dumpProtoLocked(mContext, fd, apps, flags, historyStart); 1498 if (writeData) { 1499 mStats.writeAsyncLocked(); 1500 } 1501 } 1502 if (DBG) Slog.d(TAG, "end dumpProtoLocked"); 1503 } else if (useCheckinFormat) { 1504 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications( 1505 PackageManager.MATCH_ANY_USER | PackageManager.MATCH_ALL); 1506 if (isRealCheckin) { 1507 // For a real checkin, first we want to prefer to use the last complete checkin 1508 // file if there is one. 1509 synchronized (mStats.mCheckinFile) { 1510 if (mStats.mCheckinFile.exists()) { 1511 try { 1512 byte[] raw = mStats.mCheckinFile.readFully(); 1513 if (raw != null) { 1514 Parcel in = Parcel.obtain(); 1515 in.unmarshall(raw, 0, raw.length); 1516 in.setDataPosition(0); 1517 BatteryStatsImpl checkinStats = new BatteryStatsImpl( 1518 null, mStats.mHandler, null, null, 1519 mUserManagerUserInfoProvider); 1520 checkinStats.readSummaryFromParcel(in); 1521 in.recycle(); 1522 checkinStats.dumpCheckinLocked(mContext, pw, apps, flags, 1523 historyStart); 1524 mStats.mCheckinFile.delete(); 1525 return; 1526 } 1527 } catch (IOException | ParcelFormatException e) { 1528 Slog.w(TAG, "Failure reading checkin file " 1529 + mStats.mCheckinFile.getBaseFile(), e); 1530 } 1531 } 1532 } 1533 } 1534 if (DBG) Slog.d(TAG, "begin dumpCheckinLocked from UID " + Binder.getCallingUid()); 1535 synchronized (mStats) { 1536 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart); 1537 if (writeData) { 1538 mStats.writeAsyncLocked(); 1539 } 1540 } 1541 if (DBG) Slog.d(TAG, "end dumpCheckinLocked"); 1542 } else { 1543 if (DBG) Slog.d(TAG, "begin dumpLocked from UID " + Binder.getCallingUid()); 1544 synchronized (mStats) { 1545 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart); 1546 if (writeData) { 1547 mStats.writeAsyncLocked(); 1548 } 1549 } 1550 if (DBG) Slog.d(TAG, "end dumpLocked"); 1551 } 1552 } 1553 1554 /** 1555 * Gets a snapshot of cellular stats 1556 * @hide 1557 */ getCellularBatteryStats()1558 public CellularBatteryStats getCellularBatteryStats() { 1559 synchronized (mStats) { 1560 return mStats.getCellularBatteryStats(); 1561 } 1562 } 1563 1564 /** 1565 * Gets a snapshot of Wifi stats 1566 * @hide 1567 */ getWifiBatteryStats()1568 public WifiBatteryStats getWifiBatteryStats() { 1569 synchronized (mStats) { 1570 return mStats.getWifiBatteryStats(); 1571 } 1572 } 1573 1574 /** 1575 * Gets a snapshot of Gps stats 1576 * @hide 1577 */ getGpsBatteryStats()1578 public GpsBatteryStats getGpsBatteryStats() { 1579 synchronized (mStats) { 1580 return mStats.getGpsBatteryStats(); 1581 } 1582 } 1583 1584 /** 1585 * Gets a snapshot of the system health for a particular uid. 1586 */ 1587 @Override takeUidSnapshot(int requestUid)1588 public HealthStatsParceler takeUidSnapshot(int requestUid) { 1589 if (requestUid != Binder.getCallingUid()) { 1590 mContext.enforceCallingOrSelfPermission( 1591 android.Manifest.permission.BATTERY_STATS, null); 1592 } 1593 long ident = Binder.clearCallingIdentity(); 1594 try { 1595 if (shouldCollectExternalStats()) { 1596 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL); 1597 } 1598 synchronized (mStats) { 1599 return getHealthStatsForUidLocked(requestUid); 1600 } 1601 } catch (Exception ex) { 1602 Slog.w(TAG, "Crashed while writing for takeUidSnapshot(" + requestUid + ")", ex); 1603 throw ex; 1604 } finally { 1605 Binder.restoreCallingIdentity(ident); 1606 } 1607 } 1608 1609 /** 1610 * Gets a snapshot of the system health for a number of uids. 1611 */ 1612 @Override takeUidSnapshots(int[] requestUids)1613 public HealthStatsParceler[] takeUidSnapshots(int[] requestUids) { 1614 if (!onlyCaller(requestUids)) { 1615 mContext.enforceCallingOrSelfPermission( 1616 android.Manifest.permission.BATTERY_STATS, null); 1617 } 1618 long ident = Binder.clearCallingIdentity(); 1619 int i=-1; 1620 try { 1621 if (shouldCollectExternalStats()) { 1622 syncStats("get-health-stats-for-uids", BatteryExternalStatsWorker.UPDATE_ALL); 1623 } 1624 synchronized (mStats) { 1625 final int N = requestUids.length; 1626 final HealthStatsParceler[] results = new HealthStatsParceler[N]; 1627 for (i=0; i<N; i++) { 1628 results[i] = getHealthStatsForUidLocked(requestUids[i]); 1629 } 1630 return results; 1631 } 1632 } catch (Exception ex) { 1633 if (DBG) Slog.d(TAG, "Crashed while writing for takeUidSnapshots(" 1634 + Arrays.toString(requestUids) + ") i=" + i, ex); 1635 throw ex; 1636 } finally { 1637 Binder.restoreCallingIdentity(ident); 1638 } 1639 } 1640 shouldCollectExternalStats()1641 private boolean shouldCollectExternalStats() { 1642 return (SystemClock.elapsedRealtime() - mWorker.getLastCollectionTimeStamp()) 1643 > mStats.getExternalStatsCollectionRateLimitMs(); 1644 } 1645 1646 /** 1647 * Returns whether the Binder.getCallingUid is the only thing in requestUids. 1648 */ onlyCaller(int[] requestUids)1649 private static boolean onlyCaller(int[] requestUids) { 1650 final int caller = Binder.getCallingUid(); 1651 final int N = requestUids.length; 1652 for (int i=0; i<N; i++) { 1653 if (requestUids[i] != caller) { 1654 return false; 1655 } 1656 } 1657 return true; 1658 } 1659 1660 /** 1661 * Gets a HealthStatsParceler for the given uid. You should probably call 1662 * updateExternalStatsSync first. 1663 */ getHealthStatsForUidLocked(int requestUid)1664 HealthStatsParceler getHealthStatsForUidLocked(int requestUid) { 1665 final HealthStatsBatteryStatsWriter writer = new HealthStatsBatteryStatsWriter(); 1666 final HealthStatsWriter uidWriter = new HealthStatsWriter(UidHealthStats.CONSTANTS); 1667 final BatteryStats.Uid uid = mStats.getUidStats().get(requestUid); 1668 if (uid != null) { 1669 writer.writeUid(uidWriter, mStats, uid); 1670 } 1671 return new HealthStatsParceler(uidWriter); 1672 } 1673 1674 /** 1675 * Delay for sending ACTION_CHARGING after device is plugged in. 1676 * 1677 * @hide 1678 */ setChargingStateUpdateDelayMillis(int delayMillis)1679 public boolean setChargingStateUpdateDelayMillis(int delayMillis) { 1680 mContext.enforceCallingOrSelfPermission(android.Manifest.permission.POWER_SAVER, null); 1681 final long ident = Binder.clearCallingIdentity(); 1682 1683 try { 1684 final ContentResolver contentResolver = mContext.getContentResolver(); 1685 return Settings.Global.putLong(contentResolver, 1686 Settings.Global.BATTERY_CHARGING_STATE_UPDATE_DELAY, 1687 delayMillis); 1688 } finally { 1689 Binder.restoreCallingIdentity(ident); 1690 } 1691 } 1692 1693 } 1694