diff options
7 files changed, 92 insertions, 19 deletions
diff --git a/core/java/android/os/BatteryUsageStats.java b/core/java/android/os/BatteryUsageStats.java index 0f94cbef3886..86e6db1dc625 100644 --- a/core/java/android/os/BatteryUsageStats.java +++ b/core/java/android/os/BatteryUsageStats.java @@ -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; } diff --git a/core/java/com/android/internal/os/BatteryStatsHistory.java b/core/java/com/android/internal/os/BatteryStatsHistory.java index 879e0a8cfe10..8ebb11dd752b 100644 --- a/core/java/com/android/internal/os/BatteryStatsHistory.java +++ b/core/java/com/android/internal/os/BatteryStatsHistory.java @@ -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. + * 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. - * Checkin file also call this method. * @param out the output parcel */ - public void writeToParcel(Parcel out) { + 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(); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 169eff009bff..cea0b0fa6bd0 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -1273,12 +1273,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; diff --git a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java index 27bc31861f44..79832867d01f 100644 --- a/core/java/com/android/internal/os/BatteryUsageStatsProvider.java +++ b/core/java/com/android/internal/os/BatteryUsageStatsProvider.java @@ -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(); diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java index 74b6dbe76a16..93910b9c816e 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsProviderTest.java @@ -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 diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java index ac87806b1639..d5a7abf43d18 100644 --- a/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java +++ b/core/tests/coretests/src/com/android/internal/os/BatteryUsageStatsRule.java @@ -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(); } diff --git a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java index cfecf15b55ef..ed4ab8d6489e 100644 --- a/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java +++ b/core/tests/coretests/src/com/android/internal/os/MockBatteryStatsImpl.java @@ -27,6 +27,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; @@ -42,7 +43,12 @@ public class MockBatteryStatsImpl extends BatteryStatsImpl { private DummyExternalStatsSync mExternalStatsSync = new DummyExternalStatsSync(); MockBatteryStatsImpl(Clocks clocks) { - super(clocks); + this(clocks, null); + } + + MockBatteryStatsImpl(Clocks clocks, File historyDirectory) { + super(clocks, historyDirectory); + this.clocks = mClocks; initTimersAndCounters(); |