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