Skip to content

Commit a9007ed

Browse files
authored
Merge pull request #2524 from DataDog/jward/RUM-8875-manual-jank-stats-add
[RUM-8875] Add ability to manually add an activity to JankStats
2 parents 146a8c9 + bdddd22 commit a9007ed

File tree

11 files changed

+110
-0
lines changed

11 files changed

+110
-0
lines changed

features/dd-sdk-android-rum/api/apiSurface

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ class com.datadog.android.rum._RumInternalProxy
160160
fun updatePerformanceMetric(RumPerformanceMetric, Double)
161161
fun setInternalViewAttribute(String, Any?)
162162
fun setSyntheticsAttribute(String?, String?)
163+
fun enableJankStatsTracking(android.app.Activity)
163164
companion object
164165
fun setTelemetryConfigurationEventMapper(RumConfiguration.Builder, com.datadog.android.event.EventMapper<com.datadog.android.telemetry.model.TelemetryConfigurationEvent>): RumConfiguration.Builder
165166
fun setAdditionalConfiguration(RumConfiguration.Builder, Map<String, Any>): RumConfiguration.Builder

features/dd-sdk-android-rum/api/dd-sdk-android-rum.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ public final class com/datadog/android/rum/_RumInternalProxy {
235235
public static final field Companion Lcom/datadog/android/rum/_RumInternalProxy$Companion;
236236
public final fun addLongTask (JLjava/lang/String;)V
237237
public final fun setInternalViewAttribute (Ljava/lang/String;Ljava/lang/Object;)V
238+
public final fun enableJankStatsTracking (Landroid/app/Activity;)V
238239
public final fun setSyntheticsAttribute (Ljava/lang/String;Ljava/lang/String;)V
239240
public final fun updatePerformanceMetric (Lcom/datadog/android/rum/RumPerformanceMetric;D)V
240241
}

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/_RumInternalProxy.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package com.datadog.android.rum
88

9+
import android.app.Activity
910
import android.content.Intent
1011
import com.datadog.android.event.EventMapper
1112
import com.datadog.android.lint.InternalApi
@@ -60,6 +61,15 @@ class _RumInternalProxy internal constructor(private val rumMonitor: AdvancedRum
6061
rumMonitor.setSyntheticsAttribute(testId, resultId)
6162
}
6263

64+
/**
65+
* Enables the tracking of JankStats for the given activity. This should only be necessary for the
66+
* initial activity of an application if Datadog is initialized after that activity is created.
67+
* @param activity the activity to track
68+
*/
69+
fun enableJankStatsTracking(activity: Activity) {
70+
rumMonitor.enableJankStatsTracking(activity)
71+
}
72+
6373
internal fun setSyntheticsAttributeFromIntent(intent: Intent) {
6474
@Suppress("TooGenericExceptionCaught")
6575
val extras = try { intent.extras } catch (_: Exception) { null }

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/RumFeature.kt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package com.datadog.android.rum.internal
88

9+
import android.app.Activity
910
import android.app.ActivityManager
1011
import android.app.Application
1112
import android.app.ApplicationExitInfo
@@ -379,6 +380,25 @@ internal class RumFeature(
379380
}
380381
}
381382

383+
/**
384+
* Enables the tracking of JankStats for the given activity. This should only be necessary for the
385+
* initial activity of an application if Datadog is initialized after that activity is created.
386+
* @param activity the activity to track
387+
*/
388+
internal fun enableJankStatsTracking(activity: Activity) {
389+
try {
390+
@Suppress("UnsafeThirdPartyFunctionCall")
391+
jankStatsActivityLifecycleListener?.onActivityStarted(activity)
392+
} catch (@Suppress("TooGenericExceptionCaught") e: Exception) {
393+
sdkCore.internalLogger.log(
394+
InternalLogger.Level.ERROR,
395+
InternalLogger.Target.TELEMETRY,
396+
{ FAILED_TO_ENABLE_JANK_STATS_TRACKING_MANUALLY },
397+
e
398+
)
399+
}
400+
}
401+
382402
private fun registerTrackingStrategies(appContext: Context) {
383403
actionTrackingStrategy.register(sdkCore, appContext)
384404
viewTrackingStrategy.register(sdkCore, appContext)
@@ -619,6 +639,8 @@ internal class RumFeature(
619639
internal const val RUM_FEATURE_NOT_YET_INITIALIZED =
620640
"RUM feature is not initialized yet, you need to register it with a" +
621641
" SDK instance by calling SdkCore#registerFeature method."
642+
internal const val FAILED_TO_ENABLE_JANK_STATS_TRACKING_MANUALLY =
643+
"Manually enabling JankStats tracking threw an exception."
622644

623645
private fun provideUserTrackingStrategy(
624646
touchTargetExtraAttributesProviders: Array<ViewAttributesProvider>,

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/AdvancedRumMonitor.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package com.datadog.android.rum.internal.monitor
88

9+
import android.app.Activity
910
import com.datadog.android.core.feature.event.ThreadDump
1011
import com.datadog.android.internal.telemetry.InternalTelemetryEvent
1112
import com.datadog.android.rum.RumErrorSource
@@ -51,4 +52,6 @@ internal interface AdvancedRumMonitor : RumMonitor, AdvancedNetworkRumMonitor {
5152
fun setInternalViewAttribute(key: String, value: Any?)
5253

5354
fun setSyntheticsAttribute(testId: String, resultId: String)
55+
56+
fun enableJankStatsTracking(activity: Activity)
5457
}

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitor.kt

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package com.datadog.android.rum.internal.monitor
88

9+
import android.app.Activity
910
import android.app.ActivityManager
1011
import android.os.Handler
1112
import com.datadog.android.api.InternalLogger
@@ -644,6 +645,12 @@ internal class DatadogRumMonitor(
644645
handleEvent(RumRawEvent.TelemetryEventWrapper(telemetryEvent))
645646
}
646647

648+
override fun enableJankStatsTracking(activity: Activity) {
649+
sdkCore.getFeature(Feature.RUM_FEATURE_NAME)
650+
?.unwrap<RumFeature>()
651+
?.enableJankStatsTracking(activity)
652+
}
653+
647654
// endregion
648655

649656
// region Internal

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/vitals/JankStatsActivityLifecycleListener.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ internal class JankStatsActivityLifecycleListener(
165165

166166
private fun trackActivity(window: Window, activity: Activity) {
167167
val list = activeActivities[window] ?: mutableListOf()
168+
if (list.find { it.get() == activity } != null) {
169+
return
170+
}
168171
list.add(WeakReference(activity))
169172
activeActivities[window] = list
170173
}

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/RumInternalProxyTest.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package com.datadog.android.rum
88

9+
import android.app.Activity
910
import com.datadog.android.rum.internal.monitor.AdvancedRumMonitor
1011
import com.datadog.android.rum.utils.forge.Configurator
1112
import fr.xgouchet.elmyr.Forge
@@ -62,4 +63,18 @@ internal class RumInternalProxyTest {
6263
// Then
6364
verify(mockRumMonitor).updatePerformanceMetric(metric, value)
6465
}
66+
67+
@Test
68+
fun `M proxy enableJankStatsTracking to RumMonitor W enableJankStatsTracking()`() {
69+
// Given
70+
val mockRumMonitor = mock(AdvancedRumMonitor::class.java)
71+
val proxy = _RumInternalProxy(mockRumMonitor)
72+
val activity: Activity = mock()
73+
74+
// When
75+
proxy.enableJankStatsTracking(activity)
76+
77+
// Then
78+
verify(mockRumMonitor).enableJankStatsTracking(activity)
79+
}
6580
}

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/RumFeatureTest.kt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package com.datadog.android.rum.internal
88

9+
import android.app.Activity
910
import android.app.ActivityManager
1011
import android.app.Application
1112
import android.app.ApplicationExitInfo
@@ -534,6 +535,26 @@ internal class RumFeatureTest {
534535
.isNull()
535536
}
536537

538+
@Test
539+
fun `M call onActivityStarted W enableJankStatsTracking()`() {
540+
// Given
541+
val activity: Activity = mock()
542+
testedFeature = RumFeature(
543+
mockSdkCore,
544+
fakeApplicationId.toString(),
545+
fakeConfiguration,
546+
lateCrashReporterFactory = { mockLateCrashReporter }
547+
)
548+
val mockJankStatsActivityLifecycleListener = mock<JankStatsActivityLifecycleListener>()
549+
testedFeature.jankStatsActivityLifecycleListener = mockJankStatsActivityLifecycleListener
550+
551+
// When
552+
testedFeature.enableJankStatsTracking(activity)
553+
554+
// Then
555+
verify(mockJankStatsActivityLifecycleListener).onActivityStarted(activity)
556+
}
557+
537558
@Test
538559
fun `M use noop viewTrackingStrategy W onStop()`() {
539560
// Given

features/dd-sdk-android-rum/src/test/kotlin/com/datadog/android/rum/internal/monitor/DatadogRumMonitorTest.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
package com.datadog.android.rum.internal.monitor
88

9+
import android.app.Activity
910
import android.app.ActivityManager
1011
import android.os.Handler
1112
import com.datadog.android.api.InternalLogger
@@ -1911,6 +1912,22 @@ internal class DatadogRumMonitorTest {
19111912
}
19121913
}
19131914

1915+
@Test
1916+
fun `M call enableJankStatsTracking on RUM feature W enableJankStatsTracking`() {
1917+
// Given
1918+
val mockActivity = mock<Activity>()
1919+
val mockRumScope = mock<FeatureScope>()
1920+
whenever(mockSdkCore.getFeature(Feature.RUM_FEATURE_NAME)) doReturn mockRumScope
1921+
val mockRumFeature = mock<RumFeature>()
1922+
whenever(mockRumScope.unwrap<RumFeature>()) doReturn mockRumFeature
1923+
1924+
// When
1925+
testedMonitor.enableJankStatsTracking(mockActivity)
1926+
1927+
// Then
1928+
verify(mockRumFeature).enableJankStatsTracking(mockActivity)
1929+
}
1930+
19141931
@Test
19151932
fun `M call sessionEndedMetricDispatcher W addSkippedFrame`(
19161933
@IntForgery(min = 0, max = 100) count: Int,

0 commit comments

Comments
 (0)