BatteryStatsService.java revision d953c53d3b04d772bb1b62ede1c2011641ca82b5
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 17package com.android.server.am; 18 19import android.bluetooth.BluetoothAdapter; 20import android.bluetooth.BluetoothHeadset; 21import android.bluetooth.BluetoothProfile; 22import android.content.Context; 23import android.content.pm.ApplicationInfo; 24import android.content.pm.PackageManager; 25import android.os.BatteryStats; 26import android.os.Binder; 27import android.os.Handler; 28import android.os.IBinder; 29import android.os.Parcel; 30import android.os.ParcelFileDescriptor; 31import android.os.PowerManagerInternal; 32import android.os.Process; 33import android.os.ServiceManager; 34import android.os.SystemClock; 35import android.os.UserHandle; 36import android.os.WorkSource; 37import android.telephony.SignalStrength; 38import android.telephony.TelephonyManager; 39import android.util.Slog; 40 41import com.android.internal.app.IBatteryStats; 42import com.android.internal.os.BatteryStatsHelper; 43import com.android.internal.os.BatteryStatsImpl; 44import com.android.internal.os.PowerProfile; 45import com.android.server.LocalServices; 46 47import java.io.File; 48import java.io.FileDescriptor; 49import java.io.FileOutputStream; 50import java.io.IOException; 51import java.io.PrintWriter; 52import java.util.List; 53 54/** 55 * All information we are collecting about things that can happen that impact 56 * battery life. 57 */ 58public final class BatteryStatsService extends IBatteryStats.Stub 59 implements PowerManagerInternal.LowPowerModeListener { 60 static final String TAG = "BatteryStatsService"; 61 62 static IBatteryStats sService; 63 64 final BatteryStatsImpl mStats; 65 Context mContext; 66 private boolean mBluetoothPendingStats; 67 private BluetoothHeadset mBluetoothHeadset; 68 PowerManagerInternal mPowerManagerInternal; 69 70 BatteryStatsService(File systemDir, Handler handler) { 71 mStats = new BatteryStatsImpl(systemDir, handler); 72 } 73 74 public void publish(Context context) { 75 mContext = context; 76 ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder()); 77 mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps()); 78 mStats.setRadioScanningTimeout(mContext.getResources().getInteger( 79 com.android.internal.R.integer.config_radioScanningTimeout) 80 * 1000L); 81 } 82 83 /** 84 * At the time when the constructor runs, the power manager has not yet been 85 * initialized. So we initialize the low power observer later. 86 */ 87 public void initPowerManagement() { 88 mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class); 89 mPowerManagerInternal.registerLowPowerModeObserver(this); 90 mStats.noteLowPowerMode(mPowerManagerInternal.getLowPowerModeEnabled()); 91 (new WakeupReasonThread()).start(); 92 } 93 94 public void shutdown() { 95 Slog.w("BatteryStats", "Writing battery stats before shutdown..."); 96 synchronized (mStats) { 97 mStats.shutdownLocked(); 98 } 99 } 100 101 public static IBatteryStats getService() { 102 if (sService != null) { 103 return sService; 104 } 105 IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME); 106 sService = asInterface(b); 107 return sService; 108 } 109 110 @Override 111 public void onLowPowerModeChanged(boolean enabled) { 112 synchronized (mStats) { 113 mStats.noteLowPowerMode(enabled); 114 } 115 } 116 117 /** 118 * @return the current statistics object, which may be modified 119 * to reflect events that affect battery usage. You must lock the 120 * stats object before doing anything with it. 121 */ 122 public BatteryStatsImpl getActiveStatistics() { 123 return mStats; 124 } 125 126 public byte[] getStatistics() { 127 mContext.enforceCallingPermission( 128 android.Manifest.permission.BATTERY_STATS, null); 129 //Slog.i("foo", "SENDING BATTERY INFO:"); 130 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM)); 131 Parcel out = Parcel.obtain(); 132 mStats.writeToParcel(out, 0); 133 byte[] data = out.marshall(); 134 out.recycle(); 135 return data; 136 } 137 138 public ParcelFileDescriptor getStatisticsStream() { 139 mContext.enforceCallingPermission( 140 android.Manifest.permission.BATTERY_STATS, null); 141 //Slog.i("foo", "SENDING BATTERY INFO:"); 142 //mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM)); 143 Parcel out = Parcel.obtain(); 144 mStats.writeToParcel(out, 0); 145 byte[] data = out.marshall(); 146 out.recycle(); 147 try { 148 return ParcelFileDescriptor.fromData(data, "battery-stats"); 149 } catch (IOException e) { 150 Slog.w(TAG, "Unable to create shared memory", e); 151 return null; 152 } 153 } 154 155 public long computeBatteryTimeRemaining() { 156 synchronized (mStats) { 157 long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime()); 158 return time >= 0 ? (time/1000) : time; 159 } 160 } 161 162 public long computeChargeTimeRemaining() { 163 synchronized (mStats) { 164 long time = mStats.computeChargeTimeRemaining(SystemClock.elapsedRealtime()); 165 return time >= 0 ? (time/1000) : time; 166 } 167 } 168 169 public void addIsolatedUid(int isolatedUid, int appUid) { 170 enforceCallingPermission(); 171 synchronized (mStats) { 172 mStats.addIsolatedUidLocked(isolatedUid, appUid); 173 } 174 } 175 176 public void removeIsolatedUid(int isolatedUid, int appUid) { 177 enforceCallingPermission(); 178 synchronized (mStats) { 179 mStats.removeIsolatedUidLocked(isolatedUid, appUid); 180 } 181 } 182 183 public void noteEvent(int code, String name, int uid) { 184 enforceCallingPermission(); 185 synchronized (mStats) { 186 mStats.noteEventLocked(code, name, uid); 187 } 188 } 189 190 public void noteProcessStart(String name, int uid) { 191 enforceCallingPermission(); 192 synchronized (mStats) { 193 mStats.noteProcessStartLocked(name, uid); 194 } 195 } 196 197 public void noteProcessState(String name, int uid, int state) { 198 enforceCallingPermission(); 199 synchronized (mStats) { 200 mStats.noteProcessStateLocked(name, uid, state); 201 } 202 } 203 204 public void noteProcessFinish(String name, int uid) { 205 enforceCallingPermission(); 206 synchronized (mStats) { 207 mStats.noteProcessFinishLocked(name, uid); 208 } 209 } 210 211 public void noteSyncStart(String name, int uid) { 212 enforceCallingPermission(); 213 synchronized (mStats) { 214 mStats.noteSyncStartLocked(name, uid); 215 } 216 } 217 218 public void noteSyncFinish(String name, int uid) { 219 enforceCallingPermission(); 220 synchronized (mStats) { 221 mStats.noteSyncFinishLocked(name, uid); 222 } 223 } 224 225 public void noteJobStart(String name, int uid) { 226 enforceCallingPermission(); 227 synchronized (mStats) { 228 mStats.noteJobStartLocked(name, uid); 229 } 230 } 231 232 public void noteJobFinish(String name, int uid) { 233 enforceCallingPermission(); 234 synchronized (mStats) { 235 mStats.noteJobFinishLocked(name, uid); 236 } 237 } 238 239 public void noteStartWakelock(int uid, int pid, String name, String historyName, int type, 240 boolean unimportantForLogging) { 241 enforceCallingPermission(); 242 synchronized (mStats) { 243 mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging, 244 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); 245 } 246 } 247 248 public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) { 249 enforceCallingPermission(); 250 synchronized (mStats) { 251 mStats.noteStopWakeLocked(uid, pid, name, historyName, type, 252 SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()); 253 } 254 } 255 256 public void noteStartWakelockFromSource(WorkSource ws, int pid, String name, 257 String historyName, int type, boolean unimportantForLogging) { 258 enforceCallingPermission(); 259 synchronized (mStats) { 260 mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName, 261 type, unimportantForLogging); 262 } 263 } 264 265 public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name, 266 String historyName, int type, WorkSource newWs, int newPid, String newName, 267 String newHistoryName, int newType, boolean newUnimportantForLogging) { 268 enforceCallingPermission(); 269 synchronized (mStats) { 270 mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type, 271 newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging); 272 } 273 } 274 275 public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName, 276 int type) { 277 enforceCallingPermission(); 278 synchronized (mStats) { 279 mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type); 280 } 281 } 282 283 public void noteStartSensor(int uid, int sensor) { 284 enforceCallingPermission(); 285 synchronized (mStats) { 286 mStats.noteStartSensorLocked(uid, sensor); 287 } 288 } 289 290 public void noteStopSensor(int uid, int sensor) { 291 enforceCallingPermission(); 292 synchronized (mStats) { 293 mStats.noteStopSensorLocked(uid, sensor); 294 } 295 } 296 297 public void noteVibratorOn(int uid, long durationMillis) { 298 enforceCallingPermission(); 299 synchronized (mStats) { 300 mStats.noteVibratorOnLocked(uid, durationMillis); 301 } 302 } 303 304 public void noteVibratorOff(int uid) { 305 enforceCallingPermission(); 306 synchronized (mStats) { 307 mStats.noteVibratorOffLocked(uid); 308 } 309 } 310 311 public void noteStartGps(int uid) { 312 enforceCallingPermission(); 313 synchronized (mStats) { 314 mStats.noteStartGpsLocked(uid); 315 } 316 } 317 318 public void noteStopGps(int uid) { 319 enforceCallingPermission(); 320 synchronized (mStats) { 321 mStats.noteStopGpsLocked(uid); 322 } 323 } 324 325 public void noteScreenState(int state) { 326 enforceCallingPermission(); 327 synchronized (mStats) { 328 mStats.noteScreenStateLocked(state); 329 } 330 } 331 332 public void noteScreenBrightness(int brightness) { 333 enforceCallingPermission(); 334 synchronized (mStats) { 335 mStats.noteScreenBrightnessLocked(brightness); 336 } 337 } 338 339 public void noteUserActivity(int uid, int event) { 340 enforceCallingPermission(); 341 synchronized (mStats) { 342 mStats.noteUserActivityLocked(uid, event); 343 } 344 } 345 346 public void noteInteractive(boolean interactive) { 347 enforceCallingPermission(); 348 synchronized (mStats) { 349 mStats.noteInteractiveLocked(interactive); 350 } 351 } 352 353 public void noteMobileRadioPowerState(int powerState, long timestampNs) { 354 enforceCallingPermission(); 355 synchronized (mStats) { 356 mStats.noteMobileRadioPowerState(powerState, timestampNs); 357 } 358 } 359 360 public void notePhoneOn() { 361 enforceCallingPermission(); 362 synchronized (mStats) { 363 mStats.notePhoneOnLocked(); 364 } 365 } 366 367 public void notePhoneOff() { 368 enforceCallingPermission(); 369 synchronized (mStats) { 370 mStats.notePhoneOffLocked(); 371 } 372 } 373 374 public void notePhoneSignalStrength(SignalStrength signalStrength) { 375 enforceCallingPermission(); 376 synchronized (mStats) { 377 mStats.notePhoneSignalStrengthLocked(signalStrength); 378 } 379 } 380 381 public void notePhoneDataConnectionState(int dataType, boolean hasData) { 382 enforceCallingPermission(); 383 synchronized (mStats) { 384 mStats.notePhoneDataConnectionStateLocked(dataType, hasData); 385 } 386 } 387 388 public void notePhoneState(int state) { 389 enforceCallingPermission(); 390 int simState = TelephonyManager.getDefault().getSimState(); 391 synchronized (mStats) { 392 mStats.notePhoneStateLocked(state, simState); 393 } 394 } 395 396 public void noteWifiOn() { 397 enforceCallingPermission(); 398 synchronized (mStats) { 399 mStats.noteWifiOnLocked(); 400 } 401 } 402 403 public void noteWifiOff() { 404 enforceCallingPermission(); 405 synchronized (mStats) { 406 mStats.noteWifiOffLocked(); 407 } 408 } 409 410 public void noteStartAudio(int uid) { 411 enforceCallingPermission(); 412 synchronized (mStats) { 413 mStats.noteAudioOnLocked(uid); 414 } 415 } 416 417 public void noteStopAudio(int uid) { 418 enforceCallingPermission(); 419 synchronized (mStats) { 420 mStats.noteAudioOffLocked(uid); 421 } 422 } 423 424 public void noteStartVideo(int uid) { 425 enforceCallingPermission(); 426 synchronized (mStats) { 427 mStats.noteVideoOnLocked(uid); 428 } 429 } 430 431 public void noteStopVideo(int uid) { 432 enforceCallingPermission(); 433 synchronized (mStats) { 434 mStats.noteVideoOffLocked(uid); 435 } 436 } 437 438 public void noteResetAudio() { 439 enforceCallingPermission(); 440 synchronized (mStats) { 441 mStats.noteResetAudioLocked(); 442 } 443 } 444 445 public void noteResetVideo() { 446 enforceCallingPermission(); 447 synchronized (mStats) { 448 mStats.noteResetVideoLocked(); 449 } 450 } 451 452 public void noteFlashlightOn() { 453 enforceCallingPermission(); 454 synchronized (mStats) { 455 mStats.noteFlashlightOnLocked(); 456 } 457 } 458 459 public void noteFlashlightOff() { 460 enforceCallingPermission(); 461 synchronized (mStats) { 462 mStats.noteFlashlightOffLocked(); 463 } 464 } 465 466 public void noteWifiRunning(WorkSource ws) { 467 enforceCallingPermission(); 468 synchronized (mStats) { 469 mStats.noteWifiRunningLocked(ws); 470 } 471 } 472 473 public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) { 474 enforceCallingPermission(); 475 synchronized (mStats) { 476 mStats.noteWifiRunningChangedLocked(oldWs, newWs); 477 } 478 } 479 480 public void noteWifiStopped(WorkSource ws) { 481 enforceCallingPermission(); 482 synchronized (mStats) { 483 mStats.noteWifiStoppedLocked(ws); 484 } 485 } 486 487 public void noteWifiState(int wifiState, String accessPoint) { 488 enforceCallingPermission(); 489 synchronized (mStats) { 490 mStats.noteWifiStateLocked(wifiState, accessPoint); 491 } 492 } 493 494 public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) { 495 enforceCallingPermission(); 496 synchronized (mStats) { 497 mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth); 498 } 499 } 500 501 public void noteWifiRssiChanged(int newRssi) { 502 enforceCallingPermission(); 503 synchronized (mStats) { 504 mStats.noteWifiRssiChangedLocked(newRssi); 505 } 506 } 507 508 public void noteBluetoothOn() { 509 enforceCallingPermission(); 510 BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter(); 511 if (adapter != null) { 512 adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener, 513 BluetoothProfile.HEADSET); 514 } 515 synchronized (mStats) { 516 if (mBluetoothHeadset != null) { 517 mStats.noteBluetoothOnLocked(); 518 mStats.setBtHeadset(mBluetoothHeadset); 519 } else { 520 mBluetoothPendingStats = true; 521 } 522 } 523 } 524 525 private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener = 526 new BluetoothProfile.ServiceListener() { 527 public void onServiceConnected(int profile, BluetoothProfile proxy) { 528 mBluetoothHeadset = (BluetoothHeadset) proxy; 529 synchronized (mStats) { 530 if (mBluetoothPendingStats) { 531 mStats.noteBluetoothOnLocked(); 532 mStats.setBtHeadset(mBluetoothHeadset); 533 mBluetoothPendingStats = false; 534 } 535 } 536 } 537 538 public void onServiceDisconnected(int profile) { 539 mBluetoothHeadset = null; 540 } 541 }; 542 543 public void noteBluetoothOff() { 544 enforceCallingPermission(); 545 synchronized (mStats) { 546 mBluetoothPendingStats = false; 547 mStats.noteBluetoothOffLocked(); 548 } 549 } 550 551 public void noteBluetoothState(int bluetoothState) { 552 enforceCallingPermission(); 553 synchronized (mStats) { 554 mStats.noteBluetoothStateLocked(bluetoothState); 555 } 556 } 557 558 public void noteFullWifiLockAcquired(int uid) { 559 enforceCallingPermission(); 560 synchronized (mStats) { 561 mStats.noteFullWifiLockAcquiredLocked(uid); 562 } 563 } 564 565 public void noteFullWifiLockReleased(int uid) { 566 enforceCallingPermission(); 567 synchronized (mStats) { 568 mStats.noteFullWifiLockReleasedLocked(uid); 569 } 570 } 571 572 public void noteWifiScanStarted(int uid) { 573 enforceCallingPermission(); 574 synchronized (mStats) { 575 mStats.noteWifiScanStartedLocked(uid); 576 } 577 } 578 579 public void noteWifiScanStopped(int uid) { 580 enforceCallingPermission(); 581 synchronized (mStats) { 582 mStats.noteWifiScanStoppedLocked(uid); 583 } 584 } 585 586 public void noteWifiMulticastEnabled(int uid) { 587 enforceCallingPermission(); 588 synchronized (mStats) { 589 mStats.noteWifiMulticastEnabledLocked(uid); 590 } 591 } 592 593 public void noteWifiMulticastDisabled(int uid) { 594 enforceCallingPermission(); 595 synchronized (mStats) { 596 mStats.noteWifiMulticastDisabledLocked(uid); 597 } 598 } 599 600 public void noteFullWifiLockAcquiredFromSource(WorkSource ws) { 601 enforceCallingPermission(); 602 synchronized (mStats) { 603 mStats.noteFullWifiLockAcquiredFromSourceLocked(ws); 604 } 605 } 606 607 public void noteFullWifiLockReleasedFromSource(WorkSource ws) { 608 enforceCallingPermission(); 609 synchronized (mStats) { 610 mStats.noteFullWifiLockReleasedFromSourceLocked(ws); 611 } 612 } 613 614 public void noteWifiScanStartedFromSource(WorkSource ws) { 615 enforceCallingPermission(); 616 synchronized (mStats) { 617 mStats.noteWifiScanStartedFromSourceLocked(ws); 618 } 619 } 620 621 public void noteWifiScanStoppedFromSource(WorkSource ws) { 622 enforceCallingPermission(); 623 synchronized (mStats) { 624 mStats.noteWifiScanStoppedFromSourceLocked(ws); 625 } 626 } 627 628 public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) { 629 enforceCallingPermission(); 630 synchronized (mStats) { 631 mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph); 632 } 633 } 634 635 public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) { 636 enforceCallingPermission(); 637 synchronized (mStats) { 638 mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws); 639 } 640 } 641 642 public void noteWifiMulticastEnabledFromSource(WorkSource ws) { 643 enforceCallingPermission(); 644 synchronized (mStats) { 645 mStats.noteWifiMulticastEnabledFromSourceLocked(ws); 646 } 647 } 648 649 public void noteWifiMulticastDisabledFromSource(WorkSource ws) { 650 enforceCallingPermission(); 651 synchronized (mStats) { 652 mStats.noteWifiMulticastDisabledFromSourceLocked(ws); 653 } 654 } 655 656 @Override 657 public void noteNetworkInterfaceType(String iface, int type) { 658 enforceCallingPermission(); 659 synchronized (mStats) { 660 mStats.noteNetworkInterfaceTypeLocked(iface, type); 661 } 662 } 663 664 @Override 665 public void noteNetworkStatsEnabled() { 666 enforceCallingPermission(); 667 synchronized (mStats) { 668 mStats.noteNetworkStatsEnabledLocked(); 669 } 670 } 671 672 public boolean isOnBattery() { 673 return mStats.isOnBattery(); 674 } 675 676 public void setBatteryState(int status, int health, int plugType, int level, 677 int temp, int volt) { 678 enforceCallingPermission(); 679 mStats.setBatteryState(status, health, plugType, level, temp, volt); 680 } 681 682 public long getAwakeTimeBattery() { 683 mContext.enforceCallingOrSelfPermission( 684 android.Manifest.permission.BATTERY_STATS, null); 685 return mStats.getAwakeTimeBattery(); 686 } 687 688 public long getAwakeTimePlugged() { 689 mContext.enforceCallingOrSelfPermission( 690 android.Manifest.permission.BATTERY_STATS, null); 691 return mStats.getAwakeTimePlugged(); 692 } 693 694 public void enforceCallingPermission() { 695 if (Binder.getCallingPid() == Process.myPid()) { 696 return; 697 } 698 mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS, 699 Binder.getCallingPid(), Binder.getCallingUid(), null); 700 } 701 702 final class WakeupReasonThread extends Thread { 703 final int[] mIrqs = new int[32]; 704 final String[] mReasons = new String[32]; 705 706 WakeupReasonThread() { 707 super("BatteryStats_wakeupReason"); 708 } 709 710 public void run() { 711 Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND); 712 713 try { 714 int num; 715 while ((num=nativeWaitWakeup(mIrqs, mReasons)) >= 0) { 716 synchronized (mStats) { 717 if (num > 0) { 718 for (int i=0; i<num; i++) { 719 mStats.noteWakeupReasonLocked(mReasons[i]); 720 } 721 } else { 722 mStats.noteWakeupReasonLocked("unknown"); 723 } 724 } 725 } 726 } catch (RuntimeException e) { 727 Slog.e(TAG, "Failure reading wakeup reasons", e); 728 } 729 } 730 } 731 732 private static native int nativeWaitWakeup(int[] outIrqs, String[] outReasons); 733 734 private void dumpHelp(PrintWriter pw) { 735 pw.println("Battery stats (batterystats) dump options:"); 736 pw.println(" [--checkin] [--history] [--history-start] [--unplugged] [--charged] [-c]"); 737 pw.println(" [--reset] [--write] [-h] [<package.name>]"); 738 pw.println(" --checkin: format output for a checkin report."); 739 pw.println(" --history: show only history data."); 740 pw.println(" --history-start <num>: show only history data starting at given time offset."); 741 pw.println(" --unplugged: only output data since last unplugged."); 742 pw.println(" --charged: only output data since last charged."); 743 pw.println(" --reset: reset the stats, clearing all current data."); 744 pw.println(" --write: force write current collected stats to disk."); 745 pw.println(" <package.name>: optional name of package to filter output by."); 746 pw.println(" -h: print this help text."); 747 pw.println("Battery stats (batterystats) commands:"); 748 pw.println(" enable|disable <option>"); 749 pw.println(" Enable or disable a running option. Option state is not saved across boots."); 750 pw.println(" Options are:"); 751 pw.println(" full-history: include additional detailed events in battery history:"); 752 pw.println(" wake_lock_in and proc events"); 753 pw.println(" no-auto-reset: don't automatically reset stats when unplugged"); 754 } 755 756 private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) { 757 i++; 758 if (i >= args.length) { 759 pw.println("Missing option argument for " + (enable ? "--enable" : "--disable")); 760 dumpHelp(pw); 761 return -1; 762 } 763 if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) { 764 synchronized (mStats) { 765 mStats.setRecordAllHistoryLocked(enable); 766 } 767 } else if ("no-auto-reset".equals(args[i])) { 768 synchronized (mStats) { 769 mStats.setNoAutoReset(enable); 770 } 771 } else { 772 pw.println("Unknown enable/disable option: " + args[i]); 773 dumpHelp(pw); 774 return -1; 775 } 776 return i; 777 } 778 779 @Override 780 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 781 if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP) 782 != PackageManager.PERMISSION_GRANTED) { 783 pw.println("Permission Denial: can't dump BatteryStats from from pid=" 784 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid() 785 + " without permission " + android.Manifest.permission.DUMP); 786 return; 787 } 788 789 int flags = 0; 790 boolean useCheckinFormat = false; 791 boolean isRealCheckin = false; 792 boolean noOutput = false; 793 boolean writeData = false; 794 long historyStart = -1; 795 int reqUid = -1; 796 if (args != null) { 797 for (int i=0; i<args.length; i++) { 798 String arg = args[i]; 799 if ("--checkin".equals(arg)) { 800 useCheckinFormat = true; 801 isRealCheckin = true; 802 } else if ("--history".equals(arg)) { 803 flags |= BatteryStats.DUMP_HISTORY_ONLY; 804 } else if ("--history-start".equals(arg)) { 805 flags |= BatteryStats.DUMP_HISTORY_ONLY; 806 i++; 807 if (i >= args.length) { 808 pw.println("Missing time argument for --history-since"); 809 dumpHelp(pw); 810 return; 811 } 812 historyStart = Long.parseLong(args[i]); 813 writeData = true; 814 } else if ("-c".equals(arg)) { 815 useCheckinFormat = true; 816 flags |= BatteryStats.DUMP_INCLUDE_HISTORY; 817 } else if ("--unplugged".equals(arg)) { 818 flags |= BatteryStats.DUMP_UNPLUGGED_ONLY; 819 } else if ("--charged".equals(arg)) { 820 flags |= BatteryStats.DUMP_CHARGED_ONLY; 821 } else if ("--reset".equals(arg)) { 822 synchronized (mStats) { 823 mStats.resetAllStatsCmdLocked(); 824 pw.println("Battery stats reset."); 825 noOutput = true; 826 } 827 } else if ("--write".equals(arg)) { 828 synchronized (mStats) { 829 mStats.writeSyncLocked(); 830 pw.println("Battery stats written."); 831 noOutput = true; 832 } 833 } else if ("--enable".equals(arg) || "enable".equals(arg)) { 834 i = doEnableOrDisable(pw, i, args, true); 835 if (i < 0) { 836 return; 837 } 838 pw.println("Enabled: " + args[i]); 839 return; 840 } else if ("--disable".equals(arg) || "disable".equals(arg)) { 841 i = doEnableOrDisable(pw, i, args, false); 842 if (i < 0) { 843 return; 844 } 845 pw.println("Disabled: " + args[i]); 846 return; 847 } else if ("-h".equals(arg)) { 848 dumpHelp(pw); 849 return; 850 } else if ("-a".equals(arg)) { 851 flags |= BatteryStats.DUMP_VERBOSE; 852 } else if (arg.length() > 0 && arg.charAt(0) == '-'){ 853 pw.println("Unknown option: " + arg); 854 dumpHelp(pw); 855 return; 856 } else { 857 // Not an option, last argument must be a package name. 858 try { 859 reqUid = mContext.getPackageManager().getPackageUid(arg, 860 UserHandle.getCallingUserId()); 861 } catch (PackageManager.NameNotFoundException e) { 862 pw.println("Unknown package: " + arg); 863 dumpHelp(pw); 864 return; 865 } 866 } 867 } 868 } 869 if (noOutput) { 870 return; 871 } 872 if (BatteryStatsHelper.checkWifiOnly(mContext)) { 873 flags |= BatteryStats.DUMP_DEVICE_WIFI_ONLY; 874 } 875 if (useCheckinFormat) { 876 List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0); 877 if (isRealCheckin) { 878 // For a real checkin, first we want to prefer to use the last complete checkin 879 // file if there is one. 880 synchronized (mStats.mCheckinFile) { 881 if (mStats.mCheckinFile.exists()) { 882 try { 883 byte[] raw = mStats.mCheckinFile.readFully(); 884 if (raw != null) { 885 Parcel in = Parcel.obtain(); 886 in.unmarshall(raw, 0, raw.length); 887 in.setDataPosition(0); 888 BatteryStatsImpl checkinStats = new BatteryStatsImpl( 889 null, mStats.mHandler); 890 checkinStats.readSummaryFromParcel(in); 891 in.recycle(); 892 checkinStats.dumpCheckinLocked(mContext, pw, apps, flags, 893 historyStart); 894 mStats.mCheckinFile.delete(); 895 return; 896 } 897 } catch (IOException e) { 898 Slog.w(TAG, "Failure reading checkin file " 899 + mStats.mCheckinFile.getBaseFile(), e); 900 } 901 } 902 } 903 } 904 synchronized (mStats) { 905 mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart); 906 if (writeData) { 907 mStats.writeAsyncLocked(); 908 } 909 } 910 } else { 911 synchronized (mStats) { 912 mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart); 913 if (writeData) { 914 mStats.writeAsyncLocked(); 915 } 916 } 917 } 918 } 919} 920