Repository: corona-warn-app/cwa-app-android
File: Corona-Warn-App/src/main/java/de/rki/coronawarnapp/ccl/dccwalletinfo/calculation/DccWalletInfoCalculation.kt (Kotlin)

Code before:
import de.rki.coronawarnapp.util.TimeAndDateExtensions.seconds
import de.rki.coronawarnapp.util.coroutine.DefaultDispatcherProvider
import de.rki.coronawarnapp.util.serialization.BaseGson
import de.rki.coronawarnapp.util.serialization.BaseJackson
import kotlinx.coroutines.withContext
import org.joda.time.DateTime
import javax.inject.Inject

class DccWalletInfoCalculation @Inject constructor(
    @BaseJackson private val mapper: ObjectMapper,
    @BaseGson private val gson: Gson,
    private val cclJsonFunctions: CclJsonFunctions,
    private val dispatcherProvider: DefaultDispatcherProvider
) {

    private var boosterRulesNode: JsonNode = NullNode.instance

    fun init(boosterRules: List<DccValidationRule>) {
        boosterRulesNode = gson.toJson(boosterRules).toJsonNode()
    }

    @Suppress("BlockingMethodInNonBlockingContext")
    suspend fun getDccWalletInfo(
        dccList: List<CwaCovidCertificate>,
        dateTime: DateTime = DateTime.now()
    ): DccWalletInfo = withContext(dispatcherProvider.IO) {
        val output = cclJsonFunctions.evaluateFunction(
            FUNCTION_NAME,
            getDccWalletInfoInput(
                dccList = dccList,
                boosterNotificationRules = boosterRulesNode,
                defaultInputParameters = getDefaultInputParameters(dateTime)
            ).toJsonNode()
        )

        mapper.treeToValue(output, DccWalletInfo::class.java)
    }

    @VisibleForTesting
    internal fun getDccWalletInfoInput(
        dccList: List<CwaCovidCertificate>,
        boosterNotificationRules: JsonNode,
        defaultInputParameters: CclInputParameters,
    ) = DccWalletInfoInput(
        os = defaultInputParameters.os,
        language = defaultInputParameters.language,
        now = SystemTime(
            timestamp = defaultInputParameters.now.timestamp,
            localDate = defaultInputParameters.now.localDate,
            localDateTime = defaultInputParameters.now.localDateTime,
            localDateTimeMidnight = defaultInputParameters.now.localDateTimeMidnight,

Review comment (suggestion):
dispatcherProvider.Default should be used in this case I think because it's not really IO related work that is performed but CPU heavy work. However, the Dispatcher switch should happen within CclJsonFunctions.evaluateFunction() so that not all callers of this functions need to switch to the default dispatcher before.

Code after:
import de.rki.coronawarnapp.util.TimeAndDateExtensions.seconds
import de.rki.coronawarnapp.util.coroutine.DispatcherProvider
import de.rki.coronawarnapp.util.serialization.BaseGson
import de.rki.coronawarnapp.util.serialization.BaseJackson
import kotlinx.coroutines.withContext
import org.joda.time.DateTime
import javax.inject.Inject

class DccWalletInfoCalculation @Inject constructor(
    @BaseJackson private val mapper: ObjectMapper,
    @BaseGson private val gson: Gson,
    private val cclJsonFunctions: CCLJsonFunctions,
    private val dispatcherProvider: DispatcherProvider
) {

    private var boosterRulesNode: JsonNode = NullNode.instance

    fun init(boosterRules: List<DccValidationRule>) {
        boosterRulesNode = gson.toJson(boosterRules).toJsonNode()
    }

    @Suppress("BlockingMethodInNonBlockingContext")
    suspend fun getDccWalletInfo(
        dccList: List<CwaCovidCertificate>,
        dateTime: DateTime = DateTime.now()
    ): DccWalletInfo = withContext(dispatcherProvider.IO) {
        val output = cclJsonFunctions.evaluateFunction(
            FUNCTION_NAME,
            getDccWalletInfoInput(
                dccList = dccList,
                boosterNotificationRules = boosterRulesNode,
                defaultInputParameters = getDefaultInputParameters(dateTime)
            ).toJsonNode()
        )

        mapper.treeToValue(output, DccWalletInfo::class.java)
    }

    @VisibleForTesting
    internal fun getDccWalletInfoInput(
        dccList: List<CwaCovidCertificate>,
        boosterNotificationRules: JsonNode,
        defaultInputParameters: CclInputParameters,
    ) = DccWalletInfoInput(
        os = defaultInputParameters.os,
        language = defaultInputParameters.language,
        now = SystemTime(
            timestamp = defaultInputParameters.now.timestamp,
            localDate = defaultInputParameters.now.localDate,
            localDateTime = defaultInputParameters.now.localDateTime,
            localDateTimeMidnight = defaultInputParameters.now.localDateTimeMidnight,