From 9caf734d3afb7bd4872b32802177f2a30e27a5d1 Mon Sep 17 00:00:00 2001 From: Jing Ji Date: Tue, 2 Mar 2021 18:23:30 -0800 Subject: [PATCH] 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 --- .../android/internal/os/BinderCallsStats.java | 24 ++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java index b3e8db2052204..14b870575769b 100644 --- a/core/java/com/android/internal/os/BinderCallsStats.java +++ b/core/java/com/android/internal/os/BinderCallsStats.java @@ -120,8 +120,13 @@ public class BinderCallsStats implements BinderInternal.Observer { UidEntry uidEntry = mUidEntries.get(mSendUidsToObserver.valueAt(i)); if (uidEntry != null) { ArrayMap callStats = uidEntry.mCallStats; + final int csize = callStats.size(); + final ArrayList 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.