Merge "Populate new fields foreground_service_usage_time_in_ms, foreground_usage_consume_power, foreground_service_usage_consume_power, background_usage_consume_power and cached_usage_consume_power into database and pass them to UI."
This commit is contained in:
@@ -629,6 +629,7 @@ public class BatteryChartPreferenceController extends AbstractPreferenceControll
|
||||
PowerGaugePreference preference, BatteryDiffEntry entry) {
|
||||
final long foregroundUsageTimeInMs = entry.mForegroundUsageTimeInMs;
|
||||
final long backgroundUsageTimeInMs = entry.mBackgroundUsageTimeInMs;
|
||||
// TODO: update this value after the new API for foreground service is completed.
|
||||
final long totalUsageTimeInMs = foregroundUsageTimeInMs + backgroundUsageTimeInMs;
|
||||
String usageTimeSummary = null;
|
||||
// Not shows summary for some system components without usage time.
|
||||
|
@@ -52,8 +52,13 @@ public class BatteryDiffEntry {
|
||||
(a, b) -> Double.compare(b.getPercentOfTotal(), a.getPercentOfTotal());
|
||||
|
||||
public long mForegroundUsageTimeInMs;
|
||||
public long mForegroundServiceUsageTimeInMs;
|
||||
public long mBackgroundUsageTimeInMs;
|
||||
public double mConsumePower;
|
||||
public double mForegroundUsageConsumePower;
|
||||
public double mForegroundServiceUsageConsumePower;
|
||||
public double mBackgroundUsageConsumePower;
|
||||
public double mCachedUsageConsumePower;
|
||||
// A BatteryHistEntry corresponding to this diff usage data.
|
||||
public final BatteryHistEntry mBatteryHistEntry;
|
||||
|
||||
@@ -78,12 +83,22 @@ public class BatteryDiffEntry {
|
||||
public BatteryDiffEntry(
|
||||
Context context,
|
||||
long foregroundUsageTimeInMs,
|
||||
long foregroundServiceUsageTimeInMs,
|
||||
long backgroundUsageTimeInMs,
|
||||
double consumePower,
|
||||
double foregroundUsageConsumePower,
|
||||
double foregroundServiceUsageConsumePower,
|
||||
double backgroundUsageConsumePower,
|
||||
double cachedUsageConsumePower,
|
||||
BatteryHistEntry batteryHistEntry) {
|
||||
mContext = context;
|
||||
mConsumePower = consumePower;
|
||||
mForegroundUsageConsumePower = foregroundUsageConsumePower;
|
||||
mForegroundServiceUsageConsumePower = foregroundServiceUsageConsumePower;
|
||||
mBackgroundUsageConsumePower = backgroundUsageConsumePower;
|
||||
mCachedUsageConsumePower = cachedUsageConsumePower;
|
||||
mForegroundUsageTimeInMs = foregroundUsageTimeInMs;
|
||||
mForegroundServiceUsageTimeInMs = foregroundServiceUsageTimeInMs;
|
||||
mBackgroundUsageTimeInMs = backgroundUsageTimeInMs;
|
||||
mBatteryHistEntry = batteryHistEntry;
|
||||
mUserManager = context.getSystemService(UserManager.class);
|
||||
@@ -106,8 +121,13 @@ public class BatteryDiffEntry {
|
||||
return new BatteryDiffEntry(
|
||||
this.mContext,
|
||||
this.mForegroundUsageTimeInMs,
|
||||
this.mForegroundServiceUsageTimeInMs,
|
||||
this.mBackgroundUsageTimeInMs,
|
||||
this.mConsumePower,
|
||||
this.mForegroundUsageConsumePower,
|
||||
this.mForegroundServiceUsageConsumePower,
|
||||
this.mBackgroundUsageConsumePower,
|
||||
this.mCachedUsageConsumePower,
|
||||
this.mBatteryHistEntry /*same instance*/);
|
||||
}
|
||||
|
||||
@@ -361,10 +381,19 @@ public class BatteryDiffEntry {
|
||||
mAppLabel, mValidForRestriction))
|
||||
.append(String.format("\n\tconsume=%.2f%% %f/%f",
|
||||
mPercentOfTotal, mConsumePower, mTotalConsumePower))
|
||||
.append(String.format("\n\tforeground:%s background:%s",
|
||||
StringUtil.formatElapsedTime(mContext, mForegroundUsageTimeInMs,
|
||||
.append(String.format("\n\tconsume power= foreground:%f foregroundService:%f",
|
||||
mForegroundUsageConsumePower, mForegroundServiceUsageConsumePower))
|
||||
.append(String.format("\n\tconsume power= background:%f cached:%f",
|
||||
mBackgroundUsageConsumePower, mCachedUsageConsumePower))
|
||||
.append(String.format("\n\ttime= foreground:%s foregroundService:%s background:%s",
|
||||
StringUtil.formatElapsedTime(mContext, (double) mForegroundUsageTimeInMs,
|
||||
/*withSeconds=*/ true, /*collapseTimeUnit=*/ false),
|
||||
StringUtil.formatElapsedTime(mContext, mBackgroundUsageTimeInMs,
|
||||
StringUtil.formatElapsedTime(
|
||||
mContext,
|
||||
(double) mForegroundServiceUsageTimeInMs,
|
||||
/*withSeconds=*/ true,
|
||||
/*collapseTimeUnit=*/ false),
|
||||
StringUtil.formatElapsedTime(mContext, (double) mBackgroundUsageTimeInMs,
|
||||
/*withSeconds=*/ true, /*collapseTimeUnit=*/ false)))
|
||||
.append(String.format("\n\tpackage:%s|%s uid:%d userId:%d",
|
||||
mBatteryHistEntry.mPackageName, getPackageName(),
|
||||
|
@@ -26,6 +26,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
|
||||
import android.content.pm.UserInfo;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.BatteryConsumer;
|
||||
import android.os.BatteryConsumer.Dimensions;
|
||||
import android.os.Process;
|
||||
import android.os.RemoteException;
|
||||
import android.os.UidBatteryConsumer;
|
||||
@@ -39,7 +40,6 @@ import com.android.settings.R;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settingslib.Utils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
@@ -73,9 +73,24 @@ public class BatteryEntry {
|
||||
private static final String TAG = "BatteryEntry";
|
||||
private static final String PACKAGE_SYSTEM = "android";
|
||||
|
||||
static final HashMap<String, UidToDetail> sUidCache = new HashMap<>();
|
||||
static final int BATTERY_USAGE_INDEX_FOREGROUND = 0;
|
||||
static final int BATTERY_USAGE_INDEX_FOREGROUND_SERVICE = 1;
|
||||
static final int BATTERY_USAGE_INDEX_BACKGROUND = 2;
|
||||
static final int BATTERY_USAGE_INDEX_CACHED = 3;
|
||||
|
||||
static final ArrayList<BatteryEntry> sRequestQueue = new ArrayList<BatteryEntry>();
|
||||
static final Dimensions[] BATTERY_DIMENSIONS = new Dimensions[] {
|
||||
new Dimensions(
|
||||
BatteryConsumer.POWER_COMPONENT_ANY, BatteryConsumer.PROCESS_STATE_FOREGROUND),
|
||||
new Dimensions(
|
||||
BatteryConsumer.POWER_COMPONENT_ANY,
|
||||
BatteryConsumer.PROCESS_STATE_FOREGROUND_SERVICE),
|
||||
new Dimensions(
|
||||
BatteryConsumer.POWER_COMPONENT_ANY, BatteryConsumer.PROCESS_STATE_BACKGROUND),
|
||||
new Dimensions(
|
||||
BatteryConsumer.POWER_COMPONENT_ANY, BatteryConsumer.PROCESS_STATE_CACHED),
|
||||
};
|
||||
|
||||
static final HashMap<String, UidToDetail> sUidCache = new HashMap<>();
|
||||
|
||||
static Locale sCurrentLocale = null;
|
||||
|
||||
@@ -97,6 +112,7 @@ public class BatteryEntry {
|
||||
private final int mPowerComponentId;
|
||||
private long mUsageDurationMs;
|
||||
private long mTimeInForegroundMs;
|
||||
private long mTimeInForegroundServiceMs;
|
||||
private long mTimeInBackgroundMs;
|
||||
|
||||
public String mName;
|
||||
@@ -105,6 +121,10 @@ public class BatteryEntry {
|
||||
public double mPercent;
|
||||
private String mDefaultPackageName;
|
||||
private double mConsumedPower;
|
||||
private double mConsumedPowerInForeground;
|
||||
private double mConsumedPowerInForegroundService;
|
||||
private double mConsumedPowerInBackground;
|
||||
private double mConsumedPowerInCached;
|
||||
|
||||
static class UidToDetail {
|
||||
String mName;
|
||||
@@ -156,8 +176,19 @@ public class BatteryEntry {
|
||||
getQuickNameIconForUid(uid, packages, loadDataInBackground);
|
||||
mTimeInForegroundMs =
|
||||
uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND);
|
||||
//TODO: update this to the correct API after the new API is completed.
|
||||
mTimeInForegroundServiceMs =
|
||||
uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_FOREGROUND);
|
||||
mTimeInBackgroundMs =
|
||||
uidBatteryConsumer.getTimeInStateMs(UidBatteryConsumer.STATE_BACKGROUND);
|
||||
mConsumedPowerInForeground = safeGetConsumedPower(
|
||||
uidBatteryConsumer, BATTERY_DIMENSIONS[BATTERY_USAGE_INDEX_FOREGROUND]);
|
||||
mConsumedPowerInForegroundService = safeGetConsumedPower(
|
||||
uidBatteryConsumer, BATTERY_DIMENSIONS[BATTERY_USAGE_INDEX_FOREGROUND_SERVICE]);
|
||||
mConsumedPowerInBackground = safeGetConsumedPower(
|
||||
uidBatteryConsumer, BATTERY_DIMENSIONS[BATTERY_USAGE_INDEX_BACKGROUND]);
|
||||
mConsumedPowerInCached = safeGetConsumedPower(
|
||||
uidBatteryConsumer, BATTERY_DIMENSIONS[BATTERY_USAGE_INDEX_CACHED]);
|
||||
} else if (batteryConsumer instanceof UserBatteryConsumer) {
|
||||
mUid = Process.INVALID_UID;
|
||||
mConsumerType = ConvertUtils.CONSUMER_TYPE_USER_BATTERY;
|
||||
@@ -396,7 +427,7 @@ public class BatteryEntry {
|
||||
return mUid;
|
||||
}
|
||||
|
||||
/** Returns foreground foreground time/ms that is attributed to this entry. */
|
||||
/** Returns foreground time/ms that is attributed to this entry. */
|
||||
public long getTimeInForegroundMs() {
|
||||
if (mBatteryConsumer instanceof UidBatteryConsumer) {
|
||||
return mTimeInForegroundMs;
|
||||
@@ -405,6 +436,15 @@ public class BatteryEntry {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns foreground service time/ms that is attributed to this entry. */
|
||||
public long getTimeInForegroundServiceMs() {
|
||||
if (mBatteryConsumer instanceof UidBatteryConsumer) {
|
||||
return mTimeInForegroundServiceMs;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns background activity time/ms that is attributed to this entry. */
|
||||
public long getTimeInBackgroundMs() {
|
||||
if (mBatteryConsumer instanceof UidBatteryConsumer) {
|
||||
@@ -421,6 +461,53 @@ public class BatteryEntry {
|
||||
return mConsumedPower;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns amount of power (in milli-amp-hours) used in foreground that is attributed to this
|
||||
* entry.
|
||||
*/
|
||||
public double getConsumedPowerInForeground() {
|
||||
if (mBatteryConsumer instanceof UidBatteryConsumer) {
|
||||
return mConsumedPowerInForeground;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns amount of power (in milli-amp-hours) used in foreground service that is attributed to
|
||||
* this entry.
|
||||
*/
|
||||
public double getConsumedPowerInForegroundService() {
|
||||
if (mBatteryConsumer instanceof UidBatteryConsumer) {
|
||||
return mConsumedPowerInForegroundService;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns amount of power (in milli-amp-hours) used in background that is attributed to this
|
||||
* entry.
|
||||
*/
|
||||
public double getConsumedPowerInBackground() {
|
||||
if (mBatteryConsumer instanceof UidBatteryConsumer) {
|
||||
return mConsumedPowerInBackground;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns amount of power (in milli-amp-hours) used in cached that is attributed to this entry.
|
||||
*/
|
||||
public double getConsumedPowerInCached() {
|
||||
if (mBatteryConsumer instanceof UidBatteryConsumer) {
|
||||
return mConsumedPowerInCached;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the consumed power of the supplied BatteryConsumer to this entry. Also
|
||||
* uses its package with highest drain, if necessary.
|
||||
@@ -431,8 +518,19 @@ public class BatteryEntry {
|
||||
UidBatteryConsumer uidBatteryConsumer = (UidBatteryConsumer) batteryConsumer;
|
||||
mTimeInForegroundMs += uidBatteryConsumer.getTimeInStateMs(
|
||||
UidBatteryConsumer.STATE_FOREGROUND);
|
||||
//TODO: update this to the correct API after the new API is completed.
|
||||
mTimeInForegroundServiceMs += uidBatteryConsumer.getTimeInStateMs(
|
||||
UidBatteryConsumer.STATE_FOREGROUND);
|
||||
mTimeInBackgroundMs += uidBatteryConsumer.getTimeInStateMs(
|
||||
UidBatteryConsumer.STATE_BACKGROUND);
|
||||
mConsumedPowerInForeground += safeGetConsumedPower(
|
||||
uidBatteryConsumer, BATTERY_DIMENSIONS[BATTERY_USAGE_INDEX_FOREGROUND]);
|
||||
mConsumedPowerInForegroundService += safeGetConsumedPower(
|
||||
uidBatteryConsumer, BATTERY_DIMENSIONS[BATTERY_USAGE_INDEX_FOREGROUND_SERVICE]);
|
||||
mConsumedPowerInBackground += safeGetConsumedPower(
|
||||
uidBatteryConsumer, BATTERY_DIMENSIONS[BATTERY_USAGE_INDEX_BACKGROUND]);
|
||||
mConsumedPowerInCached += safeGetConsumedPower(
|
||||
uidBatteryConsumer, BATTERY_DIMENSIONS[BATTERY_USAGE_INDEX_CACHED]);
|
||||
if (mDefaultPackageName == null) {
|
||||
mDefaultPackageName = uidBatteryConsumer.getPackageWithHighestDrain();
|
||||
}
|
||||
@@ -533,4 +631,14 @@ public class BatteryEntry {
|
||||
public static boolean isSystemUid(int uid) {
|
||||
return uid == Process.SYSTEM_UID;
|
||||
}
|
||||
|
||||
private static double safeGetConsumedPower(
|
||||
final UidBatteryConsumer uidBatteryConsumer, final Dimensions dimension) {
|
||||
try {
|
||||
return uidBatteryConsumer.getConsumedPower(dimension);
|
||||
} catch (IllegalArgumentException e) {
|
||||
Log.e(TAG, "safeGetConsumedPower failed:" + e);
|
||||
return 0.0d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -50,8 +50,13 @@ public class BatteryHistEntry {
|
||||
// Records the battery usage relative information.
|
||||
public final double mTotalPower;
|
||||
public final double mConsumePower;
|
||||
public final double mForegroundUsageConsumePower;
|
||||
public final double mForegroundServiceUsageConsumePower;
|
||||
public final double mBackgroundUsageConsumePower;
|
||||
public final double mCachedUsageConsumePower;
|
||||
public final double mPercentOfTotal;
|
||||
public final long mForegroundUsageTimeInMs;
|
||||
public final long mForegroundServiceUsageTimeInMs;
|
||||
public final long mBackgroundUsageTimeInMs;
|
||||
@BatteryConsumer.PowerComponent
|
||||
public final int mDrainType;
|
||||
@@ -79,8 +84,14 @@ public class BatteryHistEntry {
|
||||
mZoneId = batteryInformation.getZoneId();
|
||||
mTotalPower = batteryInformation.getTotalPower();
|
||||
mConsumePower = batteryInformation.getConsumePower();
|
||||
mForegroundUsageConsumePower = batteryInformation.getForegroundUsageConsumePower();
|
||||
mForegroundServiceUsageConsumePower =
|
||||
batteryInformation.getForegroundServiceUsageConsumePower();
|
||||
mBackgroundUsageConsumePower = batteryInformation.getBackgroundUsageConsumePower();
|
||||
mCachedUsageConsumePower = batteryInformation.getCachedUsageConsumePower();
|
||||
mPercentOfTotal = batteryInformation.getPercentOfTotal();
|
||||
mForegroundUsageTimeInMs = batteryInformation.getForegroundUsageTimeInMs();
|
||||
mForegroundServiceUsageTimeInMs = batteryInformation.getForegroundServiceUsageTimeInMs();
|
||||
mBackgroundUsageTimeInMs = batteryInformation.getBackgroundUsageTimeInMs();
|
||||
mDrainType = batteryInformation.getDrainType();
|
||||
final DeviceBatteryState deviceBatteryState = batteryInformation.getDeviceBatteryState();
|
||||
@@ -103,8 +114,14 @@ public class BatteryHistEntry {
|
||||
mZoneId = batteryInformation.getZoneId();
|
||||
mTotalPower = batteryInformation.getTotalPower();
|
||||
mConsumePower = batteryInformation.getConsumePower();
|
||||
mForegroundUsageConsumePower = batteryInformation.getForegroundUsageConsumePower();
|
||||
mForegroundServiceUsageConsumePower =
|
||||
batteryInformation.getForegroundServiceUsageConsumePower();
|
||||
mBackgroundUsageConsumePower = batteryInformation.getBackgroundUsageConsumePower();
|
||||
mCachedUsageConsumePower = batteryInformation.getCachedUsageConsumePower();
|
||||
mPercentOfTotal = batteryInformation.getPercentOfTotal();
|
||||
mForegroundUsageTimeInMs = batteryInformation.getForegroundUsageTimeInMs();
|
||||
mForegroundServiceUsageTimeInMs = batteryInformation.getForegroundServiceUsageTimeInMs();
|
||||
mBackgroundUsageTimeInMs = batteryInformation.getBackgroundUsageTimeInMs();
|
||||
mDrainType = batteryInformation.getDrainType();
|
||||
final DeviceBatteryState deviceBatteryState = batteryInformation.getDeviceBatteryState();
|
||||
@@ -119,7 +136,12 @@ public class BatteryHistEntry {
|
||||
long timestamp,
|
||||
double totalPower,
|
||||
double consumePower,
|
||||
double foregroundUsageConsumePower,
|
||||
double foregroundServiceUsageConsumePower,
|
||||
double backgroundUsageConsumePower,
|
||||
double cachedUsageConsumePower,
|
||||
long foregroundUsageTimeInMs,
|
||||
long foregroundServiceUsageTimeInMs,
|
||||
long backgroundUsageTimeInMs,
|
||||
int batteryLevel) {
|
||||
mUid = fromEntry.mUid;
|
||||
@@ -132,8 +154,13 @@ public class BatteryHistEntry {
|
||||
mZoneId = fromEntry.mZoneId;
|
||||
mTotalPower = totalPower;
|
||||
mConsumePower = consumePower;
|
||||
mForegroundUsageConsumePower = foregroundUsageConsumePower;
|
||||
mForegroundServiceUsageConsumePower = foregroundServiceUsageConsumePower;
|
||||
mBackgroundUsageConsumePower = backgroundUsageConsumePower;
|
||||
mCachedUsageConsumePower = cachedUsageConsumePower;
|
||||
mPercentOfTotal = fromEntry.mPercentOfTotal;
|
||||
mForegroundUsageTimeInMs = foregroundUsageTimeInMs;
|
||||
mForegroundServiceUsageTimeInMs = foregroundServiceUsageTimeInMs;
|
||||
mBackgroundUsageTimeInMs = backgroundUsageTimeInMs;
|
||||
mDrainType = fromEntry.mDrainType;
|
||||
mConsumerType = fromEntry.mConsumerType;
|
||||
@@ -190,9 +217,15 @@ public class BatteryHistEntry {
|
||||
mPackageName, mAppLabel, mUid, mUserId, mIsHidden))
|
||||
.append(String.format("\n\ttimestamp=%s|zoneId=%s|bootTimestamp=%d",
|
||||
recordAtDateTime, mZoneId, Duration.ofMillis(mBootTimestamp).getSeconds()))
|
||||
.append(String.format("\n\tusage=%f|total=%f|consume=%f|elapsedTime=%d|%d",
|
||||
mPercentOfTotal, mTotalPower, mConsumePower,
|
||||
.append(String.format("\n\tusage=%f|total=%f|consume=%f",
|
||||
mPercentOfTotal, mTotalPower, mConsumePower))
|
||||
.append(String.format("\n\tforeground=%f|foregroundService=%f",
|
||||
mForegroundUsageConsumePower, mForegroundServiceUsageConsumePower))
|
||||
.append(String.format("\n\tbackground=%f|cached=%f",
|
||||
mBackgroundUsageConsumePower, mCachedUsageConsumePower))
|
||||
.append(String.format("\n\telapsedTime=%d|%d|%d",
|
||||
Duration.ofMillis(mForegroundUsageTimeInMs).getSeconds(),
|
||||
Duration.ofMillis(mForegroundServiceUsageTimeInMs).getSeconds(),
|
||||
Duration.ofMillis(mBackgroundUsageTimeInMs).getSeconds()))
|
||||
.append(String.format("\n\tdrainType=%d|consumerType=%d",
|
||||
mDrainType, mConsumerType))
|
||||
@@ -267,17 +300,45 @@ public class BatteryHistEntry {
|
||||
lowerHistEntry == null ? 0 : lowerHistEntry.mConsumePower,
|
||||
upperHistEntry.mConsumePower,
|
||||
ratio);
|
||||
final double foregroundUsageConsumePower = interpolate(
|
||||
lowerHistEntry == null ? 0 : lowerHistEntry.mForegroundUsageConsumePower,
|
||||
upperHistEntry.mForegroundUsageConsumePower,
|
||||
ratio);
|
||||
final double foregroundServiceUsageConsumePower = interpolate(
|
||||
lowerHistEntry == null ? 0 : lowerHistEntry.mForegroundServiceUsageConsumePower,
|
||||
upperHistEntry.mForegroundServiceUsageConsumePower,
|
||||
ratio);
|
||||
final double backgroundUsageConsumePower = interpolate(
|
||||
lowerHistEntry == null ? 0 : lowerHistEntry.mBackgroundUsageConsumePower,
|
||||
upperHistEntry.mBackgroundUsageConsumePower,
|
||||
ratio);
|
||||
final double cachedUsageConsumePower = interpolate(
|
||||
lowerHistEntry == null ? 0 : lowerHistEntry.mCachedUsageConsumePower,
|
||||
upperHistEntry.mCachedUsageConsumePower,
|
||||
ratio);
|
||||
final double foregroundUsageTimeInMs = interpolate(
|
||||
lowerHistEntry == null ? 0 : lowerHistEntry.mForegroundUsageTimeInMs,
|
||||
upperHistEntry.mForegroundUsageTimeInMs,
|
||||
(double) (lowerHistEntry == null ? 0 : lowerHistEntry.mForegroundUsageTimeInMs),
|
||||
(double) upperHistEntry.mForegroundUsageTimeInMs,
|
||||
ratio);
|
||||
final double foregroundServiceUsageTimeInMs = interpolate(
|
||||
(double) (lowerHistEntry == null
|
||||
? 0
|
||||
: lowerHistEntry.mForegroundServiceUsageTimeInMs),
|
||||
(double) upperHistEntry.mForegroundServiceUsageTimeInMs,
|
||||
ratio);
|
||||
final double backgroundUsageTimeInMs = interpolate(
|
||||
lowerHistEntry == null ? 0 : lowerHistEntry.mBackgroundUsageTimeInMs,
|
||||
upperHistEntry.mBackgroundUsageTimeInMs,
|
||||
(double) (lowerHistEntry == null ? 0 : lowerHistEntry.mBackgroundUsageTimeInMs),
|
||||
(double) upperHistEntry.mBackgroundUsageTimeInMs,
|
||||
ratio);
|
||||
// Checks whether there is any abnormal cases!
|
||||
if (upperHistEntry.mConsumePower < consumePower
|
||||
|| upperHistEntry.mForegroundUsageConsumePower < foregroundUsageConsumePower
|
||||
|| upperHistEntry.mForegroundServiceUsageConsumePower
|
||||
< foregroundServiceUsageConsumePower
|
||||
|| upperHistEntry.mBackgroundUsageConsumePower < backgroundUsageConsumePower
|
||||
|| upperHistEntry.mCachedUsageConsumePower < cachedUsageConsumePower
|
||||
|| upperHistEntry.mForegroundUsageTimeInMs < foregroundUsageTimeInMs
|
||||
|| upperHistEntry.mForegroundServiceUsageTimeInMs < foregroundServiceUsageTimeInMs
|
||||
|| upperHistEntry.mBackgroundUsageTimeInMs < backgroundUsageTimeInMs) {
|
||||
if (DEBUG) {
|
||||
Log.w(TAG, String.format(
|
||||
@@ -299,7 +360,12 @@ public class BatteryHistEntry {
|
||||
/*timestamp=*/ slotTimestamp,
|
||||
totalPower,
|
||||
consumePower,
|
||||
foregroundUsageConsumePower,
|
||||
foregroundServiceUsageConsumePower,
|
||||
backgroundUsageConsumePower,
|
||||
cachedUsageConsumePower,
|
||||
Math.round(foregroundUsageTimeInMs),
|
||||
Math.round(foregroundServiceUsageTimeInMs),
|
||||
Math.round(backgroundUsageTimeInMs),
|
||||
(int) Math.round(batteryLevel));
|
||||
}
|
||||
|
@@ -23,46 +23,22 @@ import android.os.BatteryUsageStats;
|
||||
import android.os.Build;
|
||||
import android.os.LocaleList;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.text.format.DateFormat;
|
||||
import android.text.format.DateUtils;
|
||||
import android.util.ArraySet;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import com.android.settings.Utils;
|
||||
import com.android.settings.fuelgauge.BatteryUtils;
|
||||
import com.android.settings.overlay.FeatureFactory;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.time.Duration;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
/** A utility class to convert data into another types. */
|
||||
public final class ConvertUtils {
|
||||
private static final boolean DEBUG = false;
|
||||
private static final String TAG = "ConvertUtils";
|
||||
private static final Map<String, BatteryHistEntry> EMPTY_BATTERY_MAP = new HashMap<>();
|
||||
private static final BatteryHistEntry EMPTY_BATTERY_HIST_ENTRY =
|
||||
new BatteryHistEntry(new ContentValues());
|
||||
// Maximum total time value for each slot cumulative data at most 2 hours.
|
||||
private static final float TOTAL_TIME_THRESHOLD = DateUtils.HOUR_IN_MILLIS * 2;
|
||||
|
||||
@VisibleForTesting
|
||||
static double PERCENTAGE_OF_TOTAL_THRESHOLD = 1f;
|
||||
|
||||
/** Invalid system battery consumer drain type. */
|
||||
public static final int INVALID_DRAIN_TYPE = -1;
|
||||
/** A fake package name to represent no BatteryEntry data. */
|
||||
public static final String FAKE_PACKAGE_NAME = "fake_package";
|
||||
|
||||
@@ -198,167 +174,15 @@ public final class ConvertUtils {
|
||||
return DateFormat.format(pattern, timestamp).toString();
|
||||
}
|
||||
|
||||
/** Gets indexed battery usage data for each corresponding time slot. */
|
||||
public static Map<Integer, List<BatteryDiffEntry>> getIndexedUsageMap(
|
||||
final Context context,
|
||||
final int timeSlotSize,
|
||||
final long[] batteryHistoryKeys,
|
||||
final Map<Long, Map<String, BatteryHistEntry>> batteryHistoryMap,
|
||||
final boolean purgeLowPercentageAndFakeData) {
|
||||
if (batteryHistoryMap == null || batteryHistoryMap.isEmpty()) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
final Map<Integer, List<BatteryDiffEntry>> resultMap = new HashMap<>();
|
||||
// Each time slot usage diff data =
|
||||
// Math.abs(timestamp[i+2] data - timestamp[i+1] data) +
|
||||
// Math.abs(timestamp[i+1] data - timestamp[i] data);
|
||||
// since we want to aggregate every two hours data into a single time slot.
|
||||
final int timestampStride = 2;
|
||||
for (int index = 0; index < timeSlotSize; index++) {
|
||||
final Long currentTimestamp =
|
||||
Long.valueOf(batteryHistoryKeys[index * timestampStride]);
|
||||
final Long nextTimestamp =
|
||||
Long.valueOf(batteryHistoryKeys[index * timestampStride + 1]);
|
||||
final Long nextTwoTimestamp =
|
||||
Long.valueOf(batteryHistoryKeys[index * timestampStride + 2]);
|
||||
// Fetches BatteryHistEntry data from corresponding time slot.
|
||||
final Map<String, BatteryHistEntry> currentBatteryHistMap =
|
||||
batteryHistoryMap.getOrDefault(currentTimestamp, EMPTY_BATTERY_MAP);
|
||||
final Map<String, BatteryHistEntry> nextBatteryHistMap =
|
||||
batteryHistoryMap.getOrDefault(nextTimestamp, EMPTY_BATTERY_MAP);
|
||||
final Map<String, BatteryHistEntry> nextTwoBatteryHistMap =
|
||||
batteryHistoryMap.getOrDefault(nextTwoTimestamp, EMPTY_BATTERY_MAP);
|
||||
// We should not get the empty list since we have at least one fake data to record
|
||||
// the battery level and status in each time slot, the empty list is used to
|
||||
// represent there is no enough data to apply interpolation arithmetic.
|
||||
if (currentBatteryHistMap.isEmpty()
|
||||
|| nextBatteryHistMap.isEmpty()
|
||||
|| nextTwoBatteryHistMap.isEmpty()) {
|
||||
resultMap.put(Integer.valueOf(index), new ArrayList<BatteryDiffEntry>());
|
||||
continue;
|
||||
}
|
||||
|
||||
// Collects all keys in these three time slot records as all populations.
|
||||
final Set<String> allBatteryHistEntryKeys = new ArraySet<>();
|
||||
allBatteryHistEntryKeys.addAll(currentBatteryHistMap.keySet());
|
||||
allBatteryHistEntryKeys.addAll(nextBatteryHistMap.keySet());
|
||||
allBatteryHistEntryKeys.addAll(nextTwoBatteryHistMap.keySet());
|
||||
|
||||
double totalConsumePower = 0.0;
|
||||
final List<BatteryDiffEntry> batteryDiffEntryList = new ArrayList<>();
|
||||
// Adds a specific time slot BatteryDiffEntry list into result map.
|
||||
resultMap.put(Integer.valueOf(index), batteryDiffEntryList);
|
||||
|
||||
// Calculates all packages diff usage data in a specific time slot.
|
||||
for (String key : allBatteryHistEntryKeys) {
|
||||
final BatteryHistEntry currentEntry =
|
||||
currentBatteryHistMap.getOrDefault(key, EMPTY_BATTERY_HIST_ENTRY);
|
||||
final BatteryHistEntry nextEntry =
|
||||
nextBatteryHistMap.getOrDefault(key, EMPTY_BATTERY_HIST_ENTRY);
|
||||
final BatteryHistEntry nextTwoEntry =
|
||||
nextTwoBatteryHistMap.getOrDefault(key, EMPTY_BATTERY_HIST_ENTRY);
|
||||
// Cumulative values is a specific time slot for a specific app.
|
||||
long foregroundUsageTimeInMs =
|
||||
getDiffValue(
|
||||
currentEntry.mForegroundUsageTimeInMs,
|
||||
nextEntry.mForegroundUsageTimeInMs,
|
||||
nextTwoEntry.mForegroundUsageTimeInMs);
|
||||
long backgroundUsageTimeInMs =
|
||||
getDiffValue(
|
||||
currentEntry.mBackgroundUsageTimeInMs,
|
||||
nextEntry.mBackgroundUsageTimeInMs,
|
||||
nextTwoEntry.mBackgroundUsageTimeInMs);
|
||||
double consumePower =
|
||||
getDiffValue(
|
||||
currentEntry.mConsumePower,
|
||||
nextEntry.mConsumePower,
|
||||
nextTwoEntry.mConsumePower);
|
||||
// Excludes entry since we don't have enough data to calculate.
|
||||
if (foregroundUsageTimeInMs == 0
|
||||
&& backgroundUsageTimeInMs == 0
|
||||
&& consumePower == 0) {
|
||||
continue;
|
||||
}
|
||||
final BatteryHistEntry selectedBatteryEntry =
|
||||
selectBatteryHistEntry(currentEntry, nextEntry, nextTwoEntry);
|
||||
if (selectedBatteryEntry == null) {
|
||||
continue;
|
||||
}
|
||||
// Forces refine the cumulative value since it may introduce deviation
|
||||
// error since we will apply the interpolation arithmetic.
|
||||
final float totalUsageTimeInMs =
|
||||
foregroundUsageTimeInMs + backgroundUsageTimeInMs;
|
||||
if (totalUsageTimeInMs > TOTAL_TIME_THRESHOLD) {
|
||||
final float ratio = TOTAL_TIME_THRESHOLD / totalUsageTimeInMs;
|
||||
if (DEBUG) {
|
||||
Log.w(TAG, String.format("abnormal usage time %d|%d for:\n%s",
|
||||
Duration.ofMillis(foregroundUsageTimeInMs).getSeconds(),
|
||||
Duration.ofMillis(backgroundUsageTimeInMs).getSeconds(),
|
||||
currentEntry));
|
||||
}
|
||||
foregroundUsageTimeInMs =
|
||||
Math.round(foregroundUsageTimeInMs * ratio);
|
||||
backgroundUsageTimeInMs =
|
||||
Math.round(backgroundUsageTimeInMs * ratio);
|
||||
consumePower = consumePower * ratio;
|
||||
}
|
||||
totalConsumePower += consumePower;
|
||||
batteryDiffEntryList.add(
|
||||
new BatteryDiffEntry(
|
||||
context,
|
||||
foregroundUsageTimeInMs,
|
||||
backgroundUsageTimeInMs,
|
||||
consumePower,
|
||||
selectedBatteryEntry));
|
||||
}
|
||||
// Sets total consume power data into all BatteryDiffEntry in the same slot.
|
||||
for (BatteryDiffEntry diffEntry : batteryDiffEntryList) {
|
||||
diffEntry.setTotalConsumePower(totalConsumePower);
|
||||
}
|
||||
}
|
||||
insert24HoursData(BatteryChartViewModel.SELECTED_INDEX_ALL, resultMap);
|
||||
resolveMultiUsersData(context, resultMap);
|
||||
if (purgeLowPercentageAndFakeData) {
|
||||
purgeLowPercentageAndFakeData(context, resultMap);
|
||||
}
|
||||
return resultMap;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static void resolveMultiUsersData(
|
||||
final Context context,
|
||||
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
||||
final int currentUserId = context.getUserId();
|
||||
final UserHandle userHandle =
|
||||
Utils.getManagedProfile(context.getSystemService(UserManager.class));
|
||||
final int workProfileUserId =
|
||||
userHandle != null ? userHandle.getIdentifier() : Integer.MIN_VALUE;
|
||||
// Loops for all BatteryDiffEntry in the different slots.
|
||||
for (List<BatteryDiffEntry> entryList : indexedUsageMap.values()) {
|
||||
double consumePowerFromOtherUsers = 0f;
|
||||
double consumePercentageFromOtherUsers = 0f;
|
||||
final Iterator<BatteryDiffEntry> iterator = entryList.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final BatteryDiffEntry entry = iterator.next();
|
||||
final BatteryHistEntry batteryHistEntry = entry.mBatteryHistEntry;
|
||||
if (batteryHistEntry.mConsumerType != CONSUMER_TYPE_UID_BATTERY) {
|
||||
continue;
|
||||
}
|
||||
// Whether the BatteryHistEntry represents the current user data?
|
||||
if (batteryHistEntry.mUserId == currentUserId
|
||||
|| batteryHistEntry.mUserId == workProfileUserId) {
|
||||
continue;
|
||||
}
|
||||
// Removes and aggregates non-current users data from the list.
|
||||
iterator.remove();
|
||||
consumePowerFromOtherUsers += entry.mConsumePower;
|
||||
consumePercentageFromOtherUsers += entry.getPercentOfTotal();
|
||||
}
|
||||
if (consumePercentageFromOtherUsers != 0) {
|
||||
entryList.add(createOtherUsersEntry(context, consumePowerFromOtherUsers,
|
||||
consumePercentageFromOtherUsers));
|
||||
}
|
||||
static Locale getLocale(Context context) {
|
||||
if (context == null) {
|
||||
return Locale.getDefault();
|
||||
}
|
||||
final LocaleList locales =
|
||||
context.getResources().getConfiguration().getLocales();
|
||||
return locales != null && !locales.isEmpty() ? locales.get(0)
|
||||
: Locale.getDefault();
|
||||
}
|
||||
|
||||
private static BatteryInformation constructBatteryInformation(
|
||||
@@ -387,121 +211,18 @@ public final class ConvertUtils {
|
||||
.setAppLabel(entry.getLabel() != null ? entry.getLabel() : "")
|
||||
.setTotalPower(batteryUsageStats.getConsumedPower())
|
||||
.setConsumePower(entry.getConsumedPower())
|
||||
.setForegroundUsageConsumePower(entry.getConsumedPowerInForeground())
|
||||
.setForegroundServiceUsageConsumePower(
|
||||
entry.getConsumedPowerInForegroundService())
|
||||
.setBackgroundUsageConsumePower(entry.getConsumedPowerInBackground())
|
||||
.setCachedUsageConsumePower(entry.getConsumedPowerInCached())
|
||||
.setPercentOfTotal(entry.mPercent)
|
||||
.setDrainType(entry.getPowerComponentId())
|
||||
.setForegroundUsageTimeInMs(entry.getTimeInForegroundMs())
|
||||
.setForegroundServiceUsageTimeInMs(entry.getTimeInForegroundServiceMs())
|
||||
.setBackgroundUsageTimeInMs(entry.getTimeInBackgroundMs());
|
||||
}
|
||||
|
||||
return batteryInformationBuilder.build();
|
||||
}
|
||||
|
||||
private static void insert24HoursData(
|
||||
final int desiredIndex,
|
||||
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
||||
final Map<String, BatteryDiffEntry> resultMap = new HashMap<>();
|
||||
double totalConsumePower = 0f;
|
||||
// Loops for all BatteryDiffEntry and aggregate them together.
|
||||
for (List<BatteryDiffEntry> entryList : indexedUsageMap.values()) {
|
||||
for (BatteryDiffEntry entry : entryList) {
|
||||
final String key = entry.mBatteryHistEntry.getKey();
|
||||
final BatteryDiffEntry oldBatteryDiffEntry = resultMap.get(key);
|
||||
// Creates new BatteryDiffEntry if we don't have it.
|
||||
if (oldBatteryDiffEntry == null) {
|
||||
resultMap.put(key, entry.clone());
|
||||
} else {
|
||||
// Sums up some fields data into the existing one.
|
||||
oldBatteryDiffEntry.mForegroundUsageTimeInMs +=
|
||||
entry.mForegroundUsageTimeInMs;
|
||||
oldBatteryDiffEntry.mBackgroundUsageTimeInMs +=
|
||||
entry.mBackgroundUsageTimeInMs;
|
||||
oldBatteryDiffEntry.mConsumePower += entry.mConsumePower;
|
||||
}
|
||||
totalConsumePower += entry.mConsumePower;
|
||||
}
|
||||
}
|
||||
final List<BatteryDiffEntry> resultList = new ArrayList<>(resultMap.values());
|
||||
// Sets total 24 hours consume power data into all BatteryDiffEntry.
|
||||
for (BatteryDiffEntry entry : resultList) {
|
||||
entry.setTotalConsumePower(totalConsumePower);
|
||||
}
|
||||
indexedUsageMap.put(Integer.valueOf(desiredIndex), resultList);
|
||||
}
|
||||
|
||||
// Removes low percentage data and fake usage data, which will be zero value.
|
||||
private static void purgeLowPercentageAndFakeData(
|
||||
final Context context,
|
||||
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {
|
||||
final Set<CharSequence> backgroundUsageTimeHideList =
|
||||
FeatureFactory.getFactory(context)
|
||||
.getPowerUsageFeatureProvider(context)
|
||||
.getHideBackgroundUsageTimeSet(context);
|
||||
for (List<BatteryDiffEntry> entries : indexedUsageMap.values()) {
|
||||
final Iterator<BatteryDiffEntry> iterator = entries.iterator();
|
||||
while (iterator.hasNext()) {
|
||||
final BatteryDiffEntry entry = iterator.next();
|
||||
if (entry.getPercentOfTotal() < PERCENTAGE_OF_TOTAL_THRESHOLD
|
||||
|| FAKE_PACKAGE_NAME.equals(entry.getPackageName())) {
|
||||
iterator.remove();
|
||||
}
|
||||
final String packageName = entry.getPackageName();
|
||||
if (packageName != null
|
||||
&& !backgroundUsageTimeHideList.isEmpty()
|
||||
&& backgroundUsageTimeHideList.contains(packageName)) {
|
||||
entry.mBackgroundUsageTimeInMs = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static long getDiffValue(long v1, long v2, long v3) {
|
||||
return (v2 > v1 ? v2 - v1 : 0) + (v3 > v2 ? v3 - v2 : 0);
|
||||
}
|
||||
|
||||
private static double getDiffValue(double v1, double v2, double v3) {
|
||||
return (v2 > v1 ? v2 - v1 : 0) + (v3 > v2 ? v3 - v2 : 0);
|
||||
}
|
||||
|
||||
private static BatteryHistEntry selectBatteryHistEntry(
|
||||
BatteryHistEntry entry1,
|
||||
BatteryHistEntry entry2,
|
||||
BatteryHistEntry entry3) {
|
||||
if (entry1 != null && entry1 != EMPTY_BATTERY_HIST_ENTRY) {
|
||||
return entry1;
|
||||
} else if (entry2 != null && entry2 != EMPTY_BATTERY_HIST_ENTRY) {
|
||||
return entry2;
|
||||
} else {
|
||||
return entry3 != null && entry3 != EMPTY_BATTERY_HIST_ENTRY
|
||||
? entry3 : null;
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static Locale getLocale(Context context) {
|
||||
if (context == null) {
|
||||
return Locale.getDefault();
|
||||
}
|
||||
final LocaleList locales =
|
||||
context.getResources().getConfiguration().getLocales();
|
||||
return locales != null && !locales.isEmpty() ? locales.get(0)
|
||||
: Locale.getDefault();
|
||||
}
|
||||
|
||||
private static BatteryDiffEntry createOtherUsersEntry(
|
||||
Context context, double consumePower, double consumePercentage) {
|
||||
final ContentValues values = new ContentValues();
|
||||
values.put(BatteryHistEntry.KEY_UID, BatteryUtils.UID_OTHER_USERS);
|
||||
values.put(BatteryHistEntry.KEY_USER_ID, BatteryUtils.UID_OTHER_USERS);
|
||||
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE, CONSUMER_TYPE_UID_BATTERY);
|
||||
// We will show the percentage for the "other users" item only, the aggregated
|
||||
// running time information is useless for users to identify individual apps.
|
||||
final BatteryDiffEntry batteryDiffEntry = new BatteryDiffEntry(
|
||||
context,
|
||||
/*foregroundUsageTimeInMs=*/ 0,
|
||||
/*backgroundUsageTimeInMs=*/ 0,
|
||||
consumePower,
|
||||
new BatteryHistEntry(values));
|
||||
batteryDiffEntry.setTotalConsumePower(100 * consumePower / consumePercentage);
|
||||
return batteryDiffEntry;
|
||||
}
|
||||
}
|
||||
|
@@ -87,9 +87,6 @@ public final class DataProcessor {
|
||||
@VisibleForTesting
|
||||
static final int SELECTED_INDEX_ALL = BatteryChartViewModel.SELECTED_INDEX_ALL;
|
||||
|
||||
/** A fake package name to represent no BatteryEntry data. */
|
||||
public static final String FAKE_PACKAGE_NAME = "fake_package";
|
||||
|
||||
/** A callback listener when battery usage loading async task is executed. */
|
||||
public interface UsageMapAsyncResponse {
|
||||
/** The callback function when batteryUsageMap is loaded. */
|
||||
@@ -174,7 +171,11 @@ public final class DataProcessor {
|
||||
@Nullable
|
||||
public static BatteryUsageStats getBatteryUsageStats(final Context context) {
|
||||
final BatteryUsageStatsQuery batteryUsageStatsQuery =
|
||||
new BatteryUsageStatsQuery.Builder().includeBatteryHistory().build();
|
||||
new BatteryUsageStatsQuery
|
||||
.Builder()
|
||||
.includeBatteryHistory()
|
||||
.includeProcessStateData()
|
||||
.build();
|
||||
return context.getSystemService(BatteryStatsManager.class)
|
||||
.getBatteryUsageStats(batteryUsageStatsQuery);
|
||||
}
|
||||
@@ -478,8 +479,13 @@ public final class DataProcessor {
|
||||
final BatteryDiffEntry currentBatteryDiffEntry = new BatteryDiffEntry(
|
||||
context,
|
||||
entry.mForegroundUsageTimeInMs,
|
||||
entry.mForegroundServiceUsageTimeInMs,
|
||||
entry.mBackgroundUsageTimeInMs,
|
||||
entry.mConsumePower,
|
||||
entry.mForegroundUsageConsumePower,
|
||||
entry.mForegroundServiceUsageConsumePower,
|
||||
entry.mBackgroundUsageConsumePower,
|
||||
entry.mCachedUsageConsumePower,
|
||||
entry);
|
||||
if (currentBatteryDiffEntry.isSystemEntry()) {
|
||||
systemEntries.add(currentBatteryDiffEntry);
|
||||
@@ -567,10 +573,12 @@ public final class DataProcessor {
|
||||
return batteryEntryList.stream()
|
||||
.filter(entry -> {
|
||||
final long foregroundMs = entry.getTimeInForegroundMs();
|
||||
final long foregroundServiceMs = entry.getTimeInForegroundServiceMs();
|
||||
final long backgroundMs = entry.getTimeInBackgroundMs();
|
||||
return entry.getConsumedPower() > 0
|
||||
|| (entry.getConsumedPower() == 0
|
||||
&& (foregroundMs != 0 || backgroundMs != 0));
|
||||
&& (foregroundMs != 0 || foregroundServiceMs != 0
|
||||
|| backgroundMs != 0));
|
||||
})
|
||||
.map(entry -> ConvertUtils.convertToBatteryHistEntry(
|
||||
entry,
|
||||
@@ -691,9 +699,14 @@ public final class DataProcessor {
|
||||
if (lowerEntry != null) {
|
||||
final boolean invalidForegroundUsageTime =
|
||||
lowerEntry.mForegroundUsageTimeInMs > upperEntry.mForegroundUsageTimeInMs;
|
||||
final boolean invalidForegroundServiceUsageTime =
|
||||
lowerEntry.mForegroundServiceUsageTimeInMs
|
||||
> upperEntry.mForegroundServiceUsageTimeInMs;
|
||||
final boolean invalidBackgroundUsageTime =
|
||||
lowerEntry.mBackgroundUsageTimeInMs > upperEntry.mBackgroundUsageTimeInMs;
|
||||
if (invalidForegroundUsageTime || invalidBackgroundUsageTime) {
|
||||
if (invalidForegroundUsageTime
|
||||
|| invalidForegroundServiceUsageTime
|
||||
|| invalidBackgroundUsageTime) {
|
||||
newHistEntryMap.put(entryKey, upperEntry);
|
||||
log(context, "abnormal reset condition is found", currentSlot, upperEntry);
|
||||
continue;
|
||||
@@ -924,6 +937,11 @@ public final class DataProcessor {
|
||||
currentEntry.mForegroundUsageTimeInMs,
|
||||
nextEntry.mForegroundUsageTimeInMs,
|
||||
nextTwoEntry.mForegroundUsageTimeInMs);
|
||||
long foregroundServiceUsageTimeInMs =
|
||||
getDiffValue(
|
||||
currentEntry.mForegroundServiceUsageTimeInMs,
|
||||
nextEntry.mForegroundServiceUsageTimeInMs,
|
||||
nextTwoEntry.mForegroundServiceUsageTimeInMs);
|
||||
long backgroundUsageTimeInMs =
|
||||
getDiffValue(
|
||||
currentEntry.mBackgroundUsageTimeInMs,
|
||||
@@ -934,8 +952,29 @@ public final class DataProcessor {
|
||||
currentEntry.mConsumePower,
|
||||
nextEntry.mConsumePower,
|
||||
nextTwoEntry.mConsumePower);
|
||||
double foregroundUsageConsumePower =
|
||||
getDiffValue(
|
||||
currentEntry.mForegroundUsageConsumePower,
|
||||
nextEntry.mForegroundUsageConsumePower,
|
||||
nextTwoEntry.mForegroundUsageConsumePower);
|
||||
double foregroundServiceUsageConsumePower =
|
||||
getDiffValue(
|
||||
currentEntry.mForegroundServiceUsageConsumePower,
|
||||
nextEntry.mForegroundServiceUsageConsumePower,
|
||||
nextTwoEntry.mForegroundServiceUsageConsumePower);
|
||||
double backgroundUsageConsumePower =
|
||||
getDiffValue(
|
||||
currentEntry.mBackgroundUsageConsumePower,
|
||||
nextEntry.mBackgroundUsageConsumePower,
|
||||
nextTwoEntry.mBackgroundUsageConsumePower);
|
||||
double cachedUsageConsumePower =
|
||||
getDiffValue(
|
||||
currentEntry.mCachedUsageConsumePower,
|
||||
nextEntry.mCachedUsageConsumePower,
|
||||
nextTwoEntry.mCachedUsageConsumePower);
|
||||
// Excludes entry since we don't have enough data to calculate.
|
||||
if (foregroundUsageTimeInMs == 0
|
||||
&& foregroundServiceUsageTimeInMs == 0
|
||||
&& backgroundUsageTimeInMs == 0
|
||||
&& consumePower == 0) {
|
||||
continue;
|
||||
@@ -947,6 +986,7 @@ public final class DataProcessor {
|
||||
}
|
||||
// Forces refine the cumulative value since it may introduce deviation error since we
|
||||
// will apply the interpolation arithmetic.
|
||||
// TODO: update this value after the new API for foreground service is completed.
|
||||
final float totalUsageTimeInMs =
|
||||
foregroundUsageTimeInMs + backgroundUsageTimeInMs;
|
||||
if (totalUsageTimeInMs > TOTAL_HOURLY_TIME_THRESHOLD) {
|
||||
@@ -959,9 +999,15 @@ public final class DataProcessor {
|
||||
}
|
||||
foregroundUsageTimeInMs =
|
||||
Math.round(foregroundUsageTimeInMs * ratio);
|
||||
foregroundServiceUsageTimeInMs =
|
||||
Math.round(foregroundServiceUsageTimeInMs * ratio);
|
||||
backgroundUsageTimeInMs =
|
||||
Math.round(backgroundUsageTimeInMs * ratio);
|
||||
consumePower = consumePower * ratio;
|
||||
foregroundUsageConsumePower = foregroundUsageConsumePower * ratio;
|
||||
foregroundServiceUsageConsumePower = foregroundServiceUsageConsumePower * ratio;
|
||||
backgroundUsageConsumePower = backgroundUsageConsumePower * ratio;
|
||||
cachedUsageConsumePower = cachedUsageConsumePower * ratio;
|
||||
}
|
||||
totalConsumePower += consumePower;
|
||||
|
||||
@@ -973,8 +1019,13 @@ public final class DataProcessor {
|
||||
final BatteryDiffEntry currentBatteryDiffEntry = new BatteryDiffEntry(
|
||||
context,
|
||||
foregroundUsageTimeInMs,
|
||||
foregroundServiceUsageTimeInMs,
|
||||
backgroundUsageTimeInMs,
|
||||
consumePower,
|
||||
foregroundUsageConsumePower,
|
||||
foregroundServiceUsageConsumePower,
|
||||
backgroundUsageConsumePower,
|
||||
cachedUsageConsumePower,
|
||||
selectedBatteryEntry);
|
||||
if (currentBatteryDiffEntry.isSystemEntry()) {
|
||||
systemEntries.add(currentBatteryDiffEntry);
|
||||
@@ -1054,9 +1105,16 @@ public final class DataProcessor {
|
||||
// Sums up some field data into the existing one.
|
||||
oldBatteryDiffEntry.mForegroundUsageTimeInMs +=
|
||||
entry.mForegroundUsageTimeInMs;
|
||||
oldBatteryDiffEntry.mForegroundServiceUsageTimeInMs +=
|
||||
entry.mForegroundServiceUsageTimeInMs;
|
||||
oldBatteryDiffEntry.mBackgroundUsageTimeInMs +=
|
||||
entry.mBackgroundUsageTimeInMs;
|
||||
oldBatteryDiffEntry.mConsumePower += entry.mConsumePower;
|
||||
oldBatteryDiffEntry.mForegroundUsageConsumePower += entry.mForegroundUsageConsumePower;
|
||||
oldBatteryDiffEntry.mForegroundServiceUsageConsumePower
|
||||
+= entry.mForegroundServiceUsageConsumePower;
|
||||
oldBatteryDiffEntry.mBackgroundUsageConsumePower += entry.mBackgroundUsageConsumePower;
|
||||
oldBatteryDiffEntry.mCachedUsageConsumePower += entry.mCachedUsageConsumePower;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1097,7 +1155,7 @@ public final class DataProcessor {
|
||||
final BatteryDiffEntry entry = iterator.next();
|
||||
final String packageName = entry.getPackageName();
|
||||
if (entry.getPercentOfTotal() < PERCENTAGE_OF_TOTAL_THRESHOLD
|
||||
|| FAKE_PACKAGE_NAME.equals(packageName)
|
||||
|| ConvertUtils.FAKE_PACKAGE_NAME.equals(packageName)
|
||||
|| contains(packageName, notAllowShowEntryPackages)) {
|
||||
iterator.remove();
|
||||
}
|
||||
@@ -1346,8 +1404,13 @@ public final class DataProcessor {
|
||||
final BatteryDiffEntry batteryDiffEntry = new BatteryDiffEntry(
|
||||
context,
|
||||
/*foregroundUsageTimeInMs=*/ 0,
|
||||
/*foregroundServiceUsageTimeInMs=*/ 0,
|
||||
/*backgroundUsageTimeInMs=*/ 0,
|
||||
consumePower,
|
||||
/*foregroundUsageConsumePower=*/ 0,
|
||||
/*foregroundServiceUsageConsumePower=*/ 0,
|
||||
/*backgroundUsageConsumePower=*/ 0,
|
||||
/*cachedUsageConsumePower=*/ 0,
|
||||
new BatteryHistEntry(values));
|
||||
return batteryDiffEntry;
|
||||
}
|
||||
|
@@ -164,15 +164,20 @@ public final class DatabaseUtils {
|
||||
batteryEntryList.stream()
|
||||
.filter(entry -> {
|
||||
final long foregroundMs = entry.getTimeInForegroundMs();
|
||||
final long foregroundServiceMs = entry.getTimeInForegroundServiceMs();
|
||||
final long backgroundMs = entry.getTimeInBackgroundMs();
|
||||
if (entry.getConsumedPower() == 0
|
||||
&& (foregroundMs != 0 || backgroundMs != 0)) {
|
||||
&& (foregroundMs != 0
|
||||
|| foregroundServiceMs != 0
|
||||
|| backgroundMs != 0)) {
|
||||
Log.w(TAG, String.format(
|
||||
"no consumed power but has running time for %s time=%d|%d",
|
||||
entry.getLabel(), foregroundMs, backgroundMs));
|
||||
"no consumed power but has running time for %s time=%d|%d|%d",
|
||||
entry.getLabel(), foregroundMs, foregroundServiceMs,
|
||||
backgroundMs));
|
||||
}
|
||||
return entry.getConsumedPower() != 0
|
||||
|| foregroundMs != 0
|
||||
|| foregroundServiceMs != 0
|
||||
|| backgroundMs != 0;
|
||||
})
|
||||
.forEach(entry -> valuesList.add(
|
||||
|
Reference in New Issue
Block a user