Merge "Include saved battery history chunks into BatteryUsageStats parcel"

This commit is contained in:
Dmitri Plotnikov
2022-01-22 06:16:40 +00:00
committed by Gerrit Code Review
7 changed files with 93 additions and 20 deletions

View File

@@ -127,6 +127,7 @@ public final class BatteryUsageStats implements Parcelable {
private final AggregateBatteryConsumer[] mAggregateBatteryConsumers;
private final Parcel mHistoryBuffer;
private final List<BatteryStats.HistoryTag> mHistoryTagPool;
private final BatteryStatsHistory mBatteryStatsHistory;
private BatteryUsageStats(@NonNull Builder builder) {
mStatsStartTimestampMs = builder.mStatsStartTimestampMs;
@@ -138,6 +139,7 @@ public final class BatteryUsageStats implements Parcelable {
mDischargedPowerUpperBound = builder.mDischargedPowerUpperBoundMah;
mHistoryBuffer = builder.mHistoryBuffer;
mHistoryTagPool = builder.mHistoryTagPool;
mBatteryStatsHistory = builder.mBatteryStatsHistory;
mBatteryTimeRemainingMs = builder.mBatteryTimeRemainingMs;
mChargeTimeRemainingMs = builder.mChargeTimeRemainingMs;
mCustomPowerComponentNames = builder.mCustomPowerComponentNames;
@@ -289,8 +291,8 @@ public final class BatteryUsageStats implements Parcelable {
throw new IllegalStateException(
"Battery history was not requested in the BatteryUsageStatsQuery");
}
return new BatteryStatsHistoryIterator(new BatteryStatsHistory(mHistoryBuffer),
mHistoryTagPool);
return new BatteryStatsHistoryIterator(mBatteryStatsHistory, mHistoryTagPool);
}
@Override
@@ -356,7 +358,10 @@ public final class BatteryUsageStats implements Parcelable {
tag.poolIdx = source.readInt();
mHistoryTagPool.add(tag);
}
mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
mBatteryStatsHistory.readFromBatteryUsageStatsParcel(source);
} else {
mBatteryStatsHistory = null;
mHistoryBuffer = null;
mHistoryTagPool = null;
}
@@ -404,6 +409,7 @@ public final class BatteryUsageStats implements Parcelable {
dest.writeInt(tag.uid);
dest.writeInt(tag.poolIdx);
}
mBatteryStatsHistory.writeToBatteryUsageStatsParcel(dest);
} else {
dest.writeBoolean(false);
}
@@ -757,6 +763,7 @@ public final class BatteryUsageStats implements Parcelable {
new SparseArray<>();
private Parcel mHistoryBuffer;
private List<BatteryStats.HistoryTag> mHistoryTagPool;
private BatteryStatsHistory mBatteryStatsHistory;
public Builder(@NonNull String[] customPowerComponentNames) {
this(customPowerComponentNames, false);
@@ -865,10 +872,12 @@ public final class BatteryUsageStats implements Parcelable {
* Sets the parceled recent history.
*/
@NonNull
public Builder setBatteryHistory(Parcel historyBuffer,
List<BatteryStats.HistoryTag> historyTagPool) {
public Builder setBatteryHistory(@NonNull Parcel historyBuffer,
@NonNull List<BatteryStats.HistoryTag> historyTagPool,
@NonNull BatteryStatsHistory batteryStatsHistory) {
mHistoryBuffer = historyBuffer;
mHistoryTagPool = historyTagPool;
mBatteryStatsHistory = batteryStatsHistory;
return this;
}

View File

@@ -160,6 +160,11 @@ public class BatteryStatsHistory {
mHistoryDir = null;
mHistoryBuffer = historyBuffer;
}
public File getHistoryDirectory() {
return mHistoryDir;
}
/**
* Set the active file that mHistoryBuffer is backed up into.
*
@@ -375,12 +380,24 @@ public class BatteryStatsHistory {
}
/**
* Read all history files and serialize into a big Parcel. This is to send history files to
* Settings app since Settings app can not access /data/system directory.
* Checkin file also call this method.
* Read all history files and serialize into a big Parcel.
* Checkin file calls this method.
* @param out the output parcel
*/
public void writeToParcel(Parcel out) {
writeToParcel(out, false /* useBlobs */);
}
/**
* Read all history files and serialize into a big Parcel. This is to send history files to
* Settings app since Settings app can not access /data/system directory.
* @param out the output parcel
*/
public void writeToBatteryUsageStatsParcel(Parcel out) {
writeToParcel(out, true /* useBlobs */);
}
private void writeToParcel(Parcel out, boolean useBlobs) {
final long start = SystemClock.uptimeMillis();
out.writeInt(mFileNumbers.size() - 1);
for(int i = 0; i < mFileNumbers.size() - 1; i++) {
@@ -391,7 +408,12 @@ public class BatteryStatsHistory {
} catch(Exception e) {
Slog.e(TAG, "Error reading file "+ file.getBaseFile().getPath(), e);
}
out.writeByteArray(raw);
if (useBlobs) {
out.writeBlob(raw);
} else {
// Avoiding blobs in the check-in file for compatibility
out.writeByteArray(raw);
}
}
if (DEBUG) {
Slog.d(TAG, "writeToParcel duration ms:" + (SystemClock.uptimeMillis() - start));
@@ -399,18 +421,29 @@ public class BatteryStatsHistory {
}
/**
* This is for Settings app, when Settings app receives big history parcel, it call
* this method to parse it into list of parcels.
* Checkin file also call this method.
* This is for the check-in file, which has all history files embedded.
* @param in the input parcel.
*/
public void readFromParcel(Parcel in) {
readFromParcel(in, false /* useBlobs */);
}
/**
* This is for Settings app, when Settings app receives big history parcel, it calls
* this method to parse it into list of parcels.
* @param in the input parcel.
*/
public void readFromBatteryUsageStatsParcel(Parcel in) {
readFromParcel(in, true /* useBlobs */);
}
private void readFromParcel(Parcel in, boolean useBlobs) {
final long start = SystemClock.uptimeMillis();
mHistoryParcels = new ArrayList<>();
final int count = in.readInt();
for(int i = 0; i < count; i++) {
byte[] temp = in.createByteArray();
if (temp.length == 0) {
byte[] temp = useBlobs ? in.readBlob() : in.createByteArray();
if (temp == null || temp.length == 0) {
continue;
}
Parcel p = Parcel.obtain();

View File

@@ -1200,12 +1200,21 @@ public class BatteryStatsImpl extends BatteryStats {
}
public BatteryStatsImpl(Clocks clocks) {
this(clocks, (File) null);
}
public BatteryStatsImpl(Clocks clocks, File historyDirectory) {
init(clocks);
mStartClockTimeMs = clocks.currentTimeMillis();
mStatsFile = null;
mCheckinFile = null;
mDailyFile = null;
mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
if (historyDirectory == null) {
mStatsFile = null;
mBatteryStatsHistory = new BatteryStatsHistory(mHistoryBuffer);
} else {
mStatsFile = new AtomicFile(new File(historyDirectory, "batterystats.bin"));
mBatteryStatsHistory = new BatteryStatsHistory(this, historyDirectory, mHistoryBuffer);
}
mHandler = null;
mPlatformIdleStateCallback = null;
mMeasuredEnergyRetriever = null;

View File

@@ -29,6 +29,7 @@ import android.util.SparseArray;
import com.android.internal.annotations.VisibleForTesting;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@@ -203,7 +204,12 @@ public class BatteryUsageStatsProvider {
tags.add(tag);
}
batteryUsageStatsBuilder.setBatteryHistory(historyBuffer, tags);
final File systemDir =
batteryStatsImpl.mBatteryStatsHistory.getHistoryDirectory().getParentFile();
final BatteryStatsHistory batteryStatsHistory =
new BatteryStatsHistory(batteryStatsImpl, systemDir, historyBuffer);
batteryUsageStatsBuilder.setBatteryHistory(historyBuffer, tags, batteryStatsHistory);
}
return batteryUsageStatsBuilder.build();

View File

@@ -39,6 +39,8 @@ import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import libcore.testing.io.TestIoUtils;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -52,8 +54,11 @@ public class BatteryUsageStatsProviderTest {
private static final int APP_UID = Process.FIRST_APPLICATION_UID + 42;
private static final long MINUTE_IN_MS = 60 * 1000;
private final File mHistoryDir =
TestIoUtils.createTemporaryDirectory(getClass().getSimpleName());
@Rule
public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345)
public final BatteryUsageStatsRule mStatsRule = new BatteryUsageStatsRule(12345, mHistoryDir)
.setAveragePower(PowerProfile.POWER_FLASHLIGHT, 360.0);
@Test

View File

@@ -40,6 +40,7 @@ import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.mockito.stubbing.Answer;
import java.io.File;
import java.util.Arrays;
public class BatteryUsageStatsRule implements TestRule {
@@ -57,14 +58,18 @@ public class BatteryUsageStatsRule implements TestRule {
private boolean mScreenOn;
public BatteryUsageStatsRule() {
this(0);
this(0, null);
}
public BatteryUsageStatsRule(long currentTime) {
this(currentTime, null);
}
public BatteryUsageStatsRule(long currentTime, File historyDir) {
Context context = InstrumentationRegistry.getContext();
mPowerProfile = spy(new PowerProfile(context, true /* forTest */));
mMockClocks.currentTime = currentTime;
mBatteryStats = new MockBatteryStatsImpl(mMockClocks);
mBatteryStats = new MockBatteryStatsImpl(mMockClocks, historyDir);
mBatteryStats.setPowerProfile(mPowerProfile);
mBatteryStats.onSystemReady();
}

View File

@@ -29,6 +29,7 @@ import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidFreqTimeReader
import com.android.internal.os.KernelCpuUidTimeReader.KernelCpuUidUserSysTimeReader;
import com.android.internal.power.MeasuredEnergyStats;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Queue;
@@ -44,7 +45,12 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl {
private NetworkStats mNetworkStats;
MockBatteryStatsImpl(Clocks clocks) {
super(clocks);
this(clocks, null);
}
MockBatteryStatsImpl(Clocks clocks, File historyDirectory) {
super(clocks, historyDirectory);
this.clocks = mClocks;
initTimersAndCounters();