diff options
-rw-r--r-- | core/java/android/app/ActivityThread.java | 24 | ||||
-rw-r--r-- | core/java/android/app/LoadedApk.java | 14 | ||||
-rw-r--r-- | core/java/android/content/BroadcastReceiver.java | 4 | ||||
-rw-r--r-- | core/java/com/android/internal/os/DebugStore.java | 134 | ||||
-rw-r--r-- | core/tests/coretests/src/com/android/internal/os/DebugStoreTest.java | 354 |
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(); + } + } |