diff --git a/ausweisapp/build.gradle b/ausweisapp/build.gradle index 1978e7b..231d3a3 100644 --- a/ausweisapp/build.gradle +++ b/ausweisapp/build.gradle @@ -1,4 +1,4 @@ configurations.maybeCreate("default") -artifacts.add("default", file('ausweisapp2.aar')) +artifacts.add("default", file('ausweisapp.aar')) group = 'com.governikus' version = ausweisapp_version diff --git a/build.gradle b/build.gradle index 53b2d52..05c335b 100644 --- a/build.gradle +++ b/build.gradle @@ -1,7 +1,7 @@ buildscript { ext.kotlin_version = '1.9.22' - ext.ausweisapp_version = '2.1.1' - ext.sdkwrapper_version = "$ausweisapp_version.0" + ext.ausweisapp_version = '2.2.0' + ext.sdkwrapper_version = "$ausweisapp_version" repositories { google() @@ -21,7 +21,7 @@ buildscript { } plugins { - id("org.sonarqube") version "4.4.1.3373" + id("org.sonarqube") version "5.0.0.4638" id("java") } diff --git a/sdkwrapper/build.gradle b/sdkwrapper/build.gradle index f65f30e..73bf215 100644 --- a/sdkwrapper/build.gradle +++ b/sdkwrapper/build.gradle @@ -11,7 +11,7 @@ android { defaultConfig { buildToolsVersion "34.0.0" - minSdkVersion 26 + minSdkVersion 28 targetSdkVersion 34 versionCode 4 versionName sdkwrapper_version @@ -137,7 +137,7 @@ afterEvaluate { } } -def useLocal = file("${rootDir}/ausweisapp/ausweisapp2.aar").exists(); +def useLocal = file("${rootDir}/ausweisapp/ausweisapp.aar").exists(); dependencies { if (useLocal) { diff --git a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowCallbacks.kt b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowCallbacks.kt index a18ca4e..4d48b89 100644 --- a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowCallbacks.kt +++ b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowCallbacks.kt @@ -87,6 +87,15 @@ interface WorkflowCallbacks { */ fun onInsertCard(error: String?) + /** + * Called if the SDK is waiting on a certain condition to be met. + * + * After resolving the cause of the issue, the workflow has to be resumed by calling [WorkflowController.continueWorkflow]. + * + * @param cause The cause for the waiting condition + */ + fun onPause(cause: Cause) + /** * A specific reader was recognized or has vanished. Also called as a response to [WorkflowController.getReader]. * @@ -178,19 +187,6 @@ interface WorkflowCallbacks { */ fun onStatus(workflowProgress: WorkflowProgress) - /** - * Provides information about the supported API level of the employed AusweisApp2 - * - * Response to a call to WorkflowController.getApiLevel() and WorkflowController.setApiLevel(). - * - * @param error Optional error message if WorkflowController.setApiLevel() failed. - * @param apiLevel Contains information about the supported and employed API level. - */ - fun onApiLevel( - error: String?, - apiLevel: ApiLevel?, - ) - /** * Provides information about the AusweisApp2 that is used in the SDK Wrapper. * diff --git a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowController.kt b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowController.kt index 3785ecc..ff3ea12 100644 --- a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowController.kt +++ b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowController.kt @@ -11,7 +11,6 @@ import android.nfc.tech.IsoDep import android.util.Log import de.governikus.ausweisapp2.sdkwrapper.SDKWrapper import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.getAccessRights -import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.getApiLevel import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.getAuthResult import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.getCertificateDescription import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.getReaderFromReaderMember @@ -22,8 +21,8 @@ import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.getWorkflowPro import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Accept import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Cancel import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Command +import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.ContinueWorkflow import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.GetAccessRights -import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.GetApiLevel import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.GetCertificate import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.GetInfo import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.GetReader @@ -31,7 +30,6 @@ import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.GetRe import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.GetStatus import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Message import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_ACCESS_RIGHTS -import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_API_LEVEL import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_AUTH import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_BAD_STATE import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_CERTIFICATE @@ -44,6 +42,7 @@ import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messa import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_INSERT_CARD import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_INTERNAL_ERROR import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_INVALID +import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_PAUSE import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_READER import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_READER_LIST import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messages.MSG_STATUS @@ -51,7 +50,6 @@ import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Messa import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.RunAuth import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.RunChangePin import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.SetAccessRights -import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.SetApiLevel import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.SetCan import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.SetCard import de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.SetNewPin @@ -236,30 +234,6 @@ class WorkflowController internal constructor(private val sdkConnection: SdkConn send(GetAccessRights()) } - /** - * Set supported API level of your application. - * - * If you initially develop your application against the SDK Wrapper you should check - * the highest supported level with getApiLevel() and set this value with this command - * when you connect to the SDK Wrapper. - * This will set the SDK Wrapper to act with the defined level even if a newer level is available. - * The SDK Wrapper will call [WorkflowCallbacks.onApiLevel] as an answer. - * - * @param level Supported API level of your app. - */ - fun setApiLevel(level: Int) { - send(SetApiLevel(level)) - } - - /** - * Returns information about the available and current API level. - * - * The SDK will call [WorkflowCallbacks.onApiLevel] as an answer. - */ - fun getApiLevel() { - send(GetApiLevel()) - } - /** * Provides information about the utilized AusweisApp2. * @@ -401,6 +375,13 @@ class WorkflowController internal constructor(private val sdkConnection: SdkConn send(Cancel()) } + /** + * Resumes the workflow after a callback to [WorkflowCallbacks.onPause]. + */ + fun continueWorkflow() { + send(ContinueWorkflow()) + } + /** * Request the certificate of current authentication. * @@ -480,9 +461,6 @@ class WorkflowController internal constructor(private val sdkConnection: SdkConn private fun handleMessage(message: Message) { when (message.msg) { - MSG_API_LEVEL -> { - callback { onApiLevel(message.error, message.getApiLevel()) } - } MSG_INFO -> { when (val info = message.getVersionInfo()) { null -> { @@ -584,6 +562,23 @@ class WorkflowController internal constructor(private val sdkConnection: SdkConn } } } + MSG_PAUSE -> { + val rawCause = message.cause + if (rawCause == null) { + val error = WrapperError(message.msg, "Missing cause object") + callback { onWrapperError(error) } + return + } + + val cause = Cause.fromRawName(rawCause) + if (cause == null) { + val error = WrapperError(message.msg, "Failed to map cause \"$rawCause\" to PauseReason") + callback { onWrapperError(error) } + return + } + + callback { onPause(cause) } + } MSG_READER -> { callback { onReader(message.getReaderFromRoot()) } } diff --git a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowData.kt b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowData.kt index 606c525..7c7f3ad 100644 --- a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowData.kt +++ b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowData.kt @@ -80,25 +80,46 @@ data class AuxiliaryData( /** * Provides information about inserted card. * + * An unknown card (without eID function) is represented by all properties set to null. + * * @property inoperative True if PUK is inoperative and cannot unblock PIN, otherwise false. This can be recognized if user enters a correct PUK only. It is not possible to read this data before a user tries to unblock the PIN. * @property deactivated True if eID functionality is deactivated, otherwise false. * @property pinRetryCounter Count of possible retries for the PIN. If you enter a PIN it will be decreased if PIN was incorrect. */ @Parcelize data class Card( - val deactivated: Boolean, - val inoperative: Boolean, - val pinRetryCounter: Int, + val deactivated: Boolean?, + val inoperative: Boolean?, + val pinRetryCounter: Int?, ) : Parcelable /** - * Optional definition of files for the Simulator reader. + * Convenience method to check if an unknown card (without eID function) was detected. + */ +fun Card.isUnknown(): Boolean = inoperative == null && deactivated == null && pinRetryCounter == null + +/** + * List of possible causes in [WorkflowCallbacks.onPause] + */ +enum class Cause(val rawName: String) { + BadCardPosition("BadCardPosition"), // Denotes an unstable or lost card connection. + ; + + companion object { + fun fromRawName(name: String?): Cause? = values().firstOrNull { it.rawName == name } + } +} + +/** + * Optional definition of files and keys for the Simulator reader. * * @property files List of Filesystem definitions. See [SimulatorFile]. + * @property keys List of SimulatorKey definitions. See [SimulatorKey]. */ @Parcelize data class Simulator( val files: List, + val keys: List?, ) : Parcelable /** @@ -122,15 +143,14 @@ data class SimulatorFile( ) : Parcelable /** - * Provides information about the API Level of the underlying AusweisApp2. + * Keys for Simulator reader * - * @property available List of all available API levels of the employed AusweisApp2. - * @property current The currently set API level. + * The keys are used to check the blacklist and calculate the pseudonym for the service provider. */ @Parcelize -data class ApiLevel( - val available: List?, - val current: Int, +data class SimulatorKey( + val id: Int, + val content: String, ) : Parcelable /** diff --git a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/MessageExtension.kt b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/MessageExtension.kt index 4b4bc17..87e967a 100644 --- a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/MessageExtension.kt +++ b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/MessageExtension.kt @@ -7,7 +7,6 @@ package de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2 import android.net.Uri import de.governikus.ausweisapp2.sdkwrapper.card.core.AccessRight import de.governikus.ausweisapp2.sdkwrapper.card.core.AccessRights -import de.governikus.ausweisapp2.sdkwrapper.card.core.ApiLevel import de.governikus.ausweisapp2.sdkwrapper.card.core.AuthResult import de.governikus.ausweisapp2.sdkwrapper.card.core.AuthResultData import de.governikus.ausweisapp2.sdkwrapper.card.core.AuxiliaryData @@ -58,15 +57,6 @@ internal fun Message.getCard(): Card? { ) } -internal fun Message.getApiLevel(): ApiLevel? { - val current = current ?: return null - - return ApiLevel( - available, - current, - ) -} - internal fun Message.getReaderFromRoot(): Reader? { val name = name ?: return null val insertable = insertable ?: return null diff --git a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/CommandData.kt b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/CommandData.kt index f9a006e..1ccfd5d 100644 --- a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/CommandData.kt +++ b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/CommandData.kt @@ -2,6 +2,7 @@ package de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol internal data class Simulator( val files: List, + val keys: List?, ) internal data class SimulatorFile( @@ -9,3 +10,8 @@ internal data class SimulatorFile( val shortFileId: String, val content: String, ) + +internal data class SimulatorKey( + val id: Int, + val content: String, +) diff --git a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/Commands.kt b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/Commands.kt index 344863a..4dfbc57 100644 --- a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/Commands.kt +++ b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/Commands.kt @@ -16,12 +16,8 @@ internal class Cancel : Command { override val cmd = "CANCEL" } -internal class SetApiLevel(val level: Int) : Command { - override val cmd = "SET_API_LEVEL" -} - -internal class GetApiLevel : Command { - override val cmd = "GET_API_LEVEL" +internal class ContinueWorkflow : Command { + override val cmd = "CONTINUE" } internal class GetCertificate : Command { diff --git a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/Messages.kt b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/Messages.kt index d0410da..a61add2 100644 --- a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/Messages.kt +++ b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/ausweisapp2/protocol/Messages.kt @@ -8,7 +8,6 @@ import com.google.gson.annotations.SerializedName internal object Messages { const val MSG_ACCESS_RIGHTS = "ACCESS_RIGHTS" - const val MSG_API_LEVEL = "API_LEVEL" const val MSG_AUTH = "AUTH" const val MSG_BAD_STATE = "BAD_STATE" const val MSG_CERTIFICATE = "CERTIFICATE" @@ -21,6 +20,7 @@ internal object Messages { const val MSG_INSERT_CARD = "INSERT_CARD" const val MSG_INTERNAL_ERROR = "INTERNAL_ERROR" const val MSG_INVALID = "INVALID" + const val MSG_PAUSE = "PAUSE" const val MSG_READER = "READER" const val MSG_READER_LIST = "READER_LIST" const val MSG_STATUS = "STATUS" @@ -30,10 +30,9 @@ internal object Messages { internal data class Message( val attached: Boolean?, val aux: Aux?, - val available: List?, val card: Card?, + val cause: String?, val chat: Chat?, - val current: Int?, val description: Description?, val error: String?, val insertable: Boolean?, @@ -83,9 +82,9 @@ internal data class Aux( ) internal data class Card( - val inoperative: Boolean, - val deactivated: Boolean, - val retryCounter: Int, + val inoperative: Boolean?, + val deactivated: Boolean?, + val retryCounter: Int?, ) internal data class Reader( diff --git a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/util/WorkflowDataToCommandDataConversion.kt b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/util/WorkflowDataToCommandDataConversion.kt index e29df74..1286cf7 100644 --- a/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/util/WorkflowDataToCommandDataConversion.kt +++ b/sdkwrapper/src/main/java/de/governikus/ausweisapp2/sdkwrapper/card/core/util/WorkflowDataToCommandDataConversion.kt @@ -2,14 +2,17 @@ package de.governikus.ausweisapp2.sdkwrapper.card.core.util internal typealias WorkflowSimulator = de.governikus.ausweisapp2.sdkwrapper.card.core.Simulator internal typealias WorkflowSimulatorFile = de.governikus.ausweisapp2.sdkwrapper.card.core.SimulatorFile +internal typealias WorkflowSimulatorKey = de.governikus.ausweisapp2.sdkwrapper.card.core.SimulatorKey internal typealias CommandSimulator = de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.Simulator internal typealias CommandSimulatorFile = de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.SimulatorFile +internal typealias CommandSimulatorKey = de.governikus.ausweisapp2.sdkwrapper.card.core.ausweisapp2.protocol.SimulatorKey internal fun workflowSimulatorToCommandSimulator(simulator: WorkflowSimulator?): CommandSimulator? { simulator ?: return null return CommandSimulator( simulator.files.map { workflowSimulatorFileToCommandSimulatorFile(it) }, + simulator.keys?.map { workflowSimulatorKeyToCommandSimulatorKey(it) }, ) } @@ -20,3 +23,10 @@ internal fun workflowSimulatorFileToCommandSimulatorFile(file: WorkflowSimulator file.content, ) } + +internal fun workflowSimulatorKeyToCommandSimulatorKey(key: WorkflowSimulatorKey): CommandSimulatorKey { + return CommandSimulatorKey( + key.id, + key.content, + ) +} diff --git a/sdkwrapper/src/test/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowControllerTest.kt b/sdkwrapper/src/test/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowControllerTest.kt index ab4b83b..5622bf7 100644 --- a/sdkwrapper/src/test/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowControllerTest.kt +++ b/sdkwrapper/src/test/java/de/governikus/ausweisapp2/sdkwrapper/card/core/WorkflowControllerTest.kt @@ -36,7 +36,7 @@ import kotlin.coroutines.suspendCoroutine import kotlin.time.Duration.Companion.milliseconds @RunWith(RobolectricTestRunner::class) -@Config(manifest = Config.NONE, sdk = [26]) +@Config(manifest = Config.NONE, sdk = [28]) @OptIn(kotlinx.coroutines.ExperimentalCoroutinesApi::class) class WorkflowControllerTest { private var workflowController: WorkflowController? = null @@ -388,14 +388,11 @@ internal open class TestWorkflowCallbacks : WorkflowCallbacks { override fun onStatus(workflowProgress: WorkflowProgress) {} - override fun onApiLevel( - error: String?, - apiLevel: ApiLevel?, - ) {} - override fun onInfo(versionInfo: VersionInfo) {} override fun onBadState(error: String) {} override fun onInternalError(error: String) {} + + override fun onPause(cause: Cause) {} } diff --git a/third_party_licenses/LICENSES.md b/third_party_licenses/LICENSES.md index 29c04e5..5541a6b 100644 --- a/third_party_licenses/LICENSES.md +++ b/third_party_licenses/LICENSES.md @@ -7,4 +7,4 @@ com.google.code.gson:gson:2.10.1 OPEN-SOURCE-LIZENZ FÜR DIE EUROPÄISCHE UNION - EUPL.md ====================================================== -com.governikus:ausweisapp:2.1.1 +com.governikus:ausweisapp:2.2.0