Show history of battery level.
Also clean up to remove dead code for running services and old battery usage UI. Finally some string improvements from Roy. Change-Id: I8765a4c744b92edd1505f14c47fea57b918e5d7b
This commit is contained in:
275
src/com/android/settings/fuelgauge/BatteryHistoryChart.java
Normal file
275
src/com/android/settings/fuelgauge/BatteryHistoryChart.java
Normal file
@@ -0,0 +1,275 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.settings.fuelgauge;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.ColorStateList;
|
||||
import android.content.res.TypedArray;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Typeface;
|
||||
import android.os.BatteryStats;
|
||||
import android.os.SystemClock;
|
||||
import android.os.BatteryStats.BatteryHistoryRecord;
|
||||
import android.text.TextPaint;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.View;
|
||||
|
||||
public class BatteryHistoryChart extends View {
|
||||
private static final int SANS = 1;
|
||||
private static final int SERIF = 2;
|
||||
private static final int MONOSPACE = 3;
|
||||
|
||||
final Paint mBatteryPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
final TextPaint mTextPaint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
|
||||
|
||||
int mFontSize;
|
||||
|
||||
BatteryStats mStats;
|
||||
long mStatsPeriod;
|
||||
String mDurationString;
|
||||
|
||||
int mTextAscent;
|
||||
int mTextDescent;
|
||||
int mDurationStringWidth;
|
||||
|
||||
int mNumHist;
|
||||
long mHistStart;
|
||||
long mHistEnd;
|
||||
int mBatLow;
|
||||
int mBatHigh;
|
||||
|
||||
public BatteryHistoryChart(Context context, AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
|
||||
mBatteryPaint.setARGB(255, 255, 128, 128);
|
||||
|
||||
mTextPaint.density = getResources().getDisplayMetrics().density;
|
||||
mTextPaint.setCompatibilityScaling(
|
||||
getResources().getCompatibilityInfo().applicationScale);
|
||||
|
||||
TypedArray a =
|
||||
context.obtainStyledAttributes(
|
||||
attrs, R.styleable.BatteryHistoryChart, 0, 0);
|
||||
|
||||
ColorStateList textColor = null;
|
||||
int textSize = 15;
|
||||
int typefaceIndex = -1;
|
||||
int styleIndex = -1;
|
||||
|
||||
TypedArray appearance = null;
|
||||
int ap = a.getResourceId(R.styleable.BatteryHistoryChart_android_textAppearance, -1);
|
||||
if (ap != -1) {
|
||||
appearance = context.obtainStyledAttributes(ap,
|
||||
com.android.internal.R.styleable.
|
||||
TextAppearance);
|
||||
}
|
||||
if (appearance != null) {
|
||||
int n = appearance.getIndexCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
int attr = appearance.getIndex(i);
|
||||
|
||||
switch (attr) {
|
||||
case com.android.internal.R.styleable.TextAppearance_textColor:
|
||||
textColor = appearance.getColorStateList(attr);
|
||||
break;
|
||||
|
||||
case com.android.internal.R.styleable.TextAppearance_textSize:
|
||||
textSize = appearance.getDimensionPixelSize(attr, textSize);
|
||||
break;
|
||||
|
||||
case com.android.internal.R.styleable.TextAppearance_typeface:
|
||||
typefaceIndex = appearance.getInt(attr, -1);
|
||||
break;
|
||||
|
||||
case com.android.internal.R.styleable.TextAppearance_textStyle:
|
||||
styleIndex = appearance.getInt(attr, -1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
appearance.recycle();
|
||||
}
|
||||
|
||||
int shadowcolor = 0;
|
||||
float dx=0, dy=0, r=0;
|
||||
|
||||
int n = a.getIndexCount();
|
||||
for (int i = 0; i < n; i++) {
|
||||
int attr = a.getIndex(i);
|
||||
|
||||
switch (attr) {
|
||||
case R.styleable.BatteryHistoryChart_android_shadowColor:
|
||||
shadowcolor = a.getInt(attr, 0);
|
||||
break;
|
||||
|
||||
case R.styleable.BatteryHistoryChart_android_shadowDx:
|
||||
dx = a.getFloat(attr, 0);
|
||||
break;
|
||||
|
||||
case R.styleable.BatteryHistoryChart_android_shadowDy:
|
||||
dy = a.getFloat(attr, 0);
|
||||
break;
|
||||
|
||||
case R.styleable.BatteryHistoryChart_android_shadowRadius:
|
||||
r = a.getFloat(attr, 0);
|
||||
break;
|
||||
|
||||
case R.styleable.BatteryHistoryChart_android_textColor:
|
||||
textColor = a.getColorStateList(attr);
|
||||
break;
|
||||
|
||||
case R.styleable.BatteryHistoryChart_android_textSize:
|
||||
textSize = a.getDimensionPixelSize(attr, textSize);
|
||||
break;
|
||||
|
||||
case R.styleable.BatteryHistoryChart_android_typeface:
|
||||
typefaceIndex = a.getInt(attr, typefaceIndex);
|
||||
break;
|
||||
|
||||
case R.styleable.BatteryHistoryChart_android_textStyle:
|
||||
styleIndex = a.getInt(attr, styleIndex);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mTextPaint.setColor(textColor.getDefaultColor());
|
||||
mTextPaint.setTextSize(textSize);
|
||||
|
||||
Typeface tf = null;
|
||||
switch (typefaceIndex) {
|
||||
case SANS:
|
||||
tf = Typeface.SANS_SERIF;
|
||||
break;
|
||||
|
||||
case SERIF:
|
||||
tf = Typeface.SERIF;
|
||||
break;
|
||||
|
||||
case MONOSPACE:
|
||||
tf = Typeface.MONOSPACE;
|
||||
break;
|
||||
}
|
||||
|
||||
setTypeface(tf, styleIndex);
|
||||
|
||||
if (shadowcolor != 0) {
|
||||
mTextPaint.setShadowLayer(r, dx, dy, shadowcolor);
|
||||
}
|
||||
}
|
||||
|
||||
public void setTypeface(Typeface tf, int style) {
|
||||
if (style > 0) {
|
||||
if (tf == null) {
|
||||
tf = Typeface.defaultFromStyle(style);
|
||||
} else {
|
||||
tf = Typeface.create(tf, style);
|
||||
}
|
||||
|
||||
mTextPaint.setTypeface(tf);
|
||||
// now compute what (if any) algorithmic styling is needed
|
||||
int typefaceStyle = tf != null ? tf.getStyle() : 0;
|
||||
int need = style & ~typefaceStyle;
|
||||
mTextPaint.setFakeBoldText((need & Typeface.BOLD) != 0);
|
||||
mTextPaint.setTextSkewX((need & Typeface.ITALIC) != 0 ? -0.25f : 0);
|
||||
} else {
|
||||
mTextPaint.setFakeBoldText(false);
|
||||
mTextPaint.setTextSkewX(0);
|
||||
mTextPaint.setTypeface(tf);
|
||||
}
|
||||
}
|
||||
|
||||
void setStats(BatteryStats stats) {
|
||||
mStats = stats;
|
||||
|
||||
long uSecTime = mStats.computeBatteryRealtime(SystemClock.elapsedRealtime() * 1000,
|
||||
BatteryStats.STATS_UNPLUGGED);
|
||||
mStatsPeriod = uSecTime;
|
||||
String durationString = Utils.formatElapsedTime(getContext(), mStatsPeriod / 1000);
|
||||
mDurationString = getContext().getString(R.string.battery_stats_on_battery,
|
||||
durationString);
|
||||
|
||||
BatteryStats.BatteryHistoryRecord rec = stats.getHistory();
|
||||
if (rec != null) {
|
||||
mHistStart = rec.time;
|
||||
mBatLow = mBatHigh = rec.batteryLevel;
|
||||
}
|
||||
int pos = 0;
|
||||
int lastUnplugged = 0;
|
||||
mBatLow = 0;
|
||||
mBatHigh = 100;
|
||||
while (rec != null) {
|
||||
pos++;
|
||||
if ((rec.states&BatteryHistoryRecord.STATE_BATTERY_PLUGGED_FLAG) == 0) {
|
||||
lastUnplugged = pos;
|
||||
mHistEnd = rec.time;
|
||||
}
|
||||
rec = rec.next;
|
||||
}
|
||||
mNumHist = lastUnplugged;
|
||||
|
||||
if (mHistEnd <= mHistStart) mHistEnd = mHistStart+1;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
mDurationStringWidth = (int)mTextPaint.measureText(mDurationString);
|
||||
mTextAscent = (int)mTextPaint.ascent();
|
||||
mTextDescent = (int)mTextPaint.descent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
|
||||
super.onSizeChanged(w, h, oldw, oldh);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDraw(Canvas canvas) {
|
||||
super.onDraw(canvas);
|
||||
|
||||
final int width = getWidth();
|
||||
final int height = getHeight();
|
||||
|
||||
final long timeStart = mHistStart;
|
||||
final long timeChange = mHistEnd-mHistStart;
|
||||
|
||||
final int batLow = mBatLow;
|
||||
final int batChange = mBatHigh-mBatLow;
|
||||
|
||||
BatteryStats.BatteryHistoryRecord rec = mStats.getHistory();
|
||||
int lastX=-1, lastY=-1;
|
||||
int pos = 0;
|
||||
final int N = mNumHist;
|
||||
while (rec != null && pos < N) {
|
||||
int x = (int)(((rec.time-timeStart)*width)/timeChange);
|
||||
int y = height-1 - ((rec.batteryLevel-batLow)*height)/batChange;
|
||||
if (lastX >= 0) {
|
||||
canvas.drawLine(lastX, lastY, x, y, mBatteryPaint);
|
||||
}
|
||||
lastX = x;
|
||||
lastY = y;
|
||||
rec = rec.next;
|
||||
pos++;
|
||||
}
|
||||
|
||||
canvas.drawText(mDurationString, (width/2) - (mDurationStringWidth/2),
|
||||
(height/2) - ((mTextDescent-mTextAscent)/2) - mTextAscent, mTextPaint);
|
||||
}
|
||||
}
|
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2010 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.settings.fuelgauge;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.BatteryStats;
|
||||
import android.preference.Preference;
|
||||
import android.view.View;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
|
||||
/**
|
||||
* Custom preference for displaying power consumption as a bar and an icon on the left for the
|
||||
* subsystem/app type.
|
||||
*
|
||||
*/
|
||||
public class BatteryHistoryPreference extends Preference {
|
||||
|
||||
private BatteryStats mStats;
|
||||
|
||||
public BatteryHistoryPreference(Context context, BatteryStats stats) {
|
||||
super(context);
|
||||
setLayoutResource(R.layout.preference_batteryhistory);
|
||||
mStats = stats;
|
||||
}
|
||||
|
||||
BatteryStats getStats() {
|
||||
return mStats;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onBindView(View view) {
|
||||
super.onBindView(view);
|
||||
|
||||
BatteryHistoryChart chart = (BatteryHistoryChart)view.findViewById(
|
||||
R.id.battery_history_chart);
|
||||
chart.setStats(mStats);
|
||||
}
|
||||
}
|
196
src/com/android/settings/fuelgauge/BatterySipper.java
Normal file
196
src/com/android/settings/fuelgauge/BatterySipper.java
Normal file
@@ -0,0 +1,196 @@
|
||||
/*
|
||||
* Copyright (C) 2009 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.settings.fuelgauge;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.PowerUsageDetail.DrainType;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Handler;
|
||||
import android.os.BatteryStats.Uid;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
class BatterySipper implements Comparable<BatterySipper> {
|
||||
final Context mContext;
|
||||
final HashMap<String,UidToDetail> mUidCache = new HashMap<String,UidToDetail>();
|
||||
final ArrayList<BatterySipper> mRequestQueue;
|
||||
final Handler mHandler;
|
||||
String name;
|
||||
Drawable icon;
|
||||
int iconId; // For passing to the detail screen.
|
||||
Uid uidObj;
|
||||
double value;
|
||||
double[] values;
|
||||
DrainType drainType;
|
||||
long usageTime;
|
||||
long cpuTime;
|
||||
long gpsTime;
|
||||
long cpuFgTime;
|
||||
double percent;
|
||||
double noCoveragePercent;
|
||||
String defaultPackageName;
|
||||
|
||||
static class UidToDetail {
|
||||
String name;
|
||||
String packageName;
|
||||
Drawable icon;
|
||||
}
|
||||
|
||||
BatterySipper(Context context, ArrayList<BatterySipper> requestQueue,
|
||||
Handler handler, String label, DrainType drainType,
|
||||
int iconId, Uid uid, double[] values) {
|
||||
mContext = context;
|
||||
mRequestQueue = requestQueue;
|
||||
mHandler = handler;
|
||||
this.values = values;
|
||||
name = label;
|
||||
this.drainType = drainType;
|
||||
if (iconId > 0) {
|
||||
icon = mContext.getResources().getDrawable(iconId);
|
||||
}
|
||||
if (values != null) value = values[0];
|
||||
if ((label == null || iconId == 0) && uid != null) {
|
||||
getQuickNameIconForUid(uid);
|
||||
}
|
||||
uidObj = uid;
|
||||
}
|
||||
|
||||
double getSortValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
double[] getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
Drawable getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public int compareTo(BatterySipper other) {
|
||||
// Return the flipped value because we want the items in descending order
|
||||
return (int) (other.getSortValue() - getSortValue());
|
||||
}
|
||||
|
||||
void getQuickNameIconForUid(Uid uidObj) {
|
||||
final int uid = uidObj.getUid();
|
||||
final String uidString = Integer.toString(uid);
|
||||
if (mUidCache.containsKey(uidString)) {
|
||||
UidToDetail utd = mUidCache.get(uidString);
|
||||
defaultPackageName = utd.packageName;
|
||||
name = utd.name;
|
||||
icon = utd.icon;
|
||||
return;
|
||||
}
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
|
||||
String[] packages = pm.getPackagesForUid(uid);
|
||||
icon = pm.getDefaultActivityIcon();
|
||||
if (packages == null) {
|
||||
//name = Integer.toString(uid);
|
||||
if (uid == 0) {
|
||||
name = mContext.getResources().getString(R.string.process_kernel_label);
|
||||
} else if ("mediaserver".equals(name)) {
|
||||
name = mContext.getResources().getString(R.string.process_mediaserver_label);
|
||||
}
|
||||
iconId = R.drawable.ic_power_system;
|
||||
icon = mContext.getResources().getDrawable(iconId);
|
||||
return;
|
||||
} else {
|
||||
//name = packages[0];
|
||||
}
|
||||
synchronized (mRequestQueue) {
|
||||
mRequestQueue.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets name and icon
|
||||
* @param uid Uid of the application
|
||||
*/
|
||||
void getNameIcon() {
|
||||
PackageManager pm = mContext.getPackageManager();
|
||||
final int uid = uidObj.getUid();
|
||||
final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
|
||||
String[] packages = pm.getPackagesForUid(uid);
|
||||
if (packages == null) {
|
||||
name = Integer.toString(uid);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] packageLabels = new String[packages.length];
|
||||
System.arraycopy(packages, 0, packageLabels, 0, packages.length);
|
||||
|
||||
int preferredIndex = -1;
|
||||
// Convert package names to user-facing labels where possible
|
||||
for (int i = 0; i < packageLabels.length; i++) {
|
||||
// Check if package matches preferred package
|
||||
if (packageLabels[i].equals(name)) preferredIndex = i;
|
||||
try {
|
||||
ApplicationInfo ai = pm.getApplicationInfo(packageLabels[i], 0);
|
||||
CharSequence label = ai.loadLabel(pm);
|
||||
if (label != null) {
|
||||
packageLabels[i] = label.toString();
|
||||
}
|
||||
if (ai.icon != 0) {
|
||||
defaultPackageName = packages[i];
|
||||
icon = ai.loadIcon(pm);
|
||||
break;
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
}
|
||||
}
|
||||
if (icon == null) icon = defaultActivityIcon;
|
||||
|
||||
if (packageLabels.length == 1) {
|
||||
name = packageLabels[0];
|
||||
} else {
|
||||
// Look for an official name for this UID.
|
||||
for (String pkgName : packages) {
|
||||
try {
|
||||
final PackageInfo pi = pm.getPackageInfo(pkgName, 0);
|
||||
if (pi.sharedUserLabel != 0) {
|
||||
final CharSequence nm = pm.getText(pkgName,
|
||||
pi.sharedUserLabel, pi.applicationInfo);
|
||||
if (nm != null) {
|
||||
name = nm.toString();
|
||||
if (pi.applicationInfo.icon != 0) {
|
||||
defaultPackageName = pkgName;
|
||||
icon = pi.applicationInfo.loadIcon(pm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
final String uidString = Integer.toString(uidObj.getUid());
|
||||
UidToDetail utd = new UidToDetail();
|
||||
utd.name = name;
|
||||
utd.icon = icon;
|
||||
utd.packageName = defaultPackageName;
|
||||
mUidCache.put(uidString, utd);
|
||||
mHandler.sendMessage(mHandler.obtainMessage(PowerUsageSummary.MSG_UPDATE_NAME_ICON, this));
|
||||
}
|
||||
}
|
@@ -17,9 +17,6 @@
|
||||
package com.android.settings.fuelgauge;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.ColorFilter;
|
||||
import android.graphics.PixelFormat;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.preference.Preference;
|
||||
import android.view.View;
|
||||
@@ -27,7 +24,6 @@ import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.PowerUsageSummary.BatterySipper;
|
||||
|
||||
/**
|
||||
* Custom preference for displaying power consumption as a bar and an icon on the left for the
|
||||
|
@@ -18,10 +18,6 @@ package com.android.settings.fuelgauge;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.hardware.SensorManager;
|
||||
import android.os.BatteryStats;
|
||||
@@ -53,7 +49,6 @@ import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -86,19 +81,11 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
|
||||
private double mTotalPower;
|
||||
private PowerProfile mPowerProfile;
|
||||
|
||||
private HashMap<String,UidToDetail> mUidCache = new HashMap<String,UidToDetail>();
|
||||
|
||||
/** Queue for fetching name and icon for an application */
|
||||
private ArrayList<BatterySipper> mRequestQueue = new ArrayList<BatterySipper>();
|
||||
private Thread mRequestThread;
|
||||
private boolean mAbort;
|
||||
|
||||
static class UidToDetail {
|
||||
String name;
|
||||
String packageName;
|
||||
Drawable icon;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle icicle) {
|
||||
super.onCreate(icicle);
|
||||
@@ -267,6 +254,10 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
|
||||
|
||||
mAppListGroup.setOrderingAsAdded(false);
|
||||
|
||||
BatteryHistoryPreference hist = new BatteryHistoryPreference(this, mStats);
|
||||
hist.setOrder(-1);
|
||||
mAppListGroup.addPreference(hist);
|
||||
|
||||
Collections.sort(mUsageList);
|
||||
for (BatterySipper sipper : mUsageList) {
|
||||
if (sipper.getSortValue() < MIN_POWER_THRESHOLD) continue;
|
||||
@@ -283,7 +274,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
|
||||
pref.setKey(Integer.toString(sipper.uidObj.getUid()));
|
||||
}
|
||||
mAppListGroup.addPreference(pref);
|
||||
if (mAppListGroup.getPreferenceCount() > MAX_ITEMS_TO_LIST) break;
|
||||
if (mAppListGroup.getPreferenceCount() > (MAX_ITEMS_TO_LIST+1)) break;
|
||||
}
|
||||
if (DEBUG) setTitle("Battery total uAh = " + ((mTotalPower * 1000) / 3600));
|
||||
synchronized (mRequestQueue) {
|
||||
@@ -408,7 +399,8 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
|
||||
|
||||
// Add the app to the list if it is consuming power
|
||||
if (power != 0) {
|
||||
BatterySipper app = new BatterySipper(packageWithHighestDrain, DrainType.APP, 0, u,
|
||||
BatterySipper app = new BatterySipper(this, mRequestQueue, mHandler,
|
||||
packageWithHighestDrain, DrainType.APP, 0, u,
|
||||
new double[] {power});
|
||||
app.cpuTime = cpuTime;
|
||||
app.gpsTime = gpsTime;
|
||||
@@ -549,7 +541,8 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
|
||||
double power) {
|
||||
if (power > mMaxPower) mMaxPower = power;
|
||||
mTotalPower += power;
|
||||
BatterySipper bs = new BatterySipper(label, drainType, iconId, null, new double[] {power});
|
||||
BatterySipper bs = new BatterySipper(this, mRequestQueue, mHandler,
|
||||
label, drainType, iconId, null, new double[] {power});
|
||||
bs.usageTime = time;
|
||||
bs.iconId = iconId;
|
||||
mUsageList.add(bs);
|
||||
@@ -569,156 +562,6 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
class BatterySipper implements Comparable<BatterySipper> {
|
||||
String name;
|
||||
Drawable icon;
|
||||
int iconId; // For passing to the detail screen.
|
||||
Uid uidObj;
|
||||
double value;
|
||||
double[] values;
|
||||
DrainType drainType;
|
||||
long usageTime;
|
||||
long cpuTime;
|
||||
long gpsTime;
|
||||
long cpuFgTime;
|
||||
double percent;
|
||||
double noCoveragePercent;
|
||||
String defaultPackageName;
|
||||
|
||||
BatterySipper(String label, DrainType drainType, int iconId, Uid uid, double[] values) {
|
||||
this.values = values;
|
||||
name = label;
|
||||
this.drainType = drainType;
|
||||
if (iconId > 0) {
|
||||
icon = getResources().getDrawable(iconId);
|
||||
}
|
||||
if (values != null) value = values[0];
|
||||
if ((label == null || iconId == 0) && uid != null) {
|
||||
getQuickNameIconForUid(uid);
|
||||
}
|
||||
uidObj = uid;
|
||||
}
|
||||
|
||||
double getSortValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
double[] getValues() {
|
||||
return values;
|
||||
}
|
||||
|
||||
Drawable getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
public int compareTo(BatterySipper other) {
|
||||
// Return the flipped value because we want the items in descending order
|
||||
return (int) (other.getSortValue() - getSortValue());
|
||||
}
|
||||
|
||||
void getQuickNameIconForUid(Uid uidObj) {
|
||||
final int uid = uidObj.getUid();
|
||||
final String uidString = Integer.toString(uid);
|
||||
if (mUidCache.containsKey(uidString)) {
|
||||
UidToDetail utd = mUidCache.get(uidString);
|
||||
defaultPackageName = utd.packageName;
|
||||
name = utd.name;
|
||||
icon = utd.icon;
|
||||
return;
|
||||
}
|
||||
PackageManager pm = getPackageManager();
|
||||
final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
|
||||
String[] packages = pm.getPackagesForUid(uid);
|
||||
icon = pm.getDefaultActivityIcon();
|
||||
if (packages == null) {
|
||||
//name = Integer.toString(uid);
|
||||
if (uid == 0) {
|
||||
name = getResources().getString(R.string.process_kernel_label);
|
||||
} else if ("mediaserver".equals(name)) {
|
||||
name = getResources().getString(R.string.process_mediaserver_label);
|
||||
}
|
||||
iconId = R.drawable.ic_power_system;
|
||||
icon = getResources().getDrawable(iconId);
|
||||
return;
|
||||
} else {
|
||||
//name = packages[0];
|
||||
}
|
||||
synchronized (mRequestQueue) {
|
||||
mRequestQueue.add(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets name and icon
|
||||
* @param uid Uid of the application
|
||||
*/
|
||||
void getNameIcon() {
|
||||
PackageManager pm = getPackageManager();
|
||||
final int uid = uidObj.getUid();
|
||||
final Drawable defaultActivityIcon = pm.getDefaultActivityIcon();
|
||||
String[] packages = pm.getPackagesForUid(uid);
|
||||
if (packages == null) {
|
||||
name = Integer.toString(uid);
|
||||
return;
|
||||
}
|
||||
|
||||
String[] packageLabels = new String[packages.length];
|
||||
System.arraycopy(packages, 0, packageLabels, 0, packages.length);
|
||||
|
||||
int preferredIndex = -1;
|
||||
// Convert package names to user-facing labels where possible
|
||||
for (int i = 0; i < packageLabels.length; i++) {
|
||||
// Check if package matches preferred package
|
||||
if (packageLabels[i].equals(name)) preferredIndex = i;
|
||||
try {
|
||||
ApplicationInfo ai = pm.getApplicationInfo(packageLabels[i], 0);
|
||||
CharSequence label = ai.loadLabel(pm);
|
||||
if (label != null) {
|
||||
packageLabels[i] = label.toString();
|
||||
}
|
||||
if (ai.icon != 0) {
|
||||
defaultPackageName = packages[i];
|
||||
icon = ai.loadIcon(pm);
|
||||
break;
|
||||
}
|
||||
} catch (NameNotFoundException e) {
|
||||
}
|
||||
}
|
||||
if (icon == null) icon = defaultActivityIcon;
|
||||
|
||||
if (packageLabels.length == 1) {
|
||||
name = packageLabels[0];
|
||||
} else {
|
||||
// Look for an official name for this UID.
|
||||
for (String pkgName : packages) {
|
||||
try {
|
||||
final PackageInfo pi = pm.getPackageInfo(pkgName, 0);
|
||||
if (pi.sharedUserLabel != 0) {
|
||||
final CharSequence nm = pm.getText(pkgName,
|
||||
pi.sharedUserLabel, pi.applicationInfo);
|
||||
if (nm != null) {
|
||||
name = nm.toString();
|
||||
if (pi.applicationInfo.icon != 0) {
|
||||
defaultPackageName = pkgName;
|
||||
icon = pi.applicationInfo.loadIcon(pm);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
final String uidString = Integer.toString(uidObj.getUid());
|
||||
UidToDetail utd = new UidToDetail();
|
||||
utd.name = name;
|
||||
utd.icon = icon;
|
||||
utd.packageName = defaultPackageName;
|
||||
mUidCache.put(uidString, utd);
|
||||
mHandler.sendMessage(mHandler.obtainMessage(MSG_UPDATE_NAME_ICON, this));
|
||||
}
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (true) {
|
||||
BatterySipper bs;
|
||||
@@ -733,7 +576,7 @@ public class PowerUsageSummary extends PreferenceActivity implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
private static final int MSG_UPDATE_NAME_ICON = 1;
|
||||
static final int MSG_UPDATE_NAME_ICON = 1;
|
||||
|
||||
Handler mHandler = new Handler() {
|
||||
|
||||
|
Reference in New Issue
Block a user