blob: d8da7006398b80972167ee40663d294b67dac913 [file] [log] [blame]
/*
* Copyright (C) 2006-2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.server.am;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothHeadset;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.BatteryStats;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.WorkSource;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Slog;
import com.android.internal.app.IBatteryStats;
import com.android.internal.os.BatteryStatsImpl;
import com.android.internal.os.PowerProfile;
import com.android.server.LocalServices;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
/**
* All information we are collecting about things that can happen that impact
* battery life.
*/
public final class BatteryStatsService extends IBatteryStats.Stub
implements PowerManagerInternal.LowPowerModeListener {
static final String TAG = "BatteryStatsService";
static IBatteryStats sService;
final BatteryStatsImpl mStats;
Context mContext;
private boolean mBluetoothPendingStats;
private BluetoothHeadset mBluetoothHeadset;
PowerManagerInternal mPowerManagerInternal;
BatteryStatsService(File systemDir, Handler handler) {
mStats = new BatteryStatsImpl(systemDir, handler);
}
public void publish(Context context) {
mContext = context;
ServiceManager.addService(BatteryStats.SERVICE_NAME, asBinder());
mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
com.android.internal.R.integer.config_radioScanningTimeout)
* 1000L);
}
/**
* At the time when the constructor runs, the power manager has not yet been
* initialized. So we initialize the low power observer later.
*/
public void initPowerManagement() {
mPowerManagerInternal = LocalServices.getService(PowerManagerInternal.class);
mPowerManagerInternal.registerLowPowerModeObserver(this);
mStats.noteLowPowerMode(mPowerManagerInternal.getLowPowerModeEnabled());
(new WakeupReasonThread()).start();
}
public void shutdown() {
Slog.w("BatteryStats", "Writing battery stats before shutdown...");
synchronized (mStats) {
mStats.shutdownLocked();
}
}
public static IBatteryStats getService() {
if (sService != null) {
return sService;
}
IBinder b = ServiceManager.getService(BatteryStats.SERVICE_NAME);
sService = asInterface(b);
return sService;
}
@Override
public void onLowPowerModeChanged(boolean enabled) {
synchronized (mStats) {
mStats.noteLowPowerMode(enabled);
}
}
/**
* @return the current statistics object, which may be modified
* to reflect events that affect battery usage. You must lock the
* stats object before doing anything with it.
*/
public BatteryStatsImpl getActiveStatistics() {
return mStats;
}
public byte[] getStatistics() {
mContext.enforceCallingPermission(
android.Manifest.permission.BATTERY_STATS, null);
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
mStats.writeToParcel(out, 0);
byte[] data = out.marshall();
out.recycle();
return data;
}
public ParcelFileDescriptor getStatisticsStream() {
mContext.enforceCallingPermission(
android.Manifest.permission.BATTERY_STATS, null);
//Slog.i("foo", "SENDING BATTERY INFO:");
//mStats.dumpLocked(new LogPrinter(Log.INFO, "foo", Log.LOG_ID_SYSTEM));
Parcel out = Parcel.obtain();
mStats.writeToParcel(out, 0);
byte[] data = out.marshall();
out.recycle();
try {
return ParcelFileDescriptor.fromData(data, "battery-stats");
} catch (IOException e) {
Slog.w(TAG, "Unable to create shared memory", e);
return null;
}
}
public long computeBatteryTimeRemaining() {
synchronized (mStats) {
long time = mStats.computeBatteryTimeRemaining(SystemClock.elapsedRealtime());
return time >= 0 ? (time/1000) : time;
}
}
public long computeChargeTimeRemaining() {
synchronized (mStats) {
long time = mStats.computeChargeTimeRemaining(SystemClock.elapsedRealtime());
return time >= 0 ? (time/1000) : time;
}
}
public void addIsolatedUid(int isolatedUid, int appUid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.addIsolatedUidLocked(isolatedUid, appUid);
}
}
public void removeIsolatedUid(int isolatedUid, int appUid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.removeIsolatedUidLocked(isolatedUid, appUid);
}
}
public void noteEvent(int code, String name, int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteEventLocked(code, name, uid);
}
}
public void noteProcessStart(String name, int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteProcessStartLocked(name, uid);
}
}
public void noteProcessState(String name, int uid, int state) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteProcessStateLocked(name, uid, state);
}
}
public void noteProcessFinish(String name, int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteProcessFinishLocked(name, uid);
}
}
public void noteSyncStart(String name, int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteSyncStartLocked(name, uid);
}
}
public void noteSyncFinish(String name, int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteSyncFinishLocked(name, uid);
}
}
public void noteJobStart(String name, int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteJobStartLocked(name, uid);
}
}
public void noteJobFinish(String name, int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteJobFinishLocked(name, uid);
}
}
public void noteStartWakelock(int uid, int pid, String name, String historyName, int type,
boolean unimportantForLogging) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStartWakeLocked(uid, pid, name, historyName, type, unimportantForLogging,
SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
}
}
public void noteStopWakelock(int uid, int pid, String name, String historyName, int type) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStopWakeLocked(uid, pid, name, historyName, type,
SystemClock.elapsedRealtime(), SystemClock.uptimeMillis());
}
}
public void noteStartWakelockFromSource(WorkSource ws, int pid, String name,
String historyName, int type, boolean unimportantForLogging) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStartWakeFromSourceLocked(ws, pid, name, historyName,
type, unimportantForLogging);
}
}
public void noteChangeWakelockFromSource(WorkSource ws, int pid, String name,
String historyName, int type, WorkSource newWs, int newPid, String newName,
String newHistoryName, int newType, boolean newUnimportantForLogging) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteChangeWakelockFromSourceLocked(ws, pid, name, historyName, type,
newWs, newPid, newName, newHistoryName, newType, newUnimportantForLogging);
}
}
public void noteStopWakelockFromSource(WorkSource ws, int pid, String name, String historyName,
int type) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStopWakeFromSourceLocked(ws, pid, name, historyName, type);
}
}
public void noteStartSensor(int uid, int sensor) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStartSensorLocked(uid, sensor);
}
}
public void noteStopSensor(int uid, int sensor) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStopSensorLocked(uid, sensor);
}
}
public void noteVibratorOn(int uid, long durationMillis) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteVibratorOnLocked(uid, durationMillis);
}
}
public void noteVibratorOff(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteVibratorOffLocked(uid);
}
}
public void noteStartGps(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStartGpsLocked(uid);
}
}
public void noteStopGps(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteStopGpsLocked(uid);
}
}
public void noteScreenState(int state) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteScreenStateLocked(state);
}
}
public void noteScreenBrightness(int brightness) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteScreenBrightnessLocked(brightness);
}
}
public void noteUserActivity(int uid, int event) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteUserActivityLocked(uid, event);
}
}
public void noteInteractive(boolean interactive) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteInteractiveLocked(interactive);
}
}
public void noteMobileRadioPowerState(int powerState, long timestampNs) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteMobileRadioPowerState(powerState, timestampNs);
}
}
public void notePhoneOn() {
enforceCallingPermission();
synchronized (mStats) {
mStats.notePhoneOnLocked();
}
}
public void notePhoneOff() {
enforceCallingPermission();
synchronized (mStats) {
mStats.notePhoneOffLocked();
}
}
public void notePhoneSignalStrength(SignalStrength signalStrength) {
enforceCallingPermission();
synchronized (mStats) {
mStats.notePhoneSignalStrengthLocked(signalStrength);
}
}
public void notePhoneDataConnectionState(int dataType, boolean hasData) {
enforceCallingPermission();
synchronized (mStats) {
mStats.notePhoneDataConnectionStateLocked(dataType, hasData);
}
}
public void notePhoneState(int state) {
enforceCallingPermission();
int simState = TelephonyManager.getDefault().getSimState();
synchronized (mStats) {
mStats.notePhoneStateLocked(state, simState);
}
}
public void noteWifiOn() {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiOnLocked();
}
}
public void noteWifiOff() {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiOffLocked();
}
}
public void noteStartAudio(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteAudioOnLocked(uid);
}
}
public void noteStopAudio(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteAudioOffLocked(uid);
}
}
public void noteStartVideo(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteVideoOnLocked(uid);
}
}
public void noteStopVideo(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteVideoOffLocked(uid);
}
}
public void noteResetAudio() {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteResetAudioLocked();
}
}
public void noteResetVideo() {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteResetVideoLocked();
}
}
public void noteFlashlightOn() {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteFlashlightOnLocked();
}
}
public void noteFlashlightOff() {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteFlashlightOffLocked();
}
}
public void noteWifiRunning(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiRunningLocked(ws);
}
}
public void noteWifiRunningChanged(WorkSource oldWs, WorkSource newWs) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiRunningChangedLocked(oldWs, newWs);
}
}
public void noteWifiStopped(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiStoppedLocked(ws);
}
}
public void noteWifiState(int wifiState, String accessPoint) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiStateLocked(wifiState, accessPoint);
}
}
public void noteWifiSupplicantStateChanged(int supplState, boolean failedAuth) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiSupplicantStateChangedLocked(supplState, failedAuth);
}
}
public void noteWifiRssiChanged(int newRssi) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiRssiChangedLocked(newRssi);
}
}
public void noteBluetoothOn() {
enforceCallingPermission();
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) {
adapter.getProfileProxy(mContext, mBluetoothProfileServiceListener,
BluetoothProfile.HEADSET);
}
synchronized (mStats) {
if (mBluetoothHeadset != null) {
mStats.noteBluetoothOnLocked();
mStats.setBtHeadset(mBluetoothHeadset);
} else {
mBluetoothPendingStats = true;
}
}
}
private BluetoothProfile.ServiceListener mBluetoothProfileServiceListener =
new BluetoothProfile.ServiceListener() {
public void onServiceConnected(int profile, BluetoothProfile proxy) {
mBluetoothHeadset = (BluetoothHeadset) proxy;
synchronized (mStats) {
if (mBluetoothPendingStats) {
mStats.noteBluetoothOnLocked();
mStats.setBtHeadset(mBluetoothHeadset);
mBluetoothPendingStats = false;
}
}
}
public void onServiceDisconnected(int profile) {
mBluetoothHeadset = null;
}
};
public void noteBluetoothOff() {
enforceCallingPermission();
synchronized (mStats) {
mBluetoothPendingStats = false;
mStats.noteBluetoothOffLocked();
}
}
public void noteBluetoothState(int bluetoothState) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteBluetoothStateLocked(bluetoothState);
}
}
public void noteFullWifiLockAcquired(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteFullWifiLockAcquiredLocked(uid);
}
}
public void noteFullWifiLockReleased(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteFullWifiLockReleasedLocked(uid);
}
}
public void noteWifiScanStarted(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiScanStartedLocked(uid);
}
}
public void noteWifiScanStopped(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiScanStoppedLocked(uid);
}
}
public void noteWifiMulticastEnabled(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiMulticastEnabledLocked(uid);
}
}
public void noteWifiMulticastDisabled(int uid) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiMulticastDisabledLocked(uid);
}
}
public void noteFullWifiLockAcquiredFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteFullWifiLockAcquiredFromSourceLocked(ws);
}
}
public void noteFullWifiLockReleasedFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteFullWifiLockReleasedFromSourceLocked(ws);
}
}
public void noteWifiScanStartedFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiScanStartedFromSourceLocked(ws);
}
}
public void noteWifiScanStoppedFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiScanStoppedFromSourceLocked(ws);
}
}
public void noteWifiBatchedScanStartedFromSource(WorkSource ws, int csph) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiBatchedScanStartedFromSourceLocked(ws, csph);
}
}
public void noteWifiBatchedScanStoppedFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiBatchedScanStoppedFromSourceLocked(ws);
}
}
public void noteWifiMulticastEnabledFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiMulticastEnabledFromSourceLocked(ws);
}
}
public void noteWifiMulticastDisabledFromSource(WorkSource ws) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteWifiMulticastDisabledFromSourceLocked(ws);
}
}
@Override
public void noteNetworkInterfaceType(String iface, int type) {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteNetworkInterfaceTypeLocked(iface, type);
}
}
@Override
public void noteNetworkStatsEnabled() {
enforceCallingPermission();
synchronized (mStats) {
mStats.noteNetworkStatsEnabledLocked();
}
}
public boolean isOnBattery() {
return mStats.isOnBattery();
}
public void setBatteryState(int status, int health, int plugType, int level,
int temp, int volt) {
enforceCallingPermission();
mStats.setBatteryState(status, health, plugType, level, temp, volt);
}
public long getAwakeTimeBattery() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BATTERY_STATS, null);
return mStats.getAwakeTimeBattery();
}
public long getAwakeTimePlugged() {
mContext.enforceCallingOrSelfPermission(
android.Manifest.permission.BATTERY_STATS, null);
return mStats.getAwakeTimePlugged();
}
public void enforceCallingPermission() {
if (Binder.getCallingPid() == Process.myPid()) {
return;
}
mContext.enforcePermission(android.Manifest.permission.UPDATE_DEVICE_STATS,
Binder.getCallingPid(), Binder.getCallingUid(), null);
}
final class WakeupReasonThread extends Thread {
final int[] mIrqs = new int[32];
final String[] mReasons = new String[32];
WakeupReasonThread() {
super("BatteryStats_wakeupReason");
}
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_FOREGROUND);
try {
int num;
while ((num=nativeWaitWakeup(mIrqs, mReasons)) >= 0) {
synchronized (mStats) {
if (num > 0) {
for (int i=0; i<num; i++) {
mStats.noteWakeupReasonLocked(mReasons[i]);
}
} else {
mStats.noteWakeupReasonLocked("unknown");
}
}
}
} catch (RuntimeException e) {
Slog.e(TAG, "Failure reading wakeup reasons", e);
}
}
}
private static native int nativeWaitWakeup(int[] outIrqs, String[] outReasons);
private void dumpHelp(PrintWriter pw) {
pw.println("Battery stats (batterystats) dump options:");
pw.println(" [--checkin] [--history] [--history-start] [--unplugged] [--charged] [-c]");
pw.println(" [--reset] [--write] [-h] [<package.name>]");
pw.println(" --checkin: format output for a checkin report.");
pw.println(" --history: show only history data.");
pw.println(" --history-start <num>: show only history data starting at given time offset.");
pw.println(" --unplugged: only output data since last unplugged.");
pw.println(" --charged: only output data since last charged.");
pw.println(" --reset: reset the stats, clearing all current data.");
pw.println(" --write: force write current collected stats to disk.");
pw.println(" <package.name>: optional name of package to filter output by.");
pw.println(" -h: print this help text.");
pw.println("Battery stats (batterystats) commands:");
pw.println(" enable|disable <option>");
pw.println(" Enable or disable a running option. Option state is not saved across boots.");
pw.println(" Options are:");
pw.println(" full-history: include additional detailed events in battery history:");
pw.println(" wake_lock_in and proc events");
pw.println(" no-auto-reset: don't automatically reset stats when unplugged");
}
private int doEnableOrDisable(PrintWriter pw, int i, String[] args, boolean enable) {
i++;
if (i >= args.length) {
pw.println("Missing option argument for " + (enable ? "--enable" : "--disable"));
dumpHelp(pw);
return -1;
}
if ("full-wake-history".equals(args[i]) || "full-history".equals(args[i])) {
synchronized (mStats) {
mStats.setRecordAllHistoryLocked(enable);
}
} else if ("no-auto-reset".equals(args[i])) {
synchronized (mStats) {
mStats.setNoAutoReset(enable);
}
} else {
pw.println("Unknown enable/disable option: " + args[i]);
dumpHelp(pw);
return -1;
}
return i;
}
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
pw.println("Permission Denial: can't dump BatteryStats from from pid="
+ Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
+ " without permission " + android.Manifest.permission.DUMP);
return;
}
int flags = 0;
boolean useCheckinFormat = false;
boolean isRealCheckin = false;
boolean noOutput = false;
boolean writeData = false;
long historyStart = -1;
int reqUid = -1;
if (args != null) {
for (int i=0; i<args.length; i++) {
String arg = args[i];
if ("--checkin".equals(arg)) {
useCheckinFormat = true;
isRealCheckin = true;
} else if ("--history".equals(arg)) {
flags |= BatteryStats.DUMP_HISTORY_ONLY;
} else if ("--history-start".equals(arg)) {
flags |= BatteryStats.DUMP_HISTORY_ONLY;
i++;
if (i >= args.length) {
pw.println("Missing time argument for --history-since");
dumpHelp(pw);
return;
}
historyStart = Long.parseLong(args[i]);
writeData = true;
} else if ("-c".equals(arg)) {
useCheckinFormat = true;
flags |= BatteryStats.DUMP_INCLUDE_HISTORY;
} else if ("--unplugged".equals(arg)) {
flags |= BatteryStats.DUMP_UNPLUGGED_ONLY;
} else if ("--charged".equals(arg)) {
flags |= BatteryStats.DUMP_CHARGED_ONLY;
} else if ("--reset".equals(arg)) {
synchronized (mStats) {
mStats.resetAllStatsCmdLocked();
pw.println("Battery stats reset.");
noOutput = true;
}
} else if ("--write".equals(arg)) {
synchronized (mStats) {
mStats.writeSyncLocked();
pw.println("Battery stats written.");
noOutput = true;
}
} else if ("--enable".equals(arg) || "enable".equals(arg)) {
i = doEnableOrDisable(pw, i, args, true);
if (i < 0) {
return;
}
pw.println("Enabled: " + args[i]);
return;
} else if ("--disable".equals(arg) || "disable".equals(arg)) {
i = doEnableOrDisable(pw, i, args, false);
if (i < 0) {
return;
}
pw.println("Disabled: " + args[i]);
return;
} else if ("-h".equals(arg)) {
dumpHelp(pw);
return;
} else if ("-a".equals(arg)) {
flags |= BatteryStats.DUMP_VERBOSE;
} else if (arg.length() > 0 && arg.charAt(0) == '-'){
pw.println("Unknown option: " + arg);
dumpHelp(pw);
return;
} else {
// Not an option, last argument must be a package name.
try {
reqUid = mContext.getPackageManager().getPackageUid(arg,
UserHandle.getCallingUserId());
} catch (PackageManager.NameNotFoundException e) {
pw.println("Unknown package: " + arg);
dumpHelp(pw);
return;
}
}
}
}
if (noOutput) {
return;
}
if (useCheckinFormat) {
List<ApplicationInfo> apps = mContext.getPackageManager().getInstalledApplications(0);
if (isRealCheckin) {
// For a real checkin, first we want to prefer to use the last complete checkin
// file if there is one.
synchronized (mStats.mCheckinFile) {
if (mStats.mCheckinFile.exists()) {
try {
byte[] raw = mStats.mCheckinFile.readFully();
if (raw != null) {
Parcel in = Parcel.obtain();
in.unmarshall(raw, 0, raw.length);
in.setDataPosition(0);
BatteryStatsImpl checkinStats = new BatteryStatsImpl(
null, mStats.mHandler);
checkinStats.readSummaryFromParcel(in);
in.recycle();
checkinStats.dumpCheckinLocked(mContext, pw, apps, flags,
historyStart);
mStats.mCheckinFile.delete();
return;
}
} catch (IOException e) {
Slog.w(TAG, "Failure reading checkin file "
+ mStats.mCheckinFile.getBaseFile(), e);
}
}
}
}
synchronized (mStats) {
mStats.dumpCheckinLocked(mContext, pw, apps, flags, historyStart);
if (writeData) {
mStats.writeAsyncLocked();
}
}
} else {
synchronized (mStats) {
mStats.dumpLocked(mContext, pw, flags, reqUid, historyStart);
if (writeData) {
mStats.writeAsyncLocked();
}
}
}
}
}