DataDog / dd-sdk-android

Datadog SDK for Android (Compatible with Kotlin and Java)
Apache License 2.0
150 stars 59 forks source link

Ability to control BatteryIntent processing for custom IOT devices #961

Open BobPfingsten opened 2 years ago

BobPfingsten commented 2 years ago

If a custom build of AOSP does not support or report the battery state for the device through the BatteryIntent broadcast logging is delayed or skipped. When this scenario happens there is no work around.

For example when a battery status is dumped from the ADB shell that reports something similar to the following:

dumpsys battery >>> Current Battery Service state: AC powered: false USB powered: false Wireless powered: false Max charging current: 0 Max charging voltage: 0 Charge counter: 0 status: 1 health: 1 present: false level: 0 scale: 100 voltage: 0 temperature: 0 technology:

This will prevent the SDK from syncing the logs back to the server. The only work around is to update the AOSP build which in some instances cannot be done in a timely manner.

To support custom builds that may not report battery stats there needs to be a way to provide a custom handler in BroadcastReceiverSystemInfoProvider for the BatteryIntent instead of only allowing the internal logic.

To facilitate user logic I propose the following of which I have a branch and PR for here

  1. Create an interface BatteryIntentHandler with a method for processing and returning the results of the BatteryIntent.
  2. Represent the results as BatterIntentHandlerResults that has values for full or charging (bool), charge level (int), and external power applied(bool).
  3. Move the existing logic into a class called DefaultBatteryIntentHandler
  4. Modify the BroadcastReceiverSystemInfoProvider constructor to accept the BatteryIntentHandler with a default value set to the DefaultBatteryIntentHandler.
  5. In Configuration.Builder add new setter to pass in the BatteryIntentHandler: setBatteryIntentHandler(handler: BatteryIntentHandler)
  6. In CoreFeature.setupInfoProviders use the BatteryIntentHandler if specified in the Configuration.Builder otherwise use the default constructor for BroadcastReceiverSystemInfoProvider.

The system can then be initialized like this:

val configuration = Configuration.Builder(
            logsEnabled = true,
            tracesEnabled = true,
            crashReportsEnabled = true,
            rumEnabled = true
        )
        if (NeedsCustomLogic) {
            configuration.setBatteryIntentHandler(object : BatteryIntentHandler {
                override fun handleBatteryIntent(intent: Intent): BatteryIntentResults {
                    return BatteryIntentResults(true, 100, true)
                }
            })
        }

        Datadog.initialize(
            context = this,
            credentials = Credentials(
                clientToken = "DD_CLIENT_TOKEN",
                envName = "environment",
                variant = "variant",
                rumApplicationId = "123",
                serviceName = "sample"
            ),
            configuration = configuration.build(),
            trackingConsent = TrackingConsent.GRANTED
        )
xgouchet commented 2 years ago

Hi @BobPfingsten and thanks for opening this issue. We totally appreciate the issue of having a device that doesn't play nice with the AOSP standards and doesn't report correctly its battery status or charging state. That being said, providing a custom way to bypass this check doesn't take into account the fact that this use case is an exception rather than a rule and adding a custom BatteryIntentHandler will more likely than not be used to "speed up" the upload of the gathered data at the expense of the battery life of end users. Because as far as the Android Framework is concerned, our approach respects perfectly all the information that is (or should be) available.

We're thinking of another approach to take into account the fact that a handful of devices are not reporting the relevant information, and we will try to work with you to ensure that it does work with the specific device that is causing you problems. We still need to shape out the details, but I'll come back to you very soon on this topic to ensure we can make a long term solution for this edge case.