From 4158938848d056efee59a3c934e4b91fac18f1c7 Mon Sep 17 00:00:00 2001 From: Olivier Gaillard Date: Mon, 4 Feb 2019 10:42:34 +0000 Subject: [PATCH 1/2] Bug fix: looper not enabled Looper should not be enabled when we build the LooperStatsService so that setEnabled is called and the observer is installed. Test: atest LooperStatsTest Change-Id: I8d8800a6a2222b2d67a2aacdc58ce631dc1c8217 --- services/core/java/com/android/server/LooperStatsService.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/LooperStatsService.java b/services/core/java/com/android/server/LooperStatsService.java index 2f7929c962eb0..9184128d466f8 100644 --- a/services/core/java/com/android/server/LooperStatsService.java +++ b/services/core/java/com/android/server/LooperStatsService.java @@ -59,7 +59,8 @@ public class LooperStatsService extends Binder { private final Context mContext; private final LooperStats mStats; - private boolean mEnabled = DEFAULT_ENABLED; + // Default should be false so that the first call to #setEnabled installed the looper observer. + private boolean mEnabled = false; private LooperStatsService(Context context, LooperStats stats) { this.mContext = context; From 99ab9530d321bebfec09695efc878b844f18eea8 Mon Sep 17 00:00:00 2001 From: Olivier Gaillard Date: Mon, 4 Feb 2019 10:47:48 +0000 Subject: [PATCH 2/2] Bug fix: Do not track the looper exception if the session is not sampled Test: atest LooperStatsTest Change-Id: I1811ad12bdf9830699c615fff02f5aceea74c175 --- .../com/android/internal/os/LooperStats.java | 8 +++++--- .../android/internal/os/LooperStatsTest.java | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/core/java/com/android/internal/os/LooperStats.java b/core/java/com/android/internal/os/LooperStats.java index 0f0eeddf9a472..b3d9ca7670b51 100644 --- a/core/java/com/android/internal/os/LooperStats.java +++ b/core/java/com/android/internal/os/LooperStats.java @@ -126,9 +126,11 @@ public class LooperStats implements Looper.Observer { } DispatchSession session = (DispatchSession) token; - Entry entry = findEntry(msg, /* allowCreateNew= */true); - synchronized (entry) { - entry.exceptionCount++; + Entry entry = findEntry(msg, /* allowCreateNew= */session != DispatchSession.NOT_SAMPLED); + if (entry != null) { + synchronized (entry) { + entry.exceptionCount++; + } } recycleSession(session); diff --git a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java index 2c597b14c5573..79b8477543115 100644 --- a/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java +++ b/core/tests/coretests/src/com/android/internal/os/LooperStatsTest.java @@ -137,6 +137,26 @@ public final class LooperStatsTest { assertThat(entry.maxCpuUsageMicros).isEqualTo(0); } + @Test + public void testThrewException_notSampled() { + TestableLooperStats looperStats = new TestableLooperStats(2, 100); + + Object token = looperStats.messageDispatchStarting(); + looperStats.tickRealtime(10); + looperStats.tickThreadTime(10); + looperStats.messageDispatched(token, mHandlerFirst.obtainMessage(0)); + assertThat(looperStats.getEntries()).hasSize(1); + + // Will not be sampled so does not contribute to any entries. + Object token2 = looperStats.messageDispatchStarting(); + looperStats.tickRealtime(100); + looperStats.tickThreadTime(10); + looperStats.dispatchingThrewException( + token2, mHandlerSecond.obtainMessage(7), new ArithmeticException()); + assertThat(looperStats.getEntries()).hasSize(1); + assertThat(looperStats.getEntries().get(0).messageCount).isEqualTo(1); + } + @Test public void testMultipleMessagesDispatched() { TestableLooperStats looperStats = new TestableLooperStats(2, 100);