auto import from //depot/cupcake/@137055

This commit is contained in:
The Android Open Source Project
2009-03-02 22:54:33 -08:00
parent 15ab3eae2e
commit 3dec7d563a
311 changed files with 18136 additions and 4075 deletions

View File

@ -20,20 +20,31 @@ import com.android.internal.app.IBatteryStats;
import com.android.server.am.BatteryStatsService;
import android.app.ActivityManagerNative;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.BatteryManager;
import android.os.Binder;
import android.os.Debug;
import android.os.IBinder;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UEventObserver;
import android.provider.Checkin;
import android.provider.Settings;
import android.util.EventLog;
import android.util.Log;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.String;
/**
* <p>BatteryService monitors the charging status, and charge level of the device
@ -60,12 +71,24 @@ import java.lang.String;
class BatteryService extends Binder {
private static final String TAG = BatteryService.class.getSimpleName();
private static final boolean LOCAL_LOGV = false;
static final int LOG_BATTERY_LEVEL = 2722;
static final int LOG_BATTERY_STATUS = 2723;
static final int LOG_BATTERY_DISCHARGE_STATUS = 2730;
static final int BATTERY_SCALE = 100; // battery capacity is a percentage
// Used locally for determining when to make a last ditch effort to log
// discharge stats before the device dies.
private static final int CRITICAL_BATTERY_LEVEL = 4;
private static final int DUMP_MAX_LENGTH = 24 * 1024;
private static final String[] DUMPSYS_ARGS = new String[] { "-c", "-u" };
private static final String BATTERY_STATS_SERVICE_NAME = "batteryinfo";
private static final String DUMPSYS_DATA_PATH = "/data/system/";
// This should probably be exposed in the API, though it's not critical
private static final int BATTERY_PLUGGED_NONE = 0;
@ -81,6 +104,7 @@ class BatteryService extends Binder {
private int mBatteryVoltage;
private int mBatteryTemperature;
private String mBatteryTechnology;
private boolean mBatteryLevelCritical;
private int mLastBatteryStatus;
private int mLastBatteryHealth;
@ -88,6 +112,7 @@ class BatteryService extends Binder {
private int mLastBatteryLevel;
private int mLastBatteryVoltage;
private int mLastBatteryTemperature;
private boolean mLastBatteryLevelCritical;
private int mPlugType;
private int mLastPlugType = -1; // Extra state so we can detect first run
@ -95,6 +120,7 @@ class BatteryService extends Binder {
private long mDischargeStartTime;
private int mDischargeStartLevel;
public BatteryService(Context context) {
mContext = context;
mBatteryStats = BatteryStatsService.getService();
@ -149,6 +175,8 @@ class BatteryService extends Binder {
private synchronized final void update() {
native_update();
mBatteryLevelCritical = mBatteryLevel <= CRITICAL_BATTERY_LEVEL;
if (mAcOnline) {
mPlugType = BatteryManager.BATTERY_PLUGGED_AC;
} else if (mUsbOnline) {
@ -176,6 +204,8 @@ class BatteryService extends Binder {
mDischargeStartLevel, mBatteryLevel);
// make sure we see a discharge event before logging again
mDischargeStartTime = 0;
logOutlier(duration);
}
} else if (mPlugType == BATTERY_PLUGGED_NONE) {
// charging -> discharging or we just powered up
@ -197,6 +227,12 @@ class BatteryService extends Binder {
EventLog.writeEvent(LOG_BATTERY_LEVEL,
mBatteryLevel, mBatteryVoltage, mBatteryTemperature);
}
if (mBatteryLevelCritical && !mLastBatteryLevelCritical &&
mPlugType == BATTERY_PLUGGED_NONE) {
// We want to make sure we log discharge cycle outliers
// if the battery is about to die.
logOutlier(SystemClock.elapsedRealtime() - mDischargeStartTime);
}
mLastBatteryStatus = mBatteryStatus;
mLastBatteryHealth = mBatteryHealth;
@ -205,6 +241,7 @@ class BatteryService extends Binder {
mLastPlugType = mPlugType;
mLastBatteryVoltage = mBatteryVoltage;
mLastBatteryTemperature = mBatteryTemperature;
mLastBatteryLevelCritical = mBatteryLevelCritical;
sendIntent();
}
@ -247,6 +284,83 @@ class BatteryService extends Binder {
ActivityManagerNative.broadcastStickyIntent(intent, null);
}
private final void logBatteryStats() {
IBinder batteryInfoService = ServiceManager.getService(BATTERY_STATS_SERVICE_NAME);
if (batteryInfoService != null) {
byte[] buffer = new byte[DUMP_MAX_LENGTH];
File dumpFile = null;
FileOutputStream dumpStream = null;
try {
// dump the service to a file
dumpFile = new File(DUMPSYS_DATA_PATH + BATTERY_STATS_SERVICE_NAME + ".dump");
dumpStream = new FileOutputStream(dumpFile);
batteryInfoService.dump(dumpStream.getFD(), DUMPSYS_ARGS);
dumpStream.getFD().sync();
// read dumped file above into buffer truncated to DUMP_MAX_LENGTH
// and insert into events table.
int length = (int) Math.min(dumpFile.length(), DUMP_MAX_LENGTH);
FileInputStream fileInputStream = new FileInputStream(dumpFile);
int nread = fileInputStream.read(buffer, 0, length);
if (nread > 0) {
Checkin.logEvent(mContext.getContentResolver(),
Checkin.Events.Tag.BATTERY_DISCHARGE_INFO,
new String(buffer, 0, nread));
if (LOCAL_LOGV) Log.v(TAG, "dumped " + nread + "b from " +
batteryInfoService + "to log");
if (LOCAL_LOGV) Log.v(TAG, "actual dump:" + new String(buffer, 0, nread));
}
} catch (RemoteException e) {
Log.e(TAG, "failed to dump service '" + BATTERY_STATS_SERVICE_NAME +
"':" + e);
} catch (IOException e) {
Log.e(TAG, "failed to write dumpsys file: " + e);
} finally {
// make sure we clean up
if (dumpStream != null) {
try {
dumpStream.close();
} catch (IOException e) {
Log.e(TAG, "failed to close dumpsys output stream");
}
}
if (dumpFile != null && !dumpFile.delete()) {
Log.e(TAG, "failed to delete temporary dumpsys file: "
+ dumpFile.getAbsolutePath());
}
}
}
}
private final void logOutlier(long duration) {
ContentResolver cr = mContext.getContentResolver();
String dischargeThresholdString = Settings.Gservices.getString(cr,
Settings.Gservices.BATTERY_DISCHARGE_THRESHOLD);
String durationThresholdString = Settings.Gservices.getString(cr,
Settings.Gservices.BATTERY_DISCHARGE_DURATION_THRESHOLD);
if (dischargeThresholdString != null && durationThresholdString != null) {
try {
long durationThreshold = Long.parseLong(durationThresholdString);
int dischargeThreshold = Integer.parseInt(dischargeThresholdString);
if (duration <= durationThreshold &&
mDischargeStartLevel - mBatteryLevel >= dischargeThreshold) {
// If the discharge cycle is bad enough we want to know about it.
logBatteryStats();
}
if (LOCAL_LOGV) Log.v(TAG, "duration threshold: " + durationThreshold +
" discharge threshold: " + dischargeThreshold);
if (LOCAL_LOGV) Log.v(TAG, "duration: " + duration + " discharge: " +
(mDischargeStartLevel - mBatteryLevel));
} catch (NumberFormatException e) {
Log.e(TAG, "Invalid DischargeThresholds GService string: " +
durationThresholdString + " or " + dischargeThresholdString);
return;
}
}
}
private final int getIcon(int level) {
if (mBatteryStatus == BatteryManager.BATTERY_STATUS_CHARGING) {
return com.android.internal.R.drawable.stat_sys_battery_charge;