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