Clone the CallStat objects/lists before dispatching it to the listener

As these objects/lists could be mutated after being dispatched.

Bug: 181193693
Test: atest BatteryStatsBinderCallStatsTest BinderCallsStatsTest
Change-Id: I9de44e734acc7313d03ee616aa5e2f0a01da7cf3
This commit is contained in:
Jing Ji
2021-03-02 18:23:30 -08:00
parent b5b5aa24ac
commit 9caf734d3a

View File

@@ -120,8 +120,13 @@ public class BinderCallsStats implements BinderInternal.Observer {
UidEntry uidEntry = mUidEntries.get(mSendUidsToObserver.valueAt(i));
if (uidEntry != null) {
ArrayMap<CallStatKey, CallStat> callStats = uidEntry.mCallStats;
final int csize = callStats.size();
final ArrayList<CallStat> tmpCallStats = new ArrayList<>(csize);
for (int j = 0; j < csize; j++) {
tmpCallStats.add(callStats.valueAt(j).clone());
}
mCallStatsObserver.noteCallStats(uidEntry.workSourceUid,
uidEntry.incrementalCallCount, callStats.values()
uidEntry.incrementalCallCount, tmpCallStats
);
uidEntry.incrementalCallCount = 0;
for (int j = callStats.size() - 1; j >= 0; j--) {
@@ -829,6 +834,23 @@ public class BinderCallsStats implements BinderInternal.Observer {
this.screenInteractive = screenInteractive;
}
@Override
public CallStat clone() {
CallStat clone = new CallStat(callingUid, binderClass, transactionCode,
screenInteractive);
clone.recordedCallCount = recordedCallCount;
clone.callCount = callCount;
clone.cpuTimeMicros = cpuTimeMicros;
clone.maxCpuTimeMicros = maxCpuTimeMicros;
clone.latencyMicros = latencyMicros;
clone.maxLatencyMicros = maxLatencyMicros;
clone.maxRequestSizeBytes = maxRequestSizeBytes;
clone.maxReplySizeBytes = maxReplySizeBytes;
clone.exceptionCount = exceptionCount;
clone.incrementalCallCount = incrementalCallCount;
return clone;
}
@Override
public String toString() {
// This is expensive, but CallStat.toString() is only used for debugging.