Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
8a14888
RUM-12062: Overlay now configurable directly in application
kikoveiga Oct 28, 2025
2cc148c
RUM-12060: Remove repeated line
kikoveiga Oct 27, 2025
69e0563
RUM-12060: Update README.md
kikoveiga Oct 28, 2025
b5d47a5
RUM-12060: Cut screenshot
kikoveiga Oct 28, 2025
c48a483
RUM-12060: Update screenshot
kikoveiga Oct 28, 2025
53ec2ca
RUM-12060: Update screenshot
kikoveiga Oct 28, 2025
47acfe5
RUM-12060: Format README.md
kikoveiga Oct 28, 2025
d4296c2
RUM-12060: Push requested changes
kikoveiga Oct 28, 2025
e49a7a9
RUM-12060: Update apiSurface
kikoveiga Oct 28, 2025
a97e6d8
RUM-12061: Continue unit and integration tests
kikoveiga Oct 29, 2025
7ef18f0
RUM-12061: Add more unit and integration tests
kikoveiga Oct 29, 2025
3590c10
RUM-12061: Finish tests
kikoveiga Oct 30, 2025
07e024e
RUM-12061: Fix formatting
kikoveiga Oct 30, 2025
ae7a408
RUM-12062: Fixing rebase
kikoveiga Oct 30, 2025
8b92c71
RUM-12062: Begin reconfiguration of DefaultInsightsCollector with an …
kikoveiga Oct 30, 2025
48f38ac
RUM-12062: Add RumConfiguration Builder extension function
kikoveiga Oct 30, 2025
c56bea9
RUM-12062: Improve overlay's animation and attaching to activities
kikoveiga Oct 31, 2025
1e22471
RUM-12062: Add comments and fix magic numbers, dependencies missing i…
kikoveiga Oct 31, 2025
2971f00
Merge branch 'kikoveiga/RUM-12061/add-tests' into kikoveiga/RUM-12062…
kikoveiga Oct 31, 2025
c53e593
Rollback one line
kikoveiga Oct 31, 2025
d9504f7
RUM-12062: Add @ExperimentalRumApi annotation to OverlayManager.kt
kikoveiga Oct 31, 2025
e8efdbd
RUM-12062: ChangeOverlayManager to class
kikoveiga Nov 3, 2025
e1bdbed
RUM-12062: Remove unused dependency
kikoveiga Nov 3, 2025
69f3227
Merge branch 'tvaleev/feature/innovation-week-07-04-25' into kikoveig…
kikoveiga Nov 3, 2025
c567d6a
RUM-12062: Fix unit tests
kikoveiga Nov 3, 2025
29c1752
RUM-12062: Begin reflection
kikoveiga Nov 4, 2025
4c83907
RUM-12062: Reflection working and README.md done
kikoveiga Nov 4, 2025
f3a66c9
RUM-12062: Remove unused lines in README.md
kikoveiga Nov 4, 2025
4ead2c9
RUM-12062: Clean up
kikoveiga Nov 4, 2025
35dfe83
RUM-12062: Test removal of unnecessary suppress
kikoveiga Nov 5, 2025
0a8567b
RUM-12062: Revert
kikoveiga Nov 5, 2025
95e2389
RUM-12062: Revert
kikoveiga Nov 5, 2025
cf9befe
RUM-12062: Improve documentation and clean up
kikoveiga Nov 5, 2025
e9e72d0
RUM-12062: Push suggested changes
kikoveiga Nov 5, 2025
e07a7eb
RUM-12062: Remove unnecessary annotations
kikoveiga Nov 10, 2025
2acb188
RUM-12062: Change enableRumDebugWidget function, now able to allow it…
kikoveiga Nov 12, 2025
d7b2d05
RUM-12062: Update API files
kikoveiga Nov 12, 2025
de79df8
RUM-12062: Move isDebuggable code inline
kikoveiga Nov 12, 2025
e131311
RUM-12062: Update variable name
kikoveiga Nov 12, 2025
703c3f4
RUM-12062: Add consumer-rules.pro file and other small improvements
kikoveiga Nov 13, 2025
7c2f184
RUM-12062: Improve message of internal log
kikoveiga Nov 13, 2025
a82c5f9
RUM-12062: Remove reflection
kikoveiga Nov 25, 2025
ac995b5
RUM-12062: Fix pipeline
kikoveiga Nov 26, 2025
e19cb84
RUM-12062: Fix pipeline
kikoveiga Nov 26, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions detekt_custom_safe_calls.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ datadog:
UnsafeThirdPartyFunctionCall:
knownSafeCalls:
# region Android APIs
- "android.app.Activity.findViewById(kotlin.Int)"
- "android.app.Activity.getSystemService(kotlin.String)"
- "android.app.Activity.hashCode()"
- "android.app.Application.registerActivityLifecycleCallbacks(android.app.Application.ActivityLifecycleCallbacks?)"
Expand Down Expand Up @@ -97,6 +98,7 @@ datadog:
- "android.view.resolveSize(kotlin.Int, kotlin.Int)"
- "android.view.View.addOnAttachStateChangeListener(android.view.View.OnAttachStateChangeListener?)"
- "android.view.View.animate()"
- "android.view.View.bringToFront()"
- "android.view.View.findViewById(kotlin.Int)"
- "android.view.View.getChildAt(kotlin.Int)"
- "android.view.View.getTag(kotlin.Int)"
Expand All @@ -109,8 +111,11 @@ datadog:
- "android.view.View.setOnTouchListener(android.view.View.OnTouchListener?)"
- "android.view.View.setTag(kotlin.Int, kotlin.Any?)"
- "android.view.View.takeIf(kotlin.Function1)"
- "android.view.ViewGroup.addView(android.view.View?, android.view.ViewGroup.LayoutParams?)"
- "android.view.ViewGroup.findViewById(kotlin.Int)"
- "android.view.ViewGroup.getChildAt(kotlin.Int)"
- "android.view.ViewGroup.LayoutParams.constructor(kotlin.Int, kotlin.Int)"
- "android.view.ViewGroup.removeView(android.view.View?)"
- "android.view.ViewPropertyAnimator.alpha(kotlin.Float)"
- "android.view.ViewPropertyAnimator.cancel()"
- "android.view.ViewPropertyAnimator.scaleX(kotlin.Float)"
Expand Down Expand Up @@ -565,6 +570,9 @@ datadog:
- "java.util.HashMap.orEmpty()"
- "java.util.HashSet.addAll(kotlin.collections.Collection)"
- "java.util.HashSet.find(kotlin.Function1)"
- "java.util.IdentityHashMap.clear()"
- "java.util.IdentityHashMap.constructor()"
- "java.util.IdentityHashMap.remove(android.app.Activity?)"
- "java.util.Locale.getDefault()"
- "java.util.Locale.toLanguageTag()"
- "java.util.Properties.constructor()"
Expand Down
33 changes: 32 additions & 1 deletion features/dd-sdk-android-rum-debug-widget/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,35 @@ This module can be integrated into your application to help visualize RUM data b
It is intended for debugging and development purposes only and **should not** be included in production builds.
As shown in the screenshot below, the widget provides a floating overlay that displays key metrics such as **memory usage**, **CPU load** and **RUM events**.

<img src="../../docs/images/screenshot_rumdebugwidget.png" width="400" alt="Datadog RUM Debug Widget"/>
<img src="../../docs/images/screenshot_rumdebugwidget.png" width="400" alt="Datadog RUM Debug Widget"/>

## Getting Started

To include this module in your project, simply add the following dependency to your application's `build.gradle` file:

```groovy
dependencies {
debugImplementation("com.datadoghq:dd-sdk-android-rum-debug-widget:<latest-version>")
}
```

### Initial Setup

To enable the RUM Debug Widget, add the following line to your `RumConfiguration.Builder` setup in the `Application` class:

```kotlin
import com.datadog.android.rum.enableRumDebugWidget

RumConfiguration.Builder(...)
.enableRumDebugWidget(application = this)
```

## Contributing

Pull requests are welcome, but please open an issue first to discuss what you
would like to change. For more information, read the
[Contributing Guide](../../CONTRIBUTING.md).

## License

[Apache License, v2.0](../../LICENSE)
21 changes: 1 addition & 20 deletions features/dd-sdk-android-rum-debug-widget/api/apiSurface
Original file line number Diff line number Diff line change
@@ -1,20 +1 @@
class com.datadog.android.insights.DefaultInsightsCollector : com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector
constructor(Int = 50, Long = 100L)
override var maxSize: Int
override var updateIntervalMs: Long
override fun onAction()
override fun onNewView(String)
override fun onSlowFrame(Long, Long)
override fun onLongTask(Long, Long)
override fun onNetworkRequest(Long, Long)
override fun addUpdateListener(com.datadog.android.rum.internal.instrumentation.insights.InsightsUpdatesListener)
override fun removeUpdateListener(com.datadog.android.rum.internal.instrumentation.insights.InsightsUpdatesListener)
override fun onMemoryVital(Double?)
override fun onCpuVital(Double?)
override fun onSlowFrameRate(Double?)
companion object
class com.datadog.android.insights.LocalInsightOverlay : com.datadog.android.rum.internal.instrumentation.insights.InsightsUpdatesListener
fun attach(android.app.Activity)
fun detach()
override fun onDataUpdated()
companion object
fun com.datadog.android.rum.RumConfiguration.Builder.enableRumDebugWidget(android.app.Application, Boolean = false): com.datadog.android.rum.RumConfiguration.Builder
Original file line number Diff line number Diff line change
@@ -1,34 +1,5 @@
public final class com/datadog/android/insights/DefaultInsightsCollector : com/datadog/android/rum/internal/instrumentation/insights/InsightsCollector {
public static final field Companion Lcom/datadog/android/insights/DefaultInsightsCollector$Companion;
public fun <init> (IJ)V
public synthetic fun <init> (IJILkotlin/jvm/internal/DefaultConstructorMarker;)V
public fun addUpdateListener (Lcom/datadog/android/rum/internal/instrumentation/insights/InsightsUpdatesListener;)V
public fun getMaxSize ()I
public fun getUpdateIntervalMs ()J
public fun onAction ()V
public fun onCpuVital (Ljava/lang/Double;)V
public fun onLongTask (JJ)V
public fun onMemoryVital (Ljava/lang/Double;)V
public fun onNetworkRequest (JJ)V
public fun onNewView (Ljava/lang/String;)V
public fun onSlowFrame (JJ)V
public fun onSlowFrameRate (Ljava/lang/Double;)V
public fun removeUpdateListener (Lcom/datadog/android/rum/internal/instrumentation/insights/InsightsUpdatesListener;)V
public fun setMaxSize (I)V
public fun setUpdateIntervalMs (J)V
}

public final class com/datadog/android/insights/DefaultInsightsCollector$Companion {
}

public final class com/datadog/android/insights/LocalInsightOverlay : com/datadog/android/rum/internal/instrumentation/insights/InsightsUpdatesListener {
public static final field Companion Lcom/datadog/android/insights/LocalInsightOverlay$Companion;
public fun <init> ()V
public final fun attach (Landroid/app/Activity;)V
public final fun detach ()V
public fun onDataUpdated ()V
}

public final class com/datadog/android/insights/LocalInsightOverlay$Companion {
public final class com/datadog/android/insights/internal/RumDebugWidgetKt {
public static final fun enableRumDebugWidget (Lcom/datadog/android/rum/RumConfiguration$Builder;Landroid/app/Application;Z)Lcom/datadog/android/rum/RumConfiguration$Builder;
public static synthetic fun enableRumDebugWidget$default (Lcom/datadog/android/rum/RumConfiguration$Builder;Landroid/app/Application;ZILjava/lang/Object;)Lcom/datadog/android/rum/RumConfiguration$Builder;
}

4 changes: 4 additions & 0 deletions features/dd-sdk-android-rum-debug-widget/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@ plugins {
}

android {
defaultConfig {
consumerProguardFiles("consumer-rules.pro")
}
Comment thread
kikoveiga marked this conversation as resolved.

namespace = "com.datadog.android.rumdebugwidget"
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-keep class com.datadog.android.insights.internal.RumDebugWidget
Comment thread
kikoveiga marked this conversation as resolved.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2016-Present Datadog, Inc.
*/

package com.datadog.android.insights

import android.app.Application
import android.content.pm.ApplicationInfo
import com.datadog.android.insights.internal.DefaultInsightsCollector
import com.datadog.android.insights.internal.overlay.OverlayManager
import com.datadog.android.rum.RumConfiguration
import com.datadog.android.rum._RumInternalProxy

/**
* Enables the RUM Debug Widget for the given [application].
*
* By default, the widget is only enabled in debug builds (when the application is debuggable).
* To enable it in release builds (e.g., for local testing), set [allowInRelease] to `true` and
* add the `dd-sdk-android-rum-debug-widget` module as `implementation` (not `debugImplementation`)
* in your `build.gradle` file.
*
* @param application The application where to enable the RUM Debug Widget.
* @param allowInRelease Set to `true` to enable the widget in release builds. Defaults to `false`
* to prevent accidental exposure in production.
* @return The same [RumConfiguration.Builder] instance.
*/
fun RumConfiguration.Builder.enableRumDebugWidget(
application: Application,
allowInRelease: Boolean = false
): RumConfiguration.Builder = apply {
val isApplicationDebuggable = (application.applicationInfo.flags and ApplicationInfo.FLAG_DEBUGGABLE) != 0
if (!isApplicationDebuggable && !allowInRelease) return@apply

val insightsCollector = DefaultInsightsCollector()
_RumInternalProxy.setInsightsCollector(this, insightsCollector)
application.registerActivityLifecycleCallbacks(OverlayManager(insightsCollector))
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* Copyright 2016-Present Datadog, Inc.
*/

package com.datadog.android.insights
package com.datadog.android.insights.internal

import android.os.Handler
import android.os.Looper
Expand All @@ -13,7 +13,6 @@ import com.datadog.android.insights.internal.extensions.Mb
import com.datadog.android.insights.internal.extensions.round
import com.datadog.android.insights.internal.platform.Platform
import com.datadog.android.internal.collections.EvictingQueue
import com.datadog.android.rum.ExperimentalRumApi
import com.datadog.android.rum.internal.instrumentation.insights.InsightsCollector
import com.datadog.android.rum.internal.instrumentation.insights.InsightsUpdatesListener
import java.util.concurrent.CopyOnWriteArraySet
Expand All @@ -27,8 +26,7 @@ import java.util.concurrent.CopyOnWriteArraySet
* @param handler Handler to post updates on. Injected for test purposes.
* @param platform Platform abstraction to access system information. Injected for test purposes.
*/
@ExperimentalRumApi
class DefaultInsightsCollector internal constructor(
internal class DefaultInsightsCollector internal constructor(
maxSize: Int,
updateIntervalMs: Long,
private val handler: Handler,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ internal class InsightStateStorage private constructor(
private val sharedPreferences: SharedPreferences
) {

constructor(context: Context) : this(context.getSharedPreferences(INSIGHT_PREFERENCES, Context.MODE_PRIVATE))
constructor(context: Context) : this(
context.applicationContext.getSharedPreferences(INSIGHT_PREFERENCES, Context.MODE_PRIVATE)
)

@Suppress("UnsafeThirdPartyFunctionCall") // safe because there is a putFloat call for each getFloat
var widgetPosition: Pair<Float, Float>
Expand Down
Loading
Loading