summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java15
-rw-r--r--core/java/com/android/internal/os/BinderCallsStats.java19
-rw-r--r--core/java/com/android/internal/os/BinderInternal.java8
-rw-r--r--core/java/com/android/internal/os/SystemServerCpuThreadReader.java18
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BatteryStatsBinderCallStatsTest.java10
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java27
-rw-r--r--core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java4
-rw-r--r--services/core/java/android/os/BatteryStatsInternal.java7
-rw-r--r--services/core/java/com/android/server/BinderCallsStatsService.java15
-rw-r--r--services/core/java/com/android/server/am/BatteryStatsService.java12
10 files changed, 97 insertions, 38 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index e58990eff2c8..7516a879211f 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -6613,22 +6613,29 @@ public class BatteryStatsImpl extends BatteryStats {
* the power consumption to the calling app.
*/
public void noteBinderCallStats(int workSourceUid, long incrementalCallCount,
- Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids) {
- noteBinderCallStats(workSourceUid, incrementalCallCount, callStats, binderThreadNativeTids,
+ Collection<BinderCallsStats.CallStat> callStats) {
+ noteBinderCallStats(workSourceUid, incrementalCallCount, callStats,
mClocks.elapsedRealtime(), mClocks.uptimeMillis());
}
public void noteBinderCallStats(int workSourceUid, long incrementalCallCount,
- Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids,
+ Collection<BinderCallsStats.CallStat> callStats,
long elapsedRealtimeMs, long uptimeMs) {
synchronized (this) {
getUidStatsLocked(workSourceUid, elapsedRealtimeMs, uptimeMs)
.noteBinderCallStatsLocked(incrementalCallCount, callStats);
- mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids);
}
}
/**
+ * Takes note of native IDs of threads taking incoming binder calls. The CPU time
+ * of these threads is attributed to the apps making those binder calls.
+ */
+ public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) {
+ mSystemServerCpuThreadReader.setBinderThreadNativeTids(binderThreadNativeTids);
+ }
+
+ /**
* Estimates the proportion of system server CPU activity handling incoming binder calls
* that can be attributed to each app
*/
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index f5bef0b006f5..70b1ad49d8b8 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -119,8 +119,8 @@ public class BinderCallsStats implements BinderInternal.Observer {
if (uidEntry != null) {
ArrayMap<CallStatKey, CallStat> callStats = uidEntry.mCallStats;
mCallStatsObserver.noteCallStats(uidEntry.workSourceUid,
- uidEntry.incrementalCallCount, callStats.values(),
- mNativeTids.toArray());
+ uidEntry.incrementalCallCount, callStats.values()
+ );
uidEntry.incrementalCallCount = 0;
for (int j = callStats.size() - 1; j >= 0; j--) {
callStats.valueAt(j).incrementalCallCount = 0;
@@ -168,6 +168,7 @@ public class BinderCallsStats implements BinderInternal.Observer {
public void setCallStatsObserver(
BinderInternal.CallStatsObserver callStatsObserver) {
mCallStatsObserver = callStatsObserver;
+ noteBinderThreadNativeIds();
noteCallsStatsDelayed();
}
@@ -182,13 +183,13 @@ public class BinderCallsStats implements BinderInternal.Observer {
@Override
@Nullable
public CallSession callStarted(Binder binder, int code, int workSourceUid) {
+ noteNativeThreadId();
+
if (!mRecordingAllTransactionsForUid
&& (mDeviceState == null || mDeviceState.isCharging())) {
return null;
}
- noteNativeThreadId();
-
final CallSession s = obtainCallSession();
s.binderClass = binder.getClass();
s.transactionCode = code;
@@ -359,6 +360,16 @@ public class BinderCallsStats implements BinderInternal.Observer {
mNativeTids = copyOnWriteArray;
}
}
+
+ noteBinderThreadNativeIds();
+ }
+
+ private void noteBinderThreadNativeIds() {
+ if (mCallStatsObserver == null) {
+ return;
+ }
+
+ mCallStatsObserver.noteBinderThreadNativeIds(getNativeTids());
}
/**
diff --git a/core/java/com/android/internal/os/BinderInternal.java b/core/java/com/android/internal/os/BinderInternal.java
index 2645b8e84cf1..c14d8d805d29 100644
--- a/core/java/com/android/internal/os/BinderInternal.java
+++ b/core/java/com/android/internal/os/BinderInternal.java
@@ -143,8 +143,12 @@ public class BinderInternal {
* Notes incoming binder call stats associated with this work source UID.
*/
void noteCallStats(int workSourceUid, long incrementalCallCount,
- Collection<BinderCallsStats.CallStat> callStats,
- int[] binderThreadNativeTids);
+ Collection<BinderCallsStats.CallStat> callStats);
+
+ /**
+ * Notes the native IDs of threads taking incoming binder calls.
+ */
+ void noteBinderThreadNativeIds(int[] binderThreadNativeTids);
}
/**
diff --git a/core/java/com/android/internal/os/SystemServerCpuThreadReader.java b/core/java/com/android/internal/os/SystemServerCpuThreadReader.java
index 1cdd42c7403e..3aa2390375ec 100644
--- a/core/java/com/android/internal/os/SystemServerCpuThreadReader.java
+++ b/core/java/com/android/internal/os/SystemServerCpuThreadReader.java
@@ -31,7 +31,7 @@ import java.util.Arrays;
*/
public class SystemServerCpuThreadReader {
private KernelCpuThreadReader mKernelCpuThreadReader;
- private int[] mBinderThreadNativeTids;
+ private int[] mBinderThreadNativeTids = new int[0]; // Sorted
private int[] mThreadCpuTimesUs;
private int[] mBinderThreadCpuTimesUs;
@@ -75,7 +75,8 @@ public class SystemServerCpuThreadReader {
}
public void setBinderThreadNativeTids(int[] nativeTids) {
- mBinderThreadNativeTids = nativeTids;
+ mBinderThreadNativeTids = nativeTids.clone();
+ Arrays.sort(mBinderThreadNativeTids);
}
/**
@@ -107,7 +108,8 @@ public class SystemServerCpuThreadReader {
int threadCpuUsagesSize = threadCpuUsages.size();
for (int j = 0; j < threadCpuUsagesSize; j++) {
KernelCpuThreadReader.ThreadCpuUsage tcu = threadCpuUsages.get(j);
- boolean isBinderThread = isBinderThread(tcu.threadId);
+ boolean isBinderThread =
+ Arrays.binarySearch(mBinderThreadNativeTids, tcu.threadId) >= 0;
final int len = Math.min(tcu.usageTimesMillis.length, mThreadCpuTimesUs.length);
for (int k = 0; k < len; k++) {
@@ -138,14 +140,4 @@ public class SystemServerCpuThreadReader {
return mDeltaCpuThreadTimes;
}
- private boolean isBinderThread(int threadId) {
- if (mBinderThreadNativeTids != null) {
- for (int i = 0; i < mBinderThreadNativeTids.length; i++) {
- if (threadId == mBinderThreadNativeTids[i]) {
- return true;
- }
- }
- }
- return false;
- }
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBinderCallStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBinderCallStatsTest.java
index 22c41f3c9622..85f9c97629e3 100644
--- a/core/tests/coretests/src/com/android/internal/os/BatteryStatsBinderCallStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BatteryStatsBinderCallStatsTest.java
@@ -60,7 +60,7 @@ public class BatteryStatsBinderCallStatsTest extends TestCase {
stat1.cpuTimeMicros = 1000;
callStats.add(stat1);
- bi.noteBinderCallStats(workSourceUid, 42, callStats, null);
+ bi.noteBinderCallStats(workSourceUid, 42, callStats);
callStats.clear();
BinderCallsStats.CallStat stat2 = new BinderCallsStats.CallStat(callingUid,
@@ -70,7 +70,7 @@ public class BatteryStatsBinderCallStatsTest extends TestCase {
stat2.cpuTimeMicros = 500;
callStats.add(stat2);
- bi.noteBinderCallStats(workSourceUid, 8, callStats, null);
+ bi.noteBinderCallStats(workSourceUid, 8, callStats);
BatteryStatsImpl.Uid uid = bi.getUidStatsLocked(workSourceUid);
assertEquals(42 + 8, uid.getBinderCallCount());
@@ -112,7 +112,7 @@ public class BatteryStatsBinderCallStatsTest extends TestCase {
stat1b.cpuTimeMicros = 1500;
callStats.add(stat1b);
- bi.noteBinderCallStats(workSourceUid1, 65, callStats, null);
+ bi.noteBinderCallStats(workSourceUid1, 65, callStats);
// No recorded stats for some methods. Must use the global average.
callStats.clear();
@@ -121,11 +121,11 @@ public class BatteryStatsBinderCallStatsTest extends TestCase {
stat2.incrementalCallCount = 10;
callStats.add(stat2);
- bi.noteBinderCallStats(workSourceUid2, 40, callStats, null);
+ bi.noteBinderCallStats(workSourceUid2, 40, callStats);
// No stats for any calls. Must use the global average
callStats.clear();
- bi.noteBinderCallStats(workSourceUid3, 50, callStats, null);
+ bi.noteBinderCallStats(workSourceUid3, 50, callStats);
bi.updateSystemServiceCallStats();
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 96250db4aa51..0eb34a993dec 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -47,8 +47,10 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
import java.util.Random;
+import java.util.Set;
@SmallTest
@RunWith(AndroidJUnit4.class)
@@ -770,13 +772,27 @@ public class BinderCallsStatsTest {
bcs.setSamplingInterval(1);
bcs.setTrackScreenInteractive(false);
+
final ArrayList<BinderCallsStats.CallStat> callStatsList = new ArrayList<>();
- bcs.setCallStatsObserver(
- (workSourceUid, incrementalCallCount, callStats, binderThreadIds) ->
- callStatsList.addAll(callStats));
+ final Set<Integer> nativeTids = new HashSet<>();
+ bcs.setCallStatsObserver(new BinderInternal.CallStatsObserver() {
+ @Override
+ public void noteCallStats(int workSourceUid, long incrementalCallCount,
+ Collection<BinderCallsStats.CallStat> callStats) {
+ callStatsList.addAll(callStats);
+ }
+
+ @Override
+ public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) {
+ for (int tid : binderThreadNativeTids) {
+ nativeTids.add(tid);
+ }
+ }
+ });
Binder binder = new Binder();
+ bcs.nativeTid = 1000;
CallSession callSession = bcs.callStarted(binder, 1, WORKSOURCE_UID);
bcs.time += 10;
bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
@@ -785,6 +801,7 @@ public class BinderCallsStatsTest {
bcs.time += 20;
bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
+ bcs.nativeTid = 2000;
callSession = bcs.callStarted(binder, 2, WORKSOURCE_UID);
bcs.time += 30;
bcs.callEnded(callSession, REQUEST_SIZE, REPLY_SIZE, WORKSOURCE_UID);
@@ -809,6 +826,10 @@ public class BinderCallsStatsTest {
assertEquals(30, callStats.maxCpuTimeMicros);
}
}
+
+ assertEquals(2, nativeTids.size());
+ assertTrue(nativeTids.contains(1000));
+ assertTrue(nativeTids.contains(2000));
}
@Test
diff --git a/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java b/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java
index ac5443e1c7ce..2eee140b921f 100644
--- a/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/SystemServicePowerCalculatorTest.java
@@ -87,7 +87,7 @@ public class SystemServicePowerCalculatorTest {
stat1.cpuTimeMicros = 1000000;
callStats.add(stat1);
- mMockBatteryStats.noteBinderCallStats(workSourceUid1, 100, callStats, null);
+ mMockBatteryStats.noteBinderCallStats(workSourceUid1, 100, callStats);
callStats.clear();
BinderCallsStats.CallStat stat2 = new BinderCallsStats.CallStat(workSourceUid2,
@@ -97,7 +97,7 @@ public class SystemServicePowerCalculatorTest {
stat2.cpuTimeMicros = 9000000;
callStats.add(stat2);
- mMockBatteryStats.noteBinderCallStats(workSourceUid2, 100, callStats, null);
+ mMockBatteryStats.noteBinderCallStats(workSourceUid2, 100, callStats);
mMockBatteryStats.updateSystemServiceCallStats();
mMockBatteryStats.updateSystemServerThreadStats();
diff --git a/services/core/java/android/os/BatteryStatsInternal.java b/services/core/java/android/os/BatteryStatsInternal.java
index b7fed87d570d..958c15c8d432 100644
--- a/services/core/java/android/os/BatteryStatsInternal.java
+++ b/services/core/java/android/os/BatteryStatsInternal.java
@@ -50,5 +50,10 @@ public abstract class BatteryStatsInternal {
* Informs battery stats of binder stats for the given work source UID.
*/
public abstract void noteBinderCallStats(int workSourceUid, long incrementalBinderCallCount,
- Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids);
+ Collection<BinderCallsStats.CallStat> callStats);
+
+ /**
+ * Informs battery stats of native thread IDs of threads taking incoming binder calls.
+ */
+ public abstract void noteBinderThreadNativeIds(int[] binderThreadNativeTids);
}
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index c9513592ea79..66ac889ff2ca 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -49,6 +49,7 @@ import com.android.internal.util.DumpUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
public class BinderCallsStatsService extends Binder {
@@ -273,7 +274,19 @@ public class BinderCallsStatsService extends Binder {
BatteryStatsInternal batteryStatsInternal = getLocalService(
BatteryStatsInternal.class);
- mBinderCallsStats.setCallStatsObserver(batteryStatsInternal::noteBinderCallStats);
+ mBinderCallsStats.setCallStatsObserver(new BinderInternal.CallStatsObserver() {
+ @Override
+ public void noteCallStats(int workSourceUid, long incrementalCallCount,
+ Collection<BinderCallsStats.CallStat> callStats) {
+ batteryStatsInternal.noteBinderCallStats(workSourceUid,
+ incrementalCallCount, callStats);
+ }
+
+ @Override
+ public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) {
+ batteryStatsInternal.noteBinderThreadNativeIds(binderThreadNativeTids);
+ }
+ });
// It needs to be called before mService.systemReady to make sure the observer is
// initialized before installing it.
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index 808a6993af1a..76125aabc978 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -240,14 +240,20 @@ public final class BatteryStatsService extends IBatteryStats.Stub
@Override
public void noteBinderCallStats(int workSourceUid, long incrementatCallCount,
- Collection<BinderCallsStats.CallStat> callStats, int[] binderThreadNativeTids) {
+ Collection<BinderCallsStats.CallStat> callStats) {
synchronized (BatteryStatsService.this.mLock) {
mHandler.sendMessage(PooledLambda.obtainMessage(
- mStats::noteBinderCallStats, workSourceUid, incrementatCallCount,
- callStats, binderThreadNativeTids,
+ mStats::noteBinderCallStats, workSourceUid, incrementatCallCount, callStats,
SystemClock.elapsedRealtime(), SystemClock.uptimeMillis()));
}
}
+
+ @Override
+ public void noteBinderThreadNativeIds(int[] binderThreadNativeTids) {
+ synchronized (BatteryStatsService.this.mLock) {
+ mStats.noteBinderThreadNativeIds(binderThreadNativeTids);
+ }
+ }
}
@Override