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