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