Database restructure: use protobuf to save battery information fields.

This patch only updates the existing fields.
There will be 2 following patches to:
1. Expose the new fields (foreground / foreground service / background x
   usage time / power consumption) to UI.
2. Get the full charge cycle start time from Database and remove the
   SharedPreference.

Test: make RunSettingsRoboTests + manual
Bug: 253553141
Change-Id: Iee02dc7e671f97899cb1495323acfa0173e31df2
This commit is contained in:
Kuan Wang
2022-11-09 16:24:23 +08:00
parent 45c9b11655
commit 1493fa2fea
19 changed files with 528 additions and 513 deletions

View File

@@ -19,13 +19,10 @@ package com.android.settings.fuelgauge;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Base64;
import android.util.Log;
import com.android.settings.fuelgauge.BatteryOptimizeHistoricalLogEntry.Action;
import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite;
import java.io.PrintWriter;
import java.util.List;
@@ -76,22 +73,8 @@ public final class BatteryHistoricalLogUtil {
}
private static BatteryOptimizeHistoricalLog parseLogFromString(String storedLogs) {
return parseProtoFromString(storedLogs, BatteryOptimizeHistoricalLog.getDefaultInstance());
}
@SuppressWarnings("unchecked")
private static <T extends MessageLite> T parseProtoFromString(
String serializedProto, T protoClass) {
if (serializedProto.isEmpty()) {
return (T) protoClass.getDefaultInstanceForType();
}
try {
return (T) protoClass.getParserForType()
.parseFrom(Base64.decode(serializedProto, Base64.DEFAULT));
} catch (InvalidProtocolBufferException e) {
Log.e(TAG, "Failed to deserialize proto class", e);
return (T) protoClass.getDefaultInstanceForType();
}
return BatteryUtils.parseProtoFromString(
storedLogs, BatteryOptimizeHistoricalLog.getDefaultInstance());
}
/**

View File

@@ -32,6 +32,7 @@ import android.os.Process;
import android.os.SystemClock;
import android.os.UidBatteryConsumer;
import android.os.UserHandle;
import android.util.Base64;
import android.util.Log;
import androidx.annotation.IntDef;
@@ -52,6 +53,9 @@ import com.android.settingslib.fuelgauge.PowerAllowlistBackend;
import com.android.settingslib.utils.PowerUtil;
import com.android.settingslib.utils.ThreadUtils;
import com.google.protobuf.InvalidProtocolBufferException;
import com.google.protobuf.MessageLite;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.time.Duration;
@@ -316,6 +320,28 @@ public class BatteryUtils {
}
}
/**
* Parses proto object from string.
*
* @param serializedProto the serialized proto string
* @param protoClass class of the proto
* @return instance of the proto class parsed from the string
*/
@SuppressWarnings("unchecked")
public static <T extends MessageLite> T parseProtoFromString(
String serializedProto, T protoClass) {
if (serializedProto.isEmpty()) {
return (T) protoClass.getDefaultInstanceForType();
}
try {
return (T) protoClass.getParserForType()
.parseFrom(Base64.decode(serializedProto, Base64.DEFAULT));
} catch (InvalidProtocolBufferException e) {
Log.e(TAG, "Failed to deserialize proto class", e);
return (T) protoClass.getDefaultInstanceForType();
}
}
public void setForceAppStandby(int uid, String packageName,
int mode) {
final boolean isPreOApp = isPreOApp(packageName);

View File

@@ -30,23 +30,12 @@ public class BatteryHistEntry {
/** Keys for accessing {@link ContentValues} or {@link Cursor}. */
public static final String KEY_UID = "uid";
public static final String KEY_USER_ID = "userId";
public static final String KEY_APP_LABEL = "appLabel";
public static final String KEY_PACKAGE_NAME = "packageName";
public static final String KEY_IS_HIDDEN = "isHidden";
// Device booting elapsed time from SystemClock.elapsedRealtime().
public static final String KEY_BOOT_TIMESTAMP = "bootTimestamp";
public static final String KEY_TIMESTAMP = "timestamp";
public static final String KEY_ZONE_ID = "zoneId";
public static final String KEY_TOTAL_POWER = "totalPower";
public static final String KEY_CONSUME_POWER = "consumePower";
public static final String KEY_PERCENT_OF_TOTAL = "percentOfTotal";
public static final String KEY_FOREGROUND_USAGE_TIME = "foregroundUsageTimeInMs";
public static final String KEY_BACKGROUND_USAGE_TIME = "backgroundUsageTimeInMs";
public static final String KEY_DRAIN_TYPE = "drainType";
public static final String KEY_CONSUMER_TYPE = "consumerType";
public static final String KEY_BATTERY_LEVEL = "batteryLevel";
public static final String KEY_BATTERY_STATUS = "batteryStatus";
public static final String KEY_BATTERY_HEALTH = "batteryHealth";
public static final String KEY_IS_FULL_CHARGE_CYCLE_START = "isFullChargeCycleStart";
public static final String KEY_BATTERY_INFORMATION = "batteryInformation";
public static final String KEY_BATTERY_INFORMATION_DEBUG = "batteryInformationDebug";
public final long mUid;
public final long mUserId;
@@ -79,43 +68,49 @@ public class BatteryHistEntry {
public BatteryHistEntry(ContentValues values) {
mUid = getLong(values, KEY_UID);
mUserId = getLong(values, KEY_USER_ID);
mAppLabel = getString(values, KEY_APP_LABEL);
mPackageName = getString(values, KEY_PACKAGE_NAME);
mIsHidden = getBoolean(values, KEY_IS_HIDDEN);
mBootTimestamp = getLong(values, KEY_BOOT_TIMESTAMP);
mTimestamp = getLong(values, KEY_TIMESTAMP);
mZoneId = getString(values, KEY_ZONE_ID);
mTotalPower = getDouble(values, KEY_TOTAL_POWER);
mConsumePower = getDouble(values, KEY_CONSUME_POWER);
mPercentOfTotal = getDouble(values, KEY_PERCENT_OF_TOTAL);
mForegroundUsageTimeInMs = getLong(values, KEY_FOREGROUND_USAGE_TIME);
mBackgroundUsageTimeInMs = getLong(values, KEY_BACKGROUND_USAGE_TIME);
mDrainType = getInteger(values, KEY_DRAIN_TYPE);
mConsumerType = getInteger(values, KEY_CONSUMER_TYPE);
mBatteryLevel = getInteger(values, KEY_BATTERY_LEVEL);
mBatteryStatus = getInteger(values, KEY_BATTERY_STATUS);
mBatteryHealth = getInteger(values, KEY_BATTERY_HEALTH);
final BatteryInformation batteryInformation =
ConvertUtils.getBatteryInformation(values, KEY_BATTERY_INFORMATION);
mAppLabel = batteryInformation.getAppLabel();
mIsHidden = batteryInformation.getIsHidden();
mBootTimestamp = batteryInformation.getBootTimestamp();
mZoneId = batteryInformation.getZoneId();
mTotalPower = batteryInformation.getTotalPower();
mConsumePower = batteryInformation.getConsumePower();
mPercentOfTotal = batteryInformation.getPercentOfTotal();
mForegroundUsageTimeInMs = batteryInformation.getForegroundUsageTimeInMs();
mBackgroundUsageTimeInMs = batteryInformation.getBackgroundUsageTimeInMs();
mDrainType = batteryInformation.getDrainType();
final DeviceBatteryState deviceBatteryState = batteryInformation.getDeviceBatteryState();
mBatteryLevel = deviceBatteryState.getBatteryLevel();
mBatteryStatus = deviceBatteryState.getBatteryStatus();
mBatteryHealth = deviceBatteryState.getBatteryHealth();
}
public BatteryHistEntry(Cursor cursor) {
mUid = getLong(cursor, KEY_UID);
mUserId = getLong(cursor, KEY_USER_ID);
mAppLabel = getString(cursor, KEY_APP_LABEL);
mPackageName = getString(cursor, KEY_PACKAGE_NAME);
mIsHidden = getBoolean(cursor, KEY_IS_HIDDEN);
mBootTimestamp = getLong(cursor, KEY_BOOT_TIMESTAMP);
mTimestamp = getLong(cursor, KEY_TIMESTAMP);
mZoneId = getString(cursor, KEY_ZONE_ID);
mTotalPower = getDouble(cursor, KEY_TOTAL_POWER);
mConsumePower = getDouble(cursor, KEY_CONSUME_POWER);
mPercentOfTotal = getDouble(cursor, KEY_PERCENT_OF_TOTAL);
mForegroundUsageTimeInMs = getLong(cursor, KEY_FOREGROUND_USAGE_TIME);
mBackgroundUsageTimeInMs = getLong(cursor, KEY_BACKGROUND_USAGE_TIME);
mDrainType = getInteger(cursor, KEY_DRAIN_TYPE);
mConsumerType = getInteger(cursor, KEY_CONSUMER_TYPE);
mBatteryLevel = getInteger(cursor, KEY_BATTERY_LEVEL);
mBatteryStatus = getInteger(cursor, KEY_BATTERY_STATUS);
mBatteryHealth = getInteger(cursor, KEY_BATTERY_HEALTH);
final BatteryInformation batteryInformation =
ConvertUtils.getBatteryInformation(cursor, KEY_BATTERY_INFORMATION);
mAppLabel = batteryInformation.getAppLabel();
mIsHidden = batteryInformation.getIsHidden();
mBootTimestamp = batteryInformation.getBootTimestamp();
mZoneId = batteryInformation.getZoneId();
mTotalPower = batteryInformation.getTotalPower();
mConsumePower = batteryInformation.getConsumePower();
mPercentOfTotal = batteryInformation.getPercentOfTotal();
mForegroundUsageTimeInMs = batteryInformation.getForegroundUsageTimeInMs();
mBackgroundUsageTimeInMs = batteryInformation.getBackgroundUsageTimeInMs();
mDrainType = batteryInformation.getDrainType();
final DeviceBatteryState deviceBatteryState = batteryInformation.getDeviceBatteryState();
mBatteryLevel = deviceBatteryState.getBatteryLevel();
mBatteryStatus = deviceBatteryState.getBatteryStatus();
mBatteryHealth = deviceBatteryState.getBatteryHealth();
}
private BatteryHistEntry(
@@ -240,23 +235,6 @@ public class BatteryHistEntry {
return 0L;
}
private double getDouble(ContentValues values, String key) {
if (values != null && values.containsKey(key)) {
return values.getAsDouble(key);
}
mIsValidEntry = false;
return 0f;
}
private double getDouble(Cursor cursor, String key) {
final int columnIndex = cursor.getColumnIndex(key);
if (columnIndex >= 0) {
return cursor.getDouble(columnIndex);
}
mIsValidEntry = false;
return 0f;
}
private String getString(ContentValues values, String key) {
if (values != null && values.containsKey(key)) {
return values.getAsString(key);
@@ -274,24 +252,6 @@ public class BatteryHistEntry {
return null;
}
private boolean getBoolean(ContentValues values, String key) {
if (values != null && values.containsKey(key)) {
return values.getAsBoolean(key);
}
mIsValidEntry = false;
return false;
}
private boolean getBoolean(Cursor cursor, String key) {
final int columnIndex = cursor.getColumnIndex(key);
if (columnIndex >= 0) {
// Use value == 1 to represent boolean value in the database.
return cursor.getInt(columnIndex) == 1;
}
mIsValidEntry = false;
return false;
}
/** Creates new {@link BatteryHistEntry} from interpolation. */
public static BatteryHistEntry interpolate(
long slotTimestamp,
@@ -315,7 +275,7 @@ public class BatteryHistEntry {
lowerHistEntry == null ? 0 : lowerHistEntry.mBackgroundUsageTimeInMs,
upperHistEntry.mBackgroundUsageTimeInMs,
ratio);
// Checks whether there is any abnoaml cases!
// Checks whether there is any abnormal cases!
if (upperHistEntry.mConsumePower < consumePower
|| upperHistEntry.mForegroundUsageTimeInMs < foregroundUsageTimeInMs
|| upperHistEntry.mBackgroundUsageTimeInMs < backgroundUsageTimeInMs) {

View File

@@ -18,13 +18,16 @@ package com.android.settings.fuelgauge.batteryusage;
import android.annotation.IntDef;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
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;
@@ -83,48 +86,71 @@ public final class ConvertUtils {
/** Converts to content values */
public static ContentValues convertToContentValues(
BatteryEntry entry,
BatteryUsageStats batteryUsageStats,
int batteryLevel,
int batteryStatus,
int batteryHealth,
long bootTimestamp,
long timestamp) {
final BatteryEntry entry,
final BatteryUsageStats batteryUsageStats,
final int batteryLevel,
final int batteryStatus,
final int batteryHealth,
final long bootTimestamp,
final long timestamp) {
final ContentValues values = new ContentValues();
if (entry != null && batteryUsageStats != null) {
values.put(BatteryHistEntry.KEY_UID, Long.valueOf(entry.getUid()));
values.put(BatteryHistEntry.KEY_USER_ID,
Long.valueOf(UserHandle.getUserId(entry.getUid())));
values.put(BatteryHistEntry.KEY_APP_LABEL, entry.getLabel());
values.put(BatteryHistEntry.KEY_PACKAGE_NAME,
entry.getDefaultPackageName());
values.put(BatteryHistEntry.KEY_IS_HIDDEN, Boolean.valueOf(entry.isHidden()));
values.put(BatteryHistEntry.KEY_TOTAL_POWER,
Double.valueOf(batteryUsageStats.getConsumedPower()));
values.put(BatteryHistEntry.KEY_CONSUME_POWER,
Double.valueOf(entry.getConsumedPower()));
values.put(BatteryHistEntry.KEY_PERCENT_OF_TOTAL,
Double.valueOf(entry.mPercent));
values.put(BatteryHistEntry.KEY_FOREGROUND_USAGE_TIME,
Long.valueOf(entry.getTimeInForegroundMs()));
values.put(BatteryHistEntry.KEY_BACKGROUND_USAGE_TIME,
Long.valueOf(entry.getTimeInBackgroundMs()));
values.put(BatteryHistEntry.KEY_DRAIN_TYPE,
Integer.valueOf(entry.getPowerComponentId()));
values.put(BatteryHistEntry.KEY_CONSUMER_TYPE,
Integer.valueOf(entry.getConsumerType()));
} else {
values.put(BatteryHistEntry.KEY_PACKAGE_NAME, FAKE_PACKAGE_NAME);
}
values.put(BatteryHistEntry.KEY_BOOT_TIMESTAMP, Long.valueOf(bootTimestamp));
values.put(BatteryHistEntry.KEY_TIMESTAMP, Long.valueOf(timestamp));
values.put(BatteryHistEntry.KEY_ZONE_ID, TimeZone.getDefault().getID());
values.put(BatteryHistEntry.KEY_BATTERY_LEVEL, Integer.valueOf(batteryLevel));
values.put(BatteryHistEntry.KEY_BATTERY_STATUS, Integer.valueOf(batteryStatus));
values.put(BatteryHistEntry.KEY_BATTERY_HEALTH, Integer.valueOf(batteryHealth));
final BatteryInformation batteryInformation =
constructBatteryInformation(
entry,
batteryUsageStats,
batteryLevel,
batteryStatus,
batteryHealth,
bootTimestamp);
values.put(BatteryHistEntry.KEY_BATTERY_INFORMATION,
convertBatteryInformationToString(batteryInformation));
// Save the BatteryInformation unencoded string into database for debugging.
if (Build.TYPE.equals("userdebug")) {
values.put(
BatteryHistEntry.KEY_BATTERY_INFORMATION_DEBUG, batteryInformation.toString());
}
return values;
}
/** Gets the encoded string from {@link BatteryInformation} instance. */
public static String convertBatteryInformationToString(
final BatteryInformation batteryInformation) {
return Base64.encodeToString(batteryInformation.toByteArray(), Base64.DEFAULT);
}
/** Gets the {@link BatteryInformation} instance from {@link ContentValues}. */
public static BatteryInformation getBatteryInformation(
final ContentValues values, final String key) {
final BatteryInformation defaultInstance = BatteryInformation.getDefaultInstance();
if (values != null && values.containsKey(key)) {
return BatteryUtils.parseProtoFromString(values.getAsString(key), defaultInstance);
}
return defaultInstance;
}
/** Gets the {@link BatteryInformation} instance from {@link Cursor}. */
public static BatteryInformation getBatteryInformation(final Cursor cursor, final String key) {
final BatteryInformation defaultInstance = BatteryInformation.getDefaultInstance();
final int columnIndex = cursor.getColumnIndex(key);
if (columnIndex >= 0) {
return BatteryUtils.parseProtoFromString(
cursor.getString(columnIndex), defaultInstance);
}
return defaultInstance;
}
/** Converts to {@link BatteryHistEntry} */
public static BatteryHistEntry convertToBatteryHistEntry(
BatteryEntry entry,
@@ -331,6 +357,41 @@ public final class ConvertUtils {
}
}
private static BatteryInformation constructBatteryInformation(
final BatteryEntry entry,
final BatteryUsageStats batteryUsageStats,
final int batteryLevel,
final int batteryStatus,
final int batteryHealth,
final long bootTimestamp) {
final DeviceBatteryState deviceBatteryState =
DeviceBatteryState
.newBuilder()
.setBatteryLevel(batteryLevel)
.setBatteryStatus(batteryStatus)
.setBatteryHealth(batteryHealth)
.build();
final BatteryInformation.Builder batteryInformationBuilder =
BatteryInformation
.newBuilder()
.setDeviceBatteryState(deviceBatteryState)
.setBootTimestamp(bootTimestamp)
.setZoneId(TimeZone.getDefault().getID());
if (entry != null && batteryUsageStats != null) {
batteryInformationBuilder
.setIsHidden(entry.isHidden())
.setAppLabel(entry.getLabel() != null ? entry.getLabel() : "")
.setTotalPower(batteryUsageStats.getConsumedPower())
.setConsumePower(entry.getConsumedPower())
.setPercentOfTotal(entry.mPercent)
.setDrainType(entry.getPowerComponentId())
.setForegroundUsageTimeInMs(entry.getTimeInForegroundMs())
.setBackgroundUsageTimeInMs(entry.getTimeInBackgroundMs());
}
return batteryInformationBuilder.build();
}
private static void insert24HoursData(
final int desiredIndex,
final Map<Integer, List<BatteryDiffEntry>> indexedUsageMap) {

View File

@@ -17,16 +17,16 @@
package com.android.settings.fuelgauge.batteryusage.db;
import android.content.ContentValues;
import android.content.Intent;
import android.os.BatteryManager;
import androidx.room.Entity;
import androidx.room.PrimaryKey;
import com.android.settings.fuelgauge.BatteryUtils;
import com.android.settings.fuelgauge.batteryusage.BatteryInformation;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
@@ -43,68 +43,41 @@ public class BatteryState {
// Records the app relative information.
public final long uid;
public final long userId;
public final String appLabel;
public final String packageName;
// Whether the data is represented as system component or not?
public final boolean isHidden;
// Records the timestamp relative information.
public final long bootTimestamp;
public final long timestamp;
public final String zoneId;
// Records the battery usage relative information.
public final double totalPower;
public final double consumePower;
public final double percentOfTotal;
public final long foregroundUsageTimeInMs;
public final long backgroundUsageTimeInMs;
public final int drainType;
public final int consumerType;
// Records the battery intent relative information.
public final int batteryLevel;
public final int batteryStatus;
public final int batteryHealth;
public final boolean isFullChargeCycleStart;
public final String batteryInformation;
/**
* This field is filled only when build type is "userdebug".
* For now, Java Proto Lite is recommended by the Android team as the more lightweight solution
* designed specifically for mobile apps to process protobuf.
* However, converting protobuf to string through Java Proto Lite needs to parse it into a bytes
* field first, which leads to the strings saved in our database are encoded and hard to
* understand.
* To make it easier to debug in our daily development, this field is added.
* It will not be filled for the real users.
*/
public final String batteryInformationDebug;
public BatteryState(
long uid,
long userId,
String appLabel,
String packageName,
boolean isHidden,
long bootTimestamp,
long timestamp,
String zoneId,
double totalPower,
double consumePower,
double percentOfTotal,
long foregroundUsageTimeInMs,
long backgroundUsageTimeInMs,
int drainType,
int consumerType,
int batteryLevel,
int batteryStatus,
int batteryHealth) {
boolean isFullChargeCycleStart,
String batteryInformation,
String batteryInformationDebug) {
// Records the app relative information.
this.uid = uid;
this.userId = userId;
this.appLabel = appLabel;
this.packageName = packageName;
this.isHidden = isHidden;
// Records the timestamp relative information.
this.bootTimestamp = bootTimestamp;
this.timestamp = timestamp;
this.zoneId = zoneId;
// Records the battery usage relative information.
this.totalPower = totalPower;
this.consumePower = consumePower;
this.percentOfTotal = percentOfTotal;
this.foregroundUsageTimeInMs = foregroundUsageTimeInMs;
this.backgroundUsageTimeInMs = backgroundUsageTimeInMs;
this.drainType = drainType;
this.consumerType = consumerType;
// Records the battery intent relative information.
this.batteryLevel = batteryLevel;
this.batteryStatus = batteryStatus;
this.batteryHealth = batteryHealth;
this.isFullChargeCycleStart = isFullChargeCycleStart;
this.batteryInformation = batteryInformation;
this.batteryInformationDebug = batteryInformationDebug;
}
/** Sets the auto-generated content ID. */
@@ -126,22 +99,17 @@ public class BatteryState {
sCacheSimpleDateFormat = new SimpleDateFormat("MMM dd,yyyy HH:mm:ss", Locale.US);
}
final String recordAtDateTime = sCacheSimpleDateFormat.format(new Date(timestamp));
final BatteryInformation batteryInformationInstance =
BatteryUtils.parseProtoFromString(
batteryInformation, BatteryInformation.getDefaultInstance());
final StringBuilder builder = new StringBuilder()
.append("\nBatteryState{")
.append(String.format(Locale.US,
"\n\tpackage=%s|label=%s|uid=%d|userId=%d|isHidden=%b",
packageName, appLabel, uid, userId, isHidden))
.append(String.format(Locale.US, "\n\ttimestamp=%s|zoneId=%s|bootTimestamp=%d",
recordAtDateTime, zoneId, Duration.ofMillis(bootTimestamp).getSeconds()))
.append(String.format(Locale.US,
"\n\tusage=%f|total=%f|consume=%f|elapsedTime=%d|%d",
percentOfTotal, totalPower, consumePower,
Duration.ofMillis(foregroundUsageTimeInMs).getSeconds(),
Duration.ofMillis(backgroundUsageTimeInMs).getSeconds()))
.append(String.format(Locale.US,
"\n\tdrain=%d|consumer=%d", drainType, consumerType))
.append(String.format(Locale.US, "\n\tbattery=%d|status=%d|health=%d\n}",
batteryLevel, batteryStatus, batteryHealth));
"\n\tpackage=%s|uid=%d|userId=%d", packageName, uid, userId))
.append(String.format(Locale.US, "\n\ttimestamp=%s|consumer=%d|isStart=%b",
recordAtDateTime, consumerType, isFullChargeCycleStart))
.append(String.format(Locale.US, "\n\tbatteryInfo="))
.append(batteryInformationInstance.toString());
return builder.toString();
}
@@ -155,52 +123,25 @@ public class BatteryState {
if (contentValues.containsKey("userId")) {
builder.setUserId(contentValues.getAsLong("userId"));
}
if (contentValues.containsKey("appLabel")) {
builder.setAppLabel(contentValues.getAsString("appLabel"));
}
if (contentValues.containsKey("packageName")) {
builder.setPackageName(contentValues.getAsString("packageName"));
}
if (contentValues.containsKey("isHidden")) {
builder.setIsHidden(contentValues.getAsBoolean("isHidden"));
}
if (contentValues.containsKey("bootTimestamp")) {
builder.setBootTimestamp(contentValues.getAsLong("bootTimestamp"));
}
if (contentValues.containsKey("timestamp")) {
builder.setTimestamp(contentValues.getAsLong("timestamp"));
}
if (contentValues.containsKey("consumePower")) {
builder.setConsumePower(contentValues.getAsDouble("consumePower"));
}
if (contentValues.containsKey("totalPower")) {
builder.setTotalPower(contentValues.getAsDouble("totalPower"));
}
if (contentValues.containsKey("percentOfTotal")) {
builder.setPercentOfTotal(contentValues.getAsDouble("percentOfTotal"));
}
if (contentValues.containsKey("foregroundUsageTimeInMs")) {
builder.setForegroundUsageTimeInMs(
contentValues.getAsLong("foregroundUsageTimeInMs"));
}
if (contentValues.containsKey("backgroundUsageTimeInMs")) {
builder.setBackgroundUsageTimeInMs(
contentValues.getAsLong("backgroundUsageTimeInMs"));
}
if (contentValues.containsKey("drainType")) {
builder.setDrainType(contentValues.getAsInteger("drainType"));
}
if (contentValues.containsKey("consumerType")) {
builder.setConsumerType(contentValues.getAsInteger("consumerType"));
}
if (contentValues.containsKey("batteryLevel")) {
builder.setBatteryLevel(contentValues.getAsInteger("batteryLevel"));
if (contentValues.containsKey("isFullChargeCycleStart")) {
builder.setIsFullChargeCycleStart(
contentValues.getAsBoolean("isFullChargeCycleStart"));
}
if (contentValues.containsKey("batteryStatus")) {
builder.setBatteryStatus(contentValues.getAsInteger("batteryStatus"));
if (contentValues.containsKey("batteryInformation")) {
builder.setBatteryInformation(contentValues.getAsString("batteryInformation"));
}
if (contentValues.containsKey("batteryHealth")) {
builder.setBatteryHealth(contentValues.getAsInteger("batteryHealth"));
if (contentValues.containsKey("batteryInformationDebug")) {
builder.setBatteryInformationDebug(
contentValues.getAsString("batteryInformationDebug"));
}
return builder.build();
}
@@ -214,21 +155,12 @@ public class BatteryState {
public static class Builder {
private long mUid;
private long mUserId;
private String mAppLabel;
private String mPackageName;
private boolean mIsHidden;
private long mBootTimestamp;
private long mTimestamp;
private double mTotalPower;
private double mConsumePower;
private double mPercentOfTotal;
private long mForegroundUsageTimeInMs;
private long mBackgroundUsageTimeInMs;
private int mDrainType;
private int mConsumerType;
private int mBatteryLevel;
private int mBatteryStatus;
private int mBatteryHealth;
private boolean mIsFullChargeCycleStart;
private String mBatteryInformation;
private String mBatteryInformationDebug;
/** Sets the uid. */
@CanIgnoreReturnValue
@@ -244,13 +176,6 @@ public class BatteryState {
return this;
}
/** Sets the app label. */
@CanIgnoreReturnValue
public Builder setAppLabel(String appLabel) {
this.mAppLabel = appLabel;
return this;
}
/** Sets the package name. */
@CanIgnoreReturnValue
public Builder setPackageName(String packageName) {
@@ -258,20 +183,6 @@ public class BatteryState {
return this;
}
/** Sets the is hidden value. */
@CanIgnoreReturnValue
public Builder setIsHidden(boolean isHidden) {
this.mIsHidden = isHidden;
return this;
}
/** Sets the boot timestamp. */
@CanIgnoreReturnValue
public Builder setBootTimestamp(long bootTimestamp) {
this.mBootTimestamp = bootTimestamp;
return this;
}
/** Sets the timestamp. */
@CanIgnoreReturnValue
public Builder setTimestamp(long timestamp) {
@@ -279,48 +190,6 @@ public class BatteryState {
return this;
}
/** Sets the total power. */
@CanIgnoreReturnValue
public Builder setTotalPower(double totalPower) {
this.mTotalPower = totalPower;
return this;
}
/** Sets the consumed power. */
@CanIgnoreReturnValue
public Builder setConsumePower(double consumePower) {
this.mConsumePower = consumePower;
return this;
}
/** Sets the percentage of total. */
@CanIgnoreReturnValue
public Builder setPercentOfTotal(double percentOfTotal) {
this.mPercentOfTotal = percentOfTotal;
return this;
}
/** Sets the foreground usage time. */
@CanIgnoreReturnValue
public Builder setForegroundUsageTimeInMs(long foregroundUsageTimeInMs) {
this.mForegroundUsageTimeInMs = foregroundUsageTimeInMs;
return this;
}
/** Sets the background usage time. */
@CanIgnoreReturnValue
public Builder setBackgroundUsageTimeInMs(long backgroundUsageTimeInMs) {
this.mBackgroundUsageTimeInMs = backgroundUsageTimeInMs;
return this;
}
/** Sets the drain type. */
@CanIgnoreReturnValue
public Builder setDrainType(int drainType) {
this.mDrainType = drainType;
return this;
}
/** Sets the consumer type. */
@CanIgnoreReturnValue
public Builder setConsumerType(int consumerType) {
@@ -328,44 +197,24 @@ public class BatteryState {
return this;
}
/** Sets the battery level. */
/** Sets whether is the full charge cycle start. */
@CanIgnoreReturnValue
public Builder setBatteryLevel(int batteryLevel) {
this.mBatteryLevel = batteryLevel;
public Builder setIsFullChargeCycleStart(boolean isFullChargeCycleStart) {
this.mIsFullChargeCycleStart = isFullChargeCycleStart;
return this;
}
/** Sets the battery status. */
/** Sets the consumer type. */
@CanIgnoreReturnValue
public Builder setBatteryStatus(int batteryStatus) {
this.mBatteryStatus = batteryStatus;
public Builder setBatteryInformation(String batteryInformation) {
this.mBatteryInformation = batteryInformation;
return this;
}
/** Sets the battery health. */
/** Sets the consumer type. */
@CanIgnoreReturnValue
public Builder setBatteryHealth(int batteryHealth) {
this.mBatteryHealth = batteryHealth;
return this;
}
/** Sets the battery intent. */
@CanIgnoreReturnValue
public Builder setBatteryIntent(Intent batteryIntent) {
final int level = batteryIntent.getIntExtra(BatteryManager.EXTRA_LEVEL, -1);
final int scale = batteryIntent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);
this.mBatteryLevel =
scale == 0
? -1 /*invalid battery level*/
: Math.round((level / (float) scale) * 100f);
this.mBatteryStatus =
batteryIntent.getIntExtra(
BatteryManager.EXTRA_STATUS,
BatteryManager.BATTERY_STATUS_UNKNOWN);
this.mBatteryHealth =
batteryIntent.getIntExtra(
BatteryManager.EXTRA_HEALTH,
BatteryManager.BATTERY_HEALTH_UNKNOWN);
public Builder setBatteryInformationDebug(String batteryInformationDebug) {
this.mBatteryInformationDebug = batteryInformationDebug;
return this;
}
@@ -374,22 +223,12 @@ public class BatteryState {
return new BatteryState(
mUid,
mUserId,
mAppLabel,
mPackageName,
mIsHidden,
mBootTimestamp,
mTimestamp,
/*zoneId=*/ TimeZone.getDefault().getID(),
mTotalPower,
mConsumePower,
mPercentOfTotal,
mForegroundUsageTimeInMs,
mBackgroundUsageTimeInMs,
mDrainType,
mConsumerType,
mBatteryLevel,
mBatteryStatus,
mBatteryHealth);
mIsFullChargeCycleStart,
mBatteryInformation,
mBatteryInformationDebug);
}
private Builder() {}

View File

@@ -40,7 +40,7 @@ public abstract class BatteryStateDatabase extends RoomDatabase {
if (sBatteryStateDatabase == null) {
sBatteryStateDatabase =
Room.databaseBuilder(
context, BatteryStateDatabase.class, "battery-usage-db-v5")
context, BatteryStateDatabase.class, "battery-usage-db-v6")
// Allows accessing data in the main thread for dumping bugreport.
.allowMainThreadQueries()
.fallbackToDestructiveMigration()