Skip to content

Commit aa393a5

Browse files
committed
RUM-11120: Add battery and display attributes
1 parent c6b7a43 commit aa393a5

22 files changed

+611
-33
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,9 @@ object Rum {
141141
lastInteractionIdentifier = rumFeature.lastInteractionIdentifier,
142142
slowFramesListener = rumFeature.slowFramesListener,
143143
rumSessionTypeOverride = rumFeature.configuration.rumSessionTypeOverride,
144-
accessibilitySnapshotManager = rumFeature.accessibilitySnapshotManager
144+
accessibilitySnapshotManager = rumFeature.accessibilitySnapshotManager,
145+
batteryInfoProvider = rumFeature.batteryInfoProvider,
146+
displayInfoProvider = rumFeature.displayInfoProvider
145147
)
146148
}
147149

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,12 @@ import com.datadog.android.rum.internal.domain.accessibility.DatadogAccessibilit
4949
import com.datadog.android.rum.internal.domain.accessibility.DefaultAccessibilitySnapshotManager
5050
import com.datadog.android.rum.internal.domain.accessibility.NoOpAccessibilityReader
5151
import com.datadog.android.rum.internal.domain.accessibility.NoOpAccessibilitySnapshotManager
52+
import com.datadog.android.rum.internal.domain.battery.BatteryInfoProvider
53+
import com.datadog.android.rum.internal.domain.battery.DefaultBatteryInfoProvider
54+
import com.datadog.android.rum.internal.domain.battery.NoOpBatteryInfoProvider
55+
import com.datadog.android.rum.internal.domain.display.DefaultDisplayInfoProvider
56+
import com.datadog.android.rum.internal.domain.display.DisplayInfoProvider
57+
import com.datadog.android.rum.internal.domain.display.NoOpDisplayInfoProvider
5258
import com.datadog.android.rum.internal.domain.event.RumEventMapper
5359
import com.datadog.android.rum.internal.domain.event.RumEventMetaDeserializer
5460
import com.datadog.android.rum.internal.domain.event.RumEventMetaSerializer
@@ -154,6 +160,8 @@ internal class RumFeature(
154160
internal var accessibilityReader: AccessibilityReader = NoOpAccessibilityReader()
155161
internal var accessibilitySnapshotManager: AccessibilitySnapshotManager =
156162
NoOpAccessibilitySnapshotManager()
163+
internal var batteryInfoProvider: BatteryInfoProvider = NoOpBatteryInfoProvider()
164+
internal var displayInfoProvider: DisplayInfoProvider = NoOpDisplayInfoProvider()
157165

158166
private val lateCrashEventHandler by lazy { lateCrashReporterFactory(sdkCore as InternalSdkCore) }
159167

@@ -193,6 +201,12 @@ internal class RumFeature(
193201
telemetryConfigurationSampleRate = configuration.telemetryConfigurationSampleRate
194202
backgroundEventTracking = configuration.backgroundEventTracking
195203
trackFrustrations = configuration.trackFrustrations
204+
batteryInfoProvider = DefaultBatteryInfoProvider(
205+
applicationContext = appContext
206+
)
207+
displayInfoProvider = DefaultDisplayInfoProvider(
208+
applicationContext = appContext
209+
)
196210

197211
configuration.viewTrackingStrategy?.let { viewTrackingStrategy = it }
198212
actionTrackingStrategy = if (configuration.userActionTracking) {
@@ -312,6 +326,8 @@ internal class RumFeature(
312326
accessibilitySnapshotManager = NoOpAccessibilitySnapshotManager()
313327
}
314328

329+
batteryInfoProvider = NoOpBatteryInfoProvider()
330+
315331
GlobalRumMonitor.unregister(sdkCore)
316332
}
317333

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.rum.internal.domain.battery
8+
9+
/**
10+
* Provides information about the battery state.
11+
*
12+
* @property batteryLevel the current battery charge level, expressed as a float from 0.0f (empty) to 1.0f (full).
13+
* @property lowPowerMode a boolean indicating whether the device is currently in Low Power Mode.
14+
*/
15+
internal data class BatteryInfo(
16+
val batteryLevel: Float? = null,
17+
val lowPowerMode: Boolean? = null
18+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.rum.internal.domain.battery
8+
9+
import com.datadog.tools.annotation.NoOpImplementation
10+
11+
@NoOpImplementation
12+
internal interface BatteryInfoProvider {
13+
fun getBatteryState(): BatteryInfo
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.rum.internal.domain.battery
8+
9+
import android.content.Context
10+
import android.content.Context.BATTERY_SERVICE
11+
import android.content.Context.POWER_SERVICE
12+
import android.os.BatteryManager
13+
import android.os.BatteryManager.BATTERY_PROPERTY_CAPACITY
14+
import android.os.PowerManager
15+
import kotlin.math.roundToInt
16+
17+
internal class DefaultBatteryInfoProvider(
18+
private val applicationContext: Context,
19+
private val powerManager: PowerManager? = applicationContext.getSystemService(POWER_SERVICE) as? PowerManager,
20+
private val batteryManager: BatteryManager? = applicationContext.getSystemService(
21+
BATTERY_SERVICE
22+
) as? BatteryManager
23+
) : BatteryInfoProvider {
24+
override fun getBatteryState(): BatteryInfo {
25+
return BatteryInfo(
26+
lowPowerMode = getLowPowerMode(),
27+
batteryLevel = getBatteryLevel()
28+
)
29+
}
30+
31+
private fun getLowPowerMode(): Boolean? {
32+
return powerManager?.isPowerSaveMode
33+
}
34+
35+
private fun getBatteryLevel(): Float? {
36+
val rawCapacity = batteryManager?.getIntProperty(BATTERY_PROPERTY_CAPACITY) ?: return null
37+
val rawBatteryLevel = rawCapacity / FULL_BATTERY_PCT
38+
return roundToOneDecimalPlace(rawBatteryLevel)
39+
}
40+
41+
private fun roundToOneDecimalPlace(input: Float): Float {
42+
return (input * DECIMAL_SCALING).roundToInt() / DECIMAL_SCALING
43+
}
44+
45+
private companion object {
46+
const val FULL_BATTERY_PCT = 100f
47+
const val DECIMAL_SCALING = 10f
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.rum.internal.domain.display
8+
9+
import android.content.Context
10+
import android.provider.Settings.System.SCREEN_BRIGHTNESS
11+
import kotlin.math.roundToInt
12+
13+
internal class DefaultDisplayInfoProvider(
14+
private val applicationContext: Context,
15+
private val systemSettingsWrapper: SystemSettingsWrapper = SystemSettingsWrapper(applicationContext)
16+
) : DisplayInfoProvider {
17+
18+
override fun getBrightnessLevel(): Float? {
19+
val rawBrightnessValue = systemSettingsWrapper.getInt(SCREEN_BRIGHTNESS).toFloat()
20+
val normalizedBrightness = rawBrightnessValue / MAX_BRIGHTNESS
21+
return roundToOneDecimalPlace(normalizedBrightness)
22+
}
23+
24+
private fun roundToOneDecimalPlace(input: Float): Float {
25+
return (input * DECIMAL_SCALING).roundToInt() / DECIMAL_SCALING
26+
}
27+
28+
private companion object {
29+
const val MAX_BRIGHTNESS = 255f
30+
const val DECIMAL_SCALING = 10f
31+
}
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.rum.internal.domain.display
8+
9+
import com.datadog.tools.annotation.NoOpImplementation
10+
11+
@NoOpImplementation
12+
internal interface DisplayInfoProvider {
13+
fun getBrightnessLevel(): Float?
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3+
* This product includes software developed at Datadog (https://www.datadoghq.com/).
4+
* Copyright 2016-Present Datadog, Inc.
5+
*/
6+
7+
package com.datadog.android.rum.internal.domain.display
8+
9+
import android.content.Context
10+
import android.provider.Settings
11+
12+
internal class SystemSettingsWrapper(
13+
private val applicationContext: Context
14+
) {
15+
16+
fun getInt(name: String): Int {
17+
return Settings.System.getInt(applicationContext.contentResolver, name)
18+
}
19+
}

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumApplicationScope.kt

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ import com.datadog.android.rum.RumSessionType
1919
import com.datadog.android.rum.internal.domain.RumContext
2020
import com.datadog.android.rum.internal.domain.Time
2121
import com.datadog.android.rum.internal.domain.accessibility.AccessibilitySnapshotManager
22+
import com.datadog.android.rum.internal.domain.battery.BatteryInfoProvider
23+
import com.datadog.android.rum.internal.domain.display.DisplayInfoProvider
2224
import com.datadog.android.rum.internal.metric.SessionMetricDispatcher
2325
import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener
2426
import com.datadog.android.rum.internal.vitals.VitalMonitor
@@ -43,7 +45,9 @@ internal class RumApplicationScope(
4345
internal val lastInteractionIdentifier: LastInteractionIdentifier?,
4446
private val slowFramesListener: SlowFramesListener?,
4547
private val rumSessionTypeOverride: RumSessionType?,
46-
private val accessibilitySnapshotManager: AccessibilitySnapshotManager
48+
private val accessibilitySnapshotManager: AccessibilitySnapshotManager,
49+
private val batteryInfoProvider: BatteryInfoProvider,
50+
private val displayInfoProvider: DisplayInfoProvider
4751
) : RumScope, RumViewChangedListener {
4852

4953
private var rumContext = RumContext(applicationId = applicationId)
@@ -67,7 +71,9 @@ internal class RumApplicationScope(
6771
lastInteractionIdentifier = lastInteractionIdentifier,
6872
slowFramesListener = slowFramesListener,
6973
rumSessionTypeOverride = rumSessionTypeOverride,
70-
accessibilitySnapshotManager = accessibilitySnapshotManager
74+
accessibilitySnapshotManager = accessibilitySnapshotManager,
75+
batteryInfoProvider = batteryInfoProvider,
76+
displayInfoProvider = displayInfoProvider
7177
)
7278
)
7379

@@ -164,7 +170,9 @@ internal class RumApplicationScope(
164170
lastInteractionIdentifier = lastInteractionIdentifier,
165171
slowFramesListener = slowFramesListener,
166172
rumSessionTypeOverride = rumSessionTypeOverride,
167-
accessibilitySnapshotManager = accessibilitySnapshotManager
173+
accessibilitySnapshotManager = accessibilitySnapshotManager,
174+
batteryInfoProvider = batteryInfoProvider,
175+
displayInfoProvider = displayInfoProvider
168176
)
169177
childScopes.add(newSession)
170178
if (event !is RumRawEvent.StartView) {

features/dd-sdk-android-rum/src/main/kotlin/com/datadog/android/rum/internal/domain/scope/RumSessionScope.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ import com.datadog.android.rum.RumSessionType
1717
import com.datadog.android.rum.internal.domain.RumContext
1818
import com.datadog.android.rum.internal.domain.Time
1919
import com.datadog.android.rum.internal.domain.accessibility.AccessibilitySnapshotManager
20+
import com.datadog.android.rum.internal.domain.battery.BatteryInfoProvider
21+
import com.datadog.android.rum.internal.domain.display.DisplayInfoProvider
2022
import com.datadog.android.rum.internal.metric.SessionMetricDispatcher
2123
import com.datadog.android.rum.internal.metric.slowframes.SlowFramesListener
2224
import com.datadog.android.rum.internal.utils.percent
@@ -47,6 +49,8 @@ internal class RumSessionScope(
4749
lastInteractionIdentifier: LastInteractionIdentifier?,
4850
slowFramesListener: SlowFramesListener?,
4951
private val accessibilitySnapshotManager: AccessibilitySnapshotManager,
52+
private val batteryInfoProvider: BatteryInfoProvider,
53+
private val displayInfoProvider: DisplayInfoProvider,
5054
private val sessionInactivityNanos: Long = DEFAULT_SESSION_INACTIVITY_NS,
5155
private val sessionMaxDurationNanos: Long = DEFAULT_SESSION_MAX_DURATION_NS,
5256
rumSessionTypeOverride: RumSessionType?
@@ -82,7 +86,9 @@ internal class RumSessionScope(
8286
slowFramesListener = slowFramesListener,
8387
lastInteractionIdentifier = lastInteractionIdentifier,
8488
rumSessionTypeOverride = rumSessionTypeOverride,
85-
accessibilitySnapshotManager = accessibilitySnapshotManager
89+
accessibilitySnapshotManager = accessibilitySnapshotManager,
90+
batteryInfoProvider = batteryInfoProvider,
91+
displayInfoProvider = displayInfoProvider
8692
)
8793

8894
init {

0 commit comments

Comments
 (0)