summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ben Miles <benmiles@google.com> 2025-02-28 10:00:19 -0800
committer Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> 2025-02-28 10:00:19 -0800
commit89c73f9905773615517b8a818bc1c7652cada5b6 (patch)
treea5cb5532b83e505e65721d3c3f7c750889613349
parent991d60e670814fae16d68559b6f5f98fc4e20251 (diff)
parent50f34b45baed2ec3a256f1c65df4865d72452768 (diff)
Merge "Improve ANR debug store logging with more app lifecycle events" into main am: 859c5fa3f2 am: 50f34b45ba
Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/3488833 Change-Id: I6188dd2419319f82997835fd98230395e54e8594 Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
-rw-r--r--core/java/android/app/ActivityThread.java24
-rw-r--r--core/java/android/app/LoadedApk.java14
-rw-r--r--core/java/android/content/BroadcastReceiver.java4
-rw-r--r--core/java/com/android/internal/os/DebugStore.java134
-rw-r--r--core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java354
5 files changed, 373 insertions, 157 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index c765298035e0..4c9116b02c1d 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1137,12 +1137,19 @@ public final class ActivityThread extends ClientTransactionHandler
CompatibilityInfo compatInfo, int resultCode, String data, Bundle extras,
boolean ordered, boolean assumeDelivered, int sendingUser, int processState,
int sendingUid, String sendingPackage) {
+ long debugStoreId = -1;
+ if (DEBUG_STORE_ENABLED) {
+ debugStoreId = DebugStore.recordScheduleReceiver();
+ }
updateProcessState(processState, false);
ReceiverData r = new ReceiverData(intent, resultCode, data, extras,
ordered, false, assumeDelivered, mAppThread.asBinder(), sendingUser,
sendingUid, sendingPackage);
r.info = info;
sendMessage(H.RECEIVER, r);
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordEventEnd(debugStoreId);
+ }
}
public final void scheduleReceiverList(List<ReceiverInfo> info) throws RemoteException {
@@ -1490,6 +1497,10 @@ public final class ActivityThread extends ClientTransactionHandler
boolean sticky, boolean assumeDelivered, int sendingUser, int processState,
int sendingUid, String sendingPackage)
throws RemoteException {
+ long debugStoreId = -1;
+ if (DEBUG_STORE_ENABLED) {
+ debugStoreId = DebugStore.recordScheduleRegisteredReceiver();
+ }
updateProcessState(processState, false);
// We can't modify IIntentReceiver due to UnsupportedAppUsage, so
@@ -1514,6 +1525,9 @@ public final class ActivityThread extends ClientTransactionHandler
receiver.performReceive(intent, resultCode, dataStr, extras, ordered, sticky,
sendingUser);
}
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordEventEnd(debugStoreId);
+ }
}
@Override
@@ -2505,8 +2519,15 @@ public final class ActivityThread extends ClientTransactionHandler
switch (msg.what) {
case BIND_APPLICATION:
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "bindApplication");
+ if (DEBUG_STORE_ENABLED) {
+ debugStoreId =
+ DebugStore.recordHandleBindApplication();
+ }
AppBindData data = (AppBindData)msg.obj;
handleBindApplication(data);
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordEventEnd(debugStoreId);
+ }
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
break;
case EXIT_APPLICATION:
@@ -2529,7 +2550,8 @@ public final class ActivityThread extends ClientTransactionHandler
ReceiverData receiverData = (ReceiverData) msg.obj;
if (DEBUG_STORE_ENABLED) {
debugStoreId =
- DebugStore.recordBroadcastHandleReceiver(receiverData.intent);
+ DebugStore.recordBroadcastReceive(
+ receiverData.intent, System.identityHashCode(receiverData));
}
try {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index ffd235f91e09..d0949ad86e04 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -61,6 +61,7 @@ import android.view.DisplayAdjustments;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.DebugStore;
import com.android.internal.util.ArrayUtils;
import dalvik.system.BaseDexClassLoader;
@@ -107,6 +108,9 @@ public final class LoadedApk {
static final String TAG = "LoadedApk";
static final boolean DEBUG = false;
+ private static final boolean DEBUG_STORE_ENABLED =
+ com.android.internal.os.Flags.debugStoreEnabled();
+
@UnsupportedAppUsage
private final ActivityThread mActivityThread;
@UnsupportedAppUsage
@@ -1816,6 +1820,12 @@ public final class LoadedApk {
Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER,
"broadcastReceiveReg: " + intent.getAction());
}
+ long debugStoreId = -1;
+ if (DEBUG_STORE_ENABLED) {
+ debugStoreId =
+ DebugStore.recordBroadcastReceiveReg(
+ intent, System.identityHashCode(this));
+ }
try {
ClassLoader cl = mReceiver.getClass().getClassLoader();
@@ -1838,6 +1848,10 @@ public final class LoadedApk {
"Error receiving broadcast " + intent
+ " in " + mReceiver, e);
}
+ } finally {
+ if (DEBUG_STORE_ENABLED) {
+ DebugStore.recordEventEnd(debugStoreId);
+ }
}
if (receiver.getPendingResult() != null) {
diff --git a/core/java/android/content/BroadcastReceiver.java b/core/java/android/content/BroadcastReceiver.java
index cf684876d33f..357baa3c1099 100644
--- a/core/java/android/content/BroadcastReceiver.java
+++ b/core/java/android/content/BroadcastReceiver.java
@@ -263,7 +263,7 @@ public abstract class BroadcastReceiver {
1);
}
if (DEBUG_STORE_ENABLED) {
- DebugStore.recordFinish(mReceiverClassName);
+ DebugStore.recordFinish(System.identityHashCode(this));
}
if (mType == TYPE_COMPONENT) {
@@ -444,7 +444,7 @@ public abstract class BroadcastReceiver {
PendingResult res = mPendingResult;
mPendingResult = null;
if (DEBUG_STORE_ENABLED) {
- DebugStore.recordGoAsync(getClass().getName());
+ DebugStore.recordGoAsync(System.identityHashCode(res));
}
if (res != null && Trace.isTagEnabled(Trace.TRACE_TAG_ACTIVITY_MANAGER)) {
res.mReceiverClassName = getClass().getName();
diff --git a/core/java/com/android/internal/os/DebugStore.java b/core/java/com/android/internal/os/DebugStore.java
index 4c45feed8511..3dca786a82af 100644
--- a/core/java/com/android/internal/os/DebugStore.java
+++ b/core/java/com/android/internal/os/DebugStore.java
@@ -20,6 +20,7 @@ import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Intent;
import android.content.pm.ServiceInfo;
+import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -43,6 +44,9 @@ import java.util.Objects;
* @hide
*/
public class DebugStore {
+ private static final boolean DEBUG_EVENTS = false;
+ private static final String TAG = "DebugStore";
+
private static DebugStoreNative sDebugStoreNative = new DebugStoreNativeImpl();
@UnsupportedAppUsage
@@ -120,7 +124,7 @@ public class DebugStore {
* @param receiverClassName The class name of the broadcast receiver.
*/
@UnsupportedAppUsage
- public static void recordGoAsync(String receiverClassName) {
+ public static void recordGoAsync(int pendingResultId) {
sDebugStoreNative.recordEvent(
"GoAsync",
List.of(
@@ -128,8 +132,8 @@ public class DebugStore {
Thread.currentThread().getName(),
"tid",
String.valueOf(Thread.currentThread().getId()),
- "rcv",
- Objects.toString(receiverClassName)));
+ "prid",
+ Integer.toHexString(pendingResultId)));
}
/**
@@ -138,7 +142,7 @@ public class DebugStore {
* @param receiverClassName The class of the broadcast receiver that completed the operation.
*/
@UnsupportedAppUsage
- public static void recordFinish(String receiverClassName) {
+ public static void recordFinish(int pendingResultId) {
sDebugStoreNative.recordEvent(
"Finish",
List.of(
@@ -146,9 +150,10 @@ public class DebugStore {
Thread.currentThread().getName(),
"tid",
String.valueOf(Thread.currentThread().getId()),
- "rcv",
- Objects.toString(receiverClassName)));
+ "prid",
+ Integer.toHexString(pendingResultId)));
}
+
/**
* Records the completion of a long-running looper message.
*
@@ -172,21 +177,92 @@ public class DebugStore {
/**
- * Records the reception of a broadcast.
+ * Records the reception of a broadcast by a manifest-declared receiver.
*
* @param intent The Intent associated with the broadcast.
* @return A unique ID for the recorded event.
*/
@UnsupportedAppUsage
- public static long recordBroadcastHandleReceiver(@Nullable Intent intent) {
+ public static long recordBroadcastReceive(@Nullable Intent intent, int pendingResultId) {
+ return sDebugStoreNative.beginEvent(
+ "BcRcv",
+ List.of(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()),
+ "act",
+ Objects.toString(intent != null ? intent.getAction() : null),
+ "cmp",
+ Objects.toString(intent != null ? intent.getComponent() : null),
+ "pkg",
+ Objects.toString(intent != null ? intent.getPackage() : null),
+ "prid",
+ Integer.toHexString(pendingResultId)));
+ }
+
+ /**
+ * Records the reception of a broadcast by a context-registered receiver.
+ *
+ * @param intent The Intent associated with the broadcast.
+ * @param pendingResultId The object ID of the PendingResult associated with the broadcast.
+ * @return A unique ID for the recorded event.
+ */
+ @UnsupportedAppUsage
+ public static long recordBroadcastReceiveReg(@Nullable Intent intent, int pendingResultId) {
+ return sDebugStoreNative.beginEvent(
+ "BcRcvReg",
+ List.of(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()),
+ "act",
+ Objects.toString(intent != null ? intent.getAction() : null),
+ "cmp",
+ Objects.toString(intent != null ? intent.getComponent() : null),
+ "pkg",
+ Objects.toString(intent != null ? intent.getPackage() : null),
+ "prid",
+ Integer.toHexString(pendingResultId)));
+ }
+
+ /**
+ * Records the binding of an application.
+ *
+ * @return A unique ID for the recorded event.
+ */
+ @UnsupportedAppUsage
+ public static long recordHandleBindApplication() {
+ return sDebugStoreNative.beginEvent("BindApp", List.of());
+ }
+
+ /**
+ * Records the scheduling of a receiver.
+ *
+ * @return A unique ID for the recorded event.
+ */
+ @UnsupportedAppUsage
+ public static long recordScheduleReceiver() {
return sDebugStoreNative.beginEvent(
- "HandleReceiver",
+ "SchRcv",
List.of(
"tname", Thread.currentThread().getName(),
- "tid", String.valueOf(Thread.currentThread().getId()),
- "act", Objects.toString(intent != null ? intent.getAction() : null),
- "cmp", Objects.toString(intent != null ? intent.getComponent() : null),
- "pkg", Objects.toString(intent != null ? intent.getPackage() : null)));
+ "tid", String.valueOf(Thread.currentThread().getId())));
+ }
+
+ /**
+ * Records the scheduling of a registered receiver.
+ *
+ * @return A unique ID for the recorded event.
+ */
+ @UnsupportedAppUsage
+ public static long recordScheduleRegisteredReceiver() {
+ return sDebugStoreNative.beginEvent(
+ "SchRcvReg",
+ List.of(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId())));
}
/**
@@ -225,18 +301,48 @@ public class DebugStore {
private static class DebugStoreNativeImpl implements DebugStoreNative {
@Override
public long beginEvent(String eventName, List<String> attributes) {
- return DebugStore.beginEventNative(eventName, attributes);
+ long id = DebugStore.beginEventNative(eventName, attributes);
+ if (DEBUG_EVENTS) {
+ Log.i(
+ TAG,
+ "beginEvent: " + id + " " + eventName + " " + attributeString(attributes));
+ }
+ return id;
}
@Override
public void endEvent(long id, List<String> attributes) {
+ if (DEBUG_EVENTS) {
+ Log.i(TAG, "endEvent: " + id + " " + attributeString(attributes));
+ }
DebugStore.endEventNative(id, attributes);
}
@Override
public void recordEvent(String eventName, List<String> attributes) {
+ if (DEBUG_EVENTS) {
+ Log.i(TAG, "recordEvent: " + eventName + " " + attributeString(attributes));
+ }
DebugStore.recordEventNative(eventName, attributes);
}
+
+ /**
+ * Returns a string like "[key1=foo, key2=bar]"
+ */
+ private String attributeString(List<String> attributes) {
+ StringBuilder sb = new StringBuilder().append("[");
+
+ for (int i = 0; i < attributes.size(); i++) {
+ sb.append(attributes.get(i));
+
+ if (i % 2 == 0) {
+ sb.append("=");
+ } else if (i < attributes.size() - 1) {
+ sb.append(", ");
+ }
+ }
+ return sb.append("]").toString();
+ }
}
private static native long beginEventNative(String eventName, List<String> attributes);
diff --git a/core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java b/core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java
index 786c2fc63018..bc452e7689e0 100644
--- a/core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java
@@ -47,21 +47,17 @@ import java.util.List;
/**
* Test class for {@link DebugStore}.
*
- * To run it:
- * atest FrameworksCoreTests:com.android.internal.os.DebugStoreTest
+ * <p>To run it: atest FrameworksCoreTests:com.android.internal.os.DebugStoreTest
*/
@RunWith(AndroidJUnit4.class)
@DisabledOnRavenwood(blockedBy = DebugStore.class)
@SmallTest
public class DebugStoreTest {
- @Rule
- public final RavenwoodRule mRavenwood = new RavenwoodRule();
+ @Rule public final RavenwoodRule mRavenwood = new RavenwoodRule();
- @Mock
- private DebugStore.DebugStoreNative mDebugStoreNativeMock;
+ @Mock private DebugStore.DebugStoreNative mDebugStoreNativeMock;
- @Captor
- private ArgumentCaptor<List<String>> mListCaptor;
+ @Captor private ArgumentCaptor<List<String>> mListCaptor;
@Before
public void setUp() {
@@ -79,16 +75,14 @@ public class DebugStoreTest {
when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(1L);
long eventId = DebugStore.recordServiceOnStart(1, 0, intent);
-
- verify(mDebugStoreNativeMock).beginEvent(eq("SvcStart"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "stId", "1",
- "flg", "0",
- "act", "com.android.ACTION",
- "comp", "ComponentInfo{com.android/androidService}",
- "pkg", "com.android"
- ).inOrder();
+ assertThat(paramsForBeginEvent("SvcStart"))
+ .containsExactly(
+ "stId", "1",
+ "flg", "0",
+ "act", "com.android.ACTION",
+ "comp", "ComponentInfo{com.android/androidService}",
+ "pkg", "com.android")
+ .inOrder();
assertThat(eventId).isEqualTo(1L);
}
@@ -101,13 +95,11 @@ public class DebugStoreTest {
when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(2L);
long eventId = DebugStore.recordServiceCreate(serviceInfo);
-
- verify(mDebugStoreNativeMock).beginEvent(eq("SvcCreate"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "name", "androidService",
- "pkg", "com.android"
- ).inOrder();
+ assertThat(paramsForBeginEvent("SvcCreate"))
+ .containsExactly(
+ "name", "androidService",
+ "pkg", "com.android")
+ .inOrder();
assertThat(eventId).isEqualTo(2L);
}
@@ -121,59 +113,60 @@ public class DebugStoreTest {
when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(3L);
long eventId = DebugStore.recordServiceBind(true, intent);
-
- verify(mDebugStoreNativeMock).beginEvent(eq("SvcBind"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "rebind", "true",
- "act", "com.android.ACTION",
- "cmp", "ComponentInfo{com.android/androidService}",
- "pkg", "com.android"
- ).inOrder();
+ assertThat(paramsForBeginEvent("SvcBind"))
+ .containsExactly(
+ "rebind", "true",
+ "act", "com.android.ACTION",
+ "cmp", "ComponentInfo{com.android/androidService}",
+ "pkg", "com.android")
+ .inOrder();
assertThat(eventId).isEqualTo(3L);
}
@Test
public void testRecordGoAsync() {
- DebugStore.recordGoAsync("androidReceiver");
-
- verify(mDebugStoreNativeMock).recordEvent(eq("GoAsync"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "tname", Thread.currentThread().getName(),
- "tid", String.valueOf(Thread.currentThread().getId()),
- "rcv", "androidReceiver"
- ).inOrder();
+ DebugStore.recordGoAsync(3840 /* 0xf00 */);
+
+ assertThat(paramsForRecordEvent("GoAsync"))
+ .containsExactly(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()),
+ "prid",
+ "f00")
+ .inOrder();
}
@Test
public void testRecordFinish() {
- DebugStore.recordFinish("androidReceiver");
-
- verify(mDebugStoreNativeMock).recordEvent(eq("Finish"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "tname", Thread.currentThread().getName(),
- "tid", String.valueOf(Thread.currentThread().getId()),
- "rcv", "androidReceiver"
- ).inOrder();
+ DebugStore.recordFinish(3840 /* 0xf00 */);
+
+ assertThat(paramsForRecordEvent("Finish"))
+ .containsExactly(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()),
+ "prid",
+ "f00")
+ .inOrder();
}
@Test
public void testRecordLongLooperMessage() {
DebugStore.recordLongLooperMessage(100, "androidHandler", 500L);
- verify(mDebugStoreNativeMock).recordEvent(eq("LooperMsg"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "code", "100",
- "trgt", "androidHandler",
- "elapsed", "500"
- ).inOrder();
+ assertThat(paramsForRecordEvent("LooperMsg"))
+ .containsExactly(
+ "code", "100",
+ "trgt", "androidHandler",
+ "elapsed", "500")
+ .inOrder();
}
@Test
- public void testRecordBroadcastHandleReceiver() {
+ public void testRecordBroadcastReceive() {
Intent intent = new Intent();
intent.setAction("com.android.ACTION");
intent.setComponent(new ComponentName("com.android", "androidReceiver"));
@@ -181,21 +174,87 @@ public class DebugStoreTest {
when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(4L);
- long eventId = DebugStore.recordBroadcastHandleReceiver(intent);
-
- verify(mDebugStoreNativeMock).beginEvent(eq("HandleReceiver"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "tname", Thread.currentThread().getName(),
- "tid", String.valueOf(Thread.currentThread().getId()),
- "act", "com.android.ACTION",
- "cmp", "ComponentInfo{com.android/androidReceiver}",
- "pkg", "com.android"
- ).inOrder();
+ long eventId = DebugStore.recordBroadcastReceive(intent, 3840 /* 0xf00 */);
+ assertThat(paramsForBeginEvent("BcRcv"))
+ .containsExactly(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId()),
+ "act", "com.android.ACTION",
+ "cmp", "ComponentInfo{com.android/androidReceiver}",
+ "pkg", "com.android",
+ "prid", "f00")
+ .inOrder();
assertThat(eventId).isEqualTo(4L);
}
@Test
+ public void testRecordBroadcastReceiveReg() {
+ Intent intent = new Intent();
+ intent.setAction("com.android.ACTION");
+ intent.setComponent(new ComponentName("com.android", "androidReceiver"));
+ intent.setPackage("com.android");
+
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(5L);
+
+ long eventId = DebugStore.recordBroadcastReceiveReg(intent, 3840 /* 0xf00 */);
+ assertThat(paramsForBeginEvent("BcRcvReg"))
+ .containsExactly(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()),
+ "act",
+ "com.android.ACTION",
+ "cmp",
+ "ComponentInfo{com.android/androidReceiver}",
+ "pkg",
+ "com.android",
+ "prid",
+ "f00")
+ .inOrder();
+ assertThat(eventId).isEqualTo(5L);
+ }
+
+ @Test
+ public void testRecordHandleBindApplication() {
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(6L);
+ long eventId = DebugStore.recordHandleBindApplication();
+
+ assertThat(paramsForBeginEvent("BindApp")).isEmpty();
+ assertThat(eventId).isEqualTo(6L);
+ }
+
+ @Test
+ public void testRecordScheduleReceiver() {
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(7L);
+ long eventId = DebugStore.recordScheduleReceiver();
+
+ assertThat(paramsForBeginEvent("SchRcv"))
+ .containsExactly(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()))
+ .inOrder();
+ assertThat(eventId).isEqualTo(7L);
+ }
+
+ @Test
+ public void testRecordScheduleRegisteredReceiver() {
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(8L);
+ long eventId = DebugStore.recordScheduleRegisteredReceiver();
+
+ assertThat(paramsForBeginEvent("SchRcvReg"))
+ .containsExactly(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()))
+ .inOrder();
+ assertThat(eventId).isEqualTo(8L);
+ }
+
+ @Test
public void testRecordEventEnd() {
DebugStore.recordEventEnd(1L);
@@ -203,109 +262,124 @@ public class DebugStoreTest {
}
@Test
- public void testRecordServiceOnStartWithNullIntent() {
+ public void testRecordServiceOnStart_withNullIntent() {
when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(5L);
long eventId = DebugStore.recordServiceOnStart(1, 0, null);
-
- verify(mDebugStoreNativeMock).beginEvent(eq("SvcStart"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "stId", "1",
- "flg", "0",
- "act", "null",
- "comp", "null",
- "pkg", "null"
- ).inOrder();
+ assertThat(paramsForBeginEvent("SvcStart"))
+ .containsExactly(
+ "stId", "1",
+ "flg", "0",
+ "act", "null",
+ "comp", "null",
+ "pkg", "null")
+ .inOrder();
assertThat(eventId).isEqualTo(5L);
}
@Test
- public void testRecordServiceCreateWithNullServiceInfo() {
+ public void testRecordServiceCreate_withNullServiceInfo() {
when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(6L);
long eventId = DebugStore.recordServiceCreate(null);
-
- verify(mDebugStoreNativeMock).beginEvent(eq("SvcCreate"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "name", "null",
- "pkg", "null"
- ).inOrder();
+ assertThat(paramsForBeginEvent("SvcCreate"))
+ .containsExactly(
+ "name", "null",
+ "pkg", "null")
+ .inOrder();
assertThat(eventId).isEqualTo(6L);
}
@Test
- public void testRecordServiceBindWithNullIntent() {
+ public void testRecordServiceBind_withNullIntent() {
when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(7L);
long eventId = DebugStore.recordServiceBind(false, null);
-
- verify(mDebugStoreNativeMock).beginEvent(eq("SvcBind"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "rebind", "false",
- "act", "null",
- "cmp", "null",
- "pkg", "null"
- ).inOrder();
+ assertThat(paramsForBeginEvent("SvcBind"))
+ .containsExactly(
+ "rebind", "false",
+ "act", "null",
+ "cmp", "null",
+ "pkg", "null")
+ .inOrder();
assertThat(eventId).isEqualTo(7L);
}
@Test
- public void testRecordBroadcastHandleReceiverWithNullIntent() {
+ public void testRecordBroadcastReceive_withNullIntent() {
when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(8L);
- long eventId = DebugStore.recordBroadcastHandleReceiver(null);
-
- verify(mDebugStoreNativeMock).beginEvent(eq("HandleReceiver"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "tname", Thread.currentThread().getName(),
- "tid", String.valueOf(Thread.currentThread().getId()),
- "act", "null",
- "cmp", "null",
- "pkg", "null"
- ).inOrder();
+ long eventId = DebugStore.recordBroadcastReceive(null, 3840 /* 0xf00 */);
+ assertThat(paramsForBeginEvent("BcRcv"))
+ .containsExactly(
+ "tname", Thread.currentThread().getName(),
+ "tid", String.valueOf(Thread.currentThread().getId()),
+ "act", "null",
+ "cmp", "null",
+ "pkg", "null",
+ "prid", "f00")
+ .inOrder();
assertThat(eventId).isEqualTo(8L);
}
@Test
- public void testRecordGoAsyncWithNullReceiverClassName() {
- DebugStore.recordGoAsync(null);
-
- verify(mDebugStoreNativeMock).recordEvent(eq("GoAsync"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "tname", Thread.currentThread().getName(),
- "tid", String.valueOf(Thread.currentThread().getId()),
- "rcv", "null"
- ).inOrder();
+ public void testRecordBroadcastReceiveReg_withNullIntent() {
+ when(mDebugStoreNativeMock.beginEvent(anyString(), anyList())).thenReturn(8L);
+
+ long eventId = DebugStore.recordBroadcastReceiveReg(null, 3840 /* 0xf00 */);
+ assertThat(paramsForBeginEvent("BcRcvReg"))
+ .containsExactly(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()),
+ "act",
+ "null",
+ "cmp",
+ "null",
+ "pkg",
+ "null",
+ "prid",
+ "f00")
+ .inOrder();
+ assertThat(eventId).isEqualTo(8L);
}
@Test
- public void testRecordFinishWithNullReceiverClassName() {
- DebugStore.recordFinish(null);
-
- verify(mDebugStoreNativeMock).recordEvent(eq("Finish"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "tname", Thread.currentThread().getName(),
- "tid", String.valueOf(Thread.currentThread().getId()),
- "rcv", "null"
- ).inOrder();
+ public void testRecordFinish_withNullReceiverClassName() {
+ DebugStore.recordFinish(3840 /* 0xf00 */);
+
+ assertThat(paramsForRecordEvent("Finish"))
+ .containsExactly(
+ "tname",
+ Thread.currentThread().getName(),
+ "tid",
+ String.valueOf(Thread.currentThread().getId()),
+ "prid",
+ "f00")
+ .inOrder();
}
@Test
- public void testRecordLongLooperMessageWithNullTargetClass() {
+ public void testRecordLongLooperMessage_withNullTargetClass() {
DebugStore.recordLongLooperMessage(200, null, 1000L);
- verify(mDebugStoreNativeMock).recordEvent(eq("LooperMsg"), mListCaptor.capture());
- List<String> capturedList = mListCaptor.getValue();
- assertThat(capturedList).containsExactly(
- "code", "200",
- "trgt", "null",
- "elapsed", "1000"
- ).inOrder();
+ assertThat(paramsForRecordEvent("LooperMsg"))
+ .containsExactly(
+ "code", "200",
+ "trgt", "null",
+ "elapsed", "1000")
+ .inOrder();
}
+
+ private List<String> paramsForBeginEvent(String eventName) {
+ verify(mDebugStoreNativeMock).beginEvent(eq(eventName), mListCaptor.capture());
+ return mListCaptor.getValue();
+ }
+
+ private List<String> paramsForRecordEvent(String eventName) {
+ verify(mDebugStoreNativeMock).recordEvent(eq(eventName), mListCaptor.capture());
+ return mListCaptor.getValue();
+ }
+
}