Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
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
3 changes: 3 additions & 0 deletions detekt_custom.yml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@ datadog:
- "android.graphics.drawable.LayerDrawable.getDrawable(kotlin.Int):java.lang.IndexOutOfBoundsException"
- "android.net.ConnectivityManager.registerDefaultNetworkCallback(android.net.ConnectivityManager.NetworkCallback):java.lang.IllegalArgumentException,java.lang.SecurityException"
- "android.net.ConnectivityManager.unregisterNetworkCallback(android.net.ConnectivityManager.NetworkCallback):java.lang.SecurityException"
- "android.provider.Settings.System.getInt(android.content.ContentResolver?, kotlin.String?):android.provider.Settings.SettingNotFoundException"
- "android.util.Base64.encodeToString(kotlin.ByteArray?, kotlin.Int):java.lang.AssertionError"
- "android.view.Choreographer.getInstance():java.lang.IllegalStateException"
- "android.view.Choreographer.postFrameCallback():java.lang.IllegalArgumentException"
Expand Down Expand Up @@ -389,6 +390,7 @@ datadog:
- "android.net.ConnectivityManager.NetworkCallback.onLost(android.net.Network)"
- "android.net.ConnectivityManager.getNetworkCapabilities(android.net.Network?)"
- "android.net.NetworkCapabilities.hasTransport(kotlin.Int)"
- "android.os.BatteryManager.getIntProperty(kotlin.Int)"
- "android.os.Bundle.get(kotlin.String?)"
- "android.os.Bundle.getString(kotlin.String?)"
- "android.os.Bundle.keySet()"
Expand All @@ -411,6 +413,7 @@ datadog:
- "android.os.SystemClock.elapsedRealtime()"
- "android.provider.Settings.Global.getUriFor(kotlin.String?)"
- "android.provider.Settings.Secure.getUriFor(kotlin.String?)"
- "android.provider.Settings.System.getUriFor(kotlin.String?)"
- "android.util.Log.e(kotlin.String?, kotlin.String)"
- "android.util.Log.e(kotlin.String?, kotlin.String?, kotlin.Throwable?)"
- "android.util.Log.getStackTraceString(kotlin.Throwable?)"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,9 @@ object Rum {
lastInteractionIdentifier = rumFeature.lastInteractionIdentifier,
slowFramesListener = rumFeature.slowFramesListener,
rumSessionTypeOverride = rumFeature.configuration.rumSessionTypeOverride,
accessibilitySnapshotManager = rumFeature.accessibilitySnapshotManager
accessibilitySnapshotManager = rumFeature.accessibilitySnapshotManager,
batteryInfoProvider = rumFeature.batteryInfoProvider,
displayInfoProvider = rumFeature.displayInfoProvider
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ import com.datadog.android.rum.configuration.SlowFramesConfiguration
import com.datadog.android.rum.configuration.VitalsUpdateFrequency
import com.datadog.android.rum.internal.anr.ANRDetectorRunnable
import com.datadog.android.rum.internal.debug.UiRumDebugListener
import com.datadog.android.rum.internal.domain.InfoProvider
import com.datadog.android.rum.internal.domain.NoOpInfoProvider
import com.datadog.android.rum.internal.domain.RumDataWriter
import com.datadog.android.rum.internal.domain.accessibility.AccessibilityReader
import com.datadog.android.rum.internal.domain.accessibility.AccessibilitySnapshotManager
import com.datadog.android.rum.internal.domain.accessibility.DatadogAccessibilityReader
import com.datadog.android.rum.internal.domain.accessibility.DefaultAccessibilitySnapshotManager
import com.datadog.android.rum.internal.domain.accessibility.NoOpAccessibilityReader
import com.datadog.android.rum.internal.domain.accessibility.NoOpAccessibilitySnapshotManager
import com.datadog.android.rum.internal.domain.battery.DefaultBatteryInfoProvider
import com.datadog.android.rum.internal.domain.display.DefaultDisplayInfoProvider
import com.datadog.android.rum.internal.domain.event.RumEventMapper
import com.datadog.android.rum.internal.domain.event.RumEventMetaDeserializer
import com.datadog.android.rum.internal.domain.event.RumEventMetaSerializer
Expand Down Expand Up @@ -151,9 +153,11 @@ internal class RumFeature(
internal var initialResourceIdentifier: InitialResourceIdentifier = NoOpInitialResourceIdentifier()
internal var lastInteractionIdentifier: LastInteractionIdentifier? = NoOpLastInteractionIdentifier()
internal var slowFramesListener: SlowFramesListener? = null
internal var accessibilityReader: AccessibilityReader = NoOpAccessibilityReader()
internal var accessibilityReader: InfoProvider = NoOpInfoProvider()
internal var accessibilitySnapshotManager: AccessibilitySnapshotManager =
NoOpAccessibilitySnapshotManager()
internal var batteryInfoProvider: InfoProvider = NoOpInfoProvider()
internal var displayInfoProvider: InfoProvider = NoOpInfoProvider()

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

Expand All @@ -166,8 +170,10 @@ internal class RumFeature(
this.appContext = appContext

if (configuration.collectAccessibility) {
accessibilityReader =
DatadogAccessibilityReader(applicationContext = appContext, internalLogger = sdkCore.internalLogger)
accessibilityReader = DatadogAccessibilityReader(
internalLogger = sdkCore.internalLogger,
applicationContext = appContext
)
accessibilitySnapshotManager = DefaultAccessibilitySnapshotManager(accessibilityReader)
}

Expand All @@ -193,6 +199,13 @@ internal class RumFeature(
telemetryConfigurationSampleRate = configuration.telemetryConfigurationSampleRate
backgroundEventTracking = configuration.backgroundEventTracking
trackFrustrations = configuration.trackFrustrations
batteryInfoProvider = DefaultBatteryInfoProvider(
applicationContext = appContext
)
displayInfoProvider = DefaultDisplayInfoProvider(
applicationContext = appContext,
internalLogger = sdkCore.internalLogger
)

configuration.viewTrackingStrategy?.let { viewTrackingStrategy = it }
actionTrackingStrategy = if (configuration.userActionTracking) {
Expand Down Expand Up @@ -306,17 +319,26 @@ internal class RumFeature(
vitalExecutorService = NoOpScheduledExecutorService()
sessionListener = NoOpRumSessionListener()

cleanupInfoProviders()

GlobalRumMonitor.unregister(sdkCore)
}

// endregion

private fun cleanupInfoProviders() {
if (configuration.collectAccessibility) {
accessibilityReader.cleanup()
accessibilityReader = NoOpAccessibilityReader()
accessibilityReader = NoOpInfoProvider()
accessibilitySnapshotManager = NoOpAccessibilitySnapshotManager()
}

GlobalRumMonitor.unregister(sdkCore)
batteryInfoProvider.cleanup()
batteryInfoProvider = NoOpInfoProvider()
displayInfoProvider.cleanup()
displayInfoProvider = NoOpInfoProvider()
}

// endregion

private fun createDataWriter(
configuration: Configuration,
sdkCore: InternalSdkCore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@
* Copyright 2016-Present Datadog, Inc.
*/

package com.datadog.android.rum.internal.domain.accessibility
package com.datadog.android.rum.internal.domain

import com.datadog.tools.annotation.NoOpImplementation

@NoOpImplementation
internal interface AccessibilityReader {
internal interface InfoProvider {
fun getState(): Map<String, Any>
fun cleanup()
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import android.view.View
import android.view.accessibility.AccessibilityManager
import android.view.accessibility.AccessibilityManager.TouchExplorationStateChangeListener
import com.datadog.android.api.InternalLogger
import java.util.concurrent.atomic.AtomicBoolean
import com.datadog.android.rum.internal.domain.InfoProvider
import java.util.concurrent.atomic.AtomicLong

@Suppress("TooManyFunctions")
Expand All @@ -37,14 +37,7 @@ internal class DatadogAccessibilityReader(
private val secureWrapper: SecureWrapper = SecureWrapper(),
private val globalWrapper: GlobalWrapper = GlobalWrapper(),
private val handler: Handler = Handler(Looper.getMainLooper())
) : AccessibilityReader, ComponentCallbacks {

@Volatile
private var currentState = Accessibility()

private var lastPollTime: AtomicLong = AtomicLong(0)

private var isInitialized = AtomicBoolean(false)
) : InfoProvider, ComponentCallbacks {

private val displayInversionListener = object : ContentObserver(handler) {
override fun onChange(selfChange: Boolean, uri: Uri?) {
Expand Down Expand Up @@ -72,15 +65,22 @@ internal class DatadogAccessibilityReader(
updateState { it.copy(isScreenReaderEnabled = newScreenReaderEnabled) }
}

@Volatile
private var currentState = Accessibility()

private var lastPollTime: AtomicLong = AtomicLong(0)

init {
registerListeners()
buildInitialState()
}

override fun cleanup() {
if (isInitialized.get()) {
accessibilityManager?.removeTouchExplorationStateChangeListener(touchListener)
applicationContext.contentResolver.unregisterContentObserver(animationDurationListener)
applicationContext.contentResolver.unregisterContentObserver(captioningListener)
applicationContext.contentResolver.unregisterContentObserver(displayInversionListener)
applicationContext.unregisterComponentCallbacks(this)
isInitialized.set(false)
}
accessibilityManager?.removeTouchExplorationStateChangeListener(touchListener)
applicationContext.contentResolver.unregisterContentObserver(animationDurationListener)
applicationContext.contentResolver.unregisterContentObserver(captioningListener)
applicationContext.contentResolver.unregisterContentObserver(displayInversionListener)
applicationContext.unregisterComponentCallbacks(this)
}

override fun onLowMemory() {
Expand All @@ -97,8 +97,6 @@ internal class DatadogAccessibilityReader(

@Synchronized
override fun getState(): Map<String, Any> {
ensureInitialized()

val currentTime = System.currentTimeMillis()
val shouldPoll = currentTime - lastPollTime.get() >= POLL_THRESHOLD
if (shouldPoll) {
Expand All @@ -114,16 +112,8 @@ internal class DatadogAccessibilityReader(
currentState = updater(currentState)
}

private fun ensureInitialized() {
if (!isInitialized.get()) {
registerListeners()
currentState = buildInitialState()
isInitialized.set(true)
}
}

private fun buildInitialState(): Accessibility {
return Accessibility(
private fun buildInitialState() {
currentState = Accessibility(
textSize = getTextSize(),
isScreenReaderEnabled = isScreenReaderEnabled(accessibilityManager),
isColorInversionEnabled = isDisplayInversionEnabled(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@

package com.datadog.android.rum.internal.domain.accessibility

import com.datadog.android.rum.internal.domain.InfoProvider

internal class DefaultAccessibilitySnapshotManager(
private val accessibilityReader: AccessibilityReader
private val accessibilityReader: InfoProvider
) : AccessibilitySnapshotManager {
private val lastSnapshot = mutableMapOf<String, Any>()

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* 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.rum.internal.domain.battery

import androidx.annotation.FloatRange

/**
* Provides information about the battery state.
*
* @property batteryLevel the current battery charge level, expressed as a float from 0.0f (empty) to 1.0f (full).
* @property lowPowerMode a boolean indicating whether the device is currently in Low Power Mode.
*/
internal data class BatteryInfo(
@FloatRange(0.0, 1.0) val batteryLevel: Float? = null,
val lowPowerMode: Boolean? = null
) {
fun toMap(): Map<String, Any> = buildMap {
batteryLevel?.let { put(BATTERY_LEVEL_KEY, it) }
lowPowerMode?.let { put(LOW_POWER_MODE_KEY, it) }
}

internal companion object {
const val BATTERY_LEVEL_KEY = "battery_level"
const val LOW_POWER_MODE_KEY = "low_power_mode"

fun fromMap(map: Map<String, Any>): BatteryInfo {
return BatteryInfo(
batteryLevel = map[BATTERY_LEVEL_KEY] as? Float,
lowPowerMode = map[LOW_POWER_MODE_KEY] as? Boolean
)
}
}
}
Loading
Loading