diff --git a/build.gradle b/build.gradle
index 9bf17ff..dbccb12 100644
--- a/build.gradle
+++ b/build.gradle
@@ -12,6 +12,8 @@ buildscript {
junit : '4.12',
mockito : '2.28.2',
rxjava : '2.2.12',
+ kotlin : '1.5.10',
+ coroutines: '1.5.0'
]
repositories {
@@ -20,8 +22,9 @@ buildscript {
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.6.2'
+ classpath 'com.android.tools.build:gradle:4.2.0'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.8.4'
+ classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.32'
}
}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 3a7bb1d..3da65bd 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip
diff --git a/ktx/.gitignore b/ktx/.gitignore
new file mode 100644
index 0000000..796b96d
--- /dev/null
+++ b/ktx/.gitignore
@@ -0,0 +1 @@
+/build
diff --git a/ktx/bintray.gradle b/ktx/bintray.gradle
new file mode 100644
index 0000000..bda7a89
--- /dev/null
+++ b/ktx/bintray.gradle
@@ -0,0 +1,51 @@
+apply plugin: 'maven-publish'
+apply plugin: 'com.jfrog.bintray'
+
+publishing {
+ publications {
+ Publication(MavenPublication) {
+ artifact("$buildDir/outputs/aar/ktx-release.aar")
+ groupId 'co.infinum'
+ artifact sourcesJar
+ artifact javadocsJar
+ artifactId 'goldfinger-ktx'
+ version versions.goldfinger
+
+ pom.withXml {
+ def root = asNode()
+ def dependenciesNode = root.appendNode('dependencies')
+
+ configurations.implementation.allDependencies.each {
+ def dependencyNode = dependenciesNode.appendNode('dependency')
+ if (it.name == 'core') {
+ dependencyNode.appendNode('groupId', 'co.infinum')
+ dependencyNode.appendNode('artifactId', 'goldfinger')
+ dependencyNode.appendNode('version', versions.goldfinger)
+ } else {
+ dependencyNode.appendNode('groupId', it.group)
+ dependencyNode.appendNode('artifactId', it.name)
+ dependencyNode.appendNode('version', it.version)
+ }
+ }
+ }
+ }
+ }
+}
+
+bintray {
+ user = System.getenv('BINTRAY_USER')
+ key = System.getenv('BINTRAY_API_KEY')
+ publish = false
+ publications = ['Publication']
+
+ pkg {
+ repo = 'android'
+ name = 'goldfinger-ktx'
+ userOrg = 'infinum'
+ publicDownloadNumbers = true
+
+ version {
+ name = versions.goldfinger
+ }
+ }
+}
\ No newline at end of file
diff --git a/ktx/build.gradle b/ktx/build.gradle
new file mode 100644
index 0000000..6c98fd3
--- /dev/null
+++ b/ktx/build.gradle
@@ -0,0 +1,24 @@
+apply plugin: 'com.android.library'
+
+android {
+ compileSdkVersion sdk.target
+
+ defaultConfig {
+ minSdkVersion sdk.min
+ targetSdkVersion sdk.target
+ versionName versions.goldfinger
+ }
+}
+
+dependencies {
+ implementation project(':core')
+ implementation "androidx.appcompat:appcompat:${versions.appcompat}"
+ implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:${versions.kotlin}"
+ implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:${versions.coroutines}"
+
+ testImplementation "junit:junit:${versions.junit}"
+ testImplementation "org.mockito:mockito-core:${versions.mockito}"
+}
+
+apply from: '../tasks.gradle'
+apply from: 'bintray.gradle'
\ No newline at end of file
diff --git a/ktx/src/main/AndroidManifest.xml b/ktx/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..c1ac4af
--- /dev/null
+++ b/ktx/src/main/AndroidManifest.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt
new file mode 100644
index 0000000..c4319ca
--- /dev/null
+++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtx.kt
@@ -0,0 +1,75 @@
+package co.infinum.goldfinger.ktx
+
+import android.content.Context
+import co.infinum.goldfinger.Goldfinger
+import co.infinum.goldfinger.Goldfinger.PromptParams
+import co.infinum.goldfinger.crypto.CipherCrypter
+import co.infinum.goldfinger.crypto.CipherFactory
+import co.infinum.goldfinger.crypto.MacCrypter
+import co.infinum.goldfinger.crypto.MacFactory
+import co.infinum.goldfinger.crypto.SignatureCrypter
+import co.infinum.goldfinger.crypto.SignatureFactory
+import kotlinx.coroutines.flow.Flow
+
+interface GoldfingerKtx {
+
+ fun hasFingerprintHardware(): Boolean
+
+ fun hasEnrolledFingerprint(): Boolean
+
+ fun canAuthenticate(): Boolean
+
+ fun authenticate(
+ params: PromptParams,
+ ): Flow
+
+ fun encrypt(
+ params: PromptParams,
+ key: String,
+ value: String,
+ ): Flow
+
+ fun decrypt(
+ params: PromptParams,
+ key: String,
+ value: String,
+ ): Flow
+
+ fun cancel()
+
+ class Builder(context: Context) {
+
+ private val baseBuilder: Goldfinger.Builder = Goldfinger.Builder(context)
+
+ fun build(): GoldfingerKtx =
+ GoldfingerKtxImpl(baseBuilder.build())
+
+ fun cipherCrypter(cipherCrypter: CipherCrypter?): Builder = apply {
+ baseBuilder.cipherCrypter(cipherCrypter)
+ }
+
+ fun cipherFactory(cipherFactory: CipherFactory?): Builder = apply {
+ baseBuilder.cipherFactory(cipherFactory)
+ }
+
+ fun logEnabled(logEnabled: Boolean): Builder = apply {
+ baseBuilder.logEnabled(logEnabled)
+ }
+
+ fun macCrypter(macCrypter: MacCrypter?): Builder = apply {
+ baseBuilder.macCrypter(macCrypter)
+ }
+
+ fun macFactory(macFactory: MacFactory?): Builder = apply {
+ baseBuilder.macFactory(macFactory)
+ }
+
+ fun signatureCrypter(signatureCrypter: SignatureCrypter?): Builder = apply {
+ baseBuilder.signatureCrypter(signatureCrypter)
+ }
+
+ fun signatureFactory(signatureFactory: SignatureFactory?): Builder = apply {
+ baseBuilder.signatureFactory(signatureFactory)
+ }
+ }
+}
diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt
new file mode 100644
index 0000000..588cdcd
--- /dev/null
+++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxCallback.kt
@@ -0,0 +1,28 @@
+package co.infinum.goldfinger.ktx
+
+import co.infinum.goldfinger.Goldfinger
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.channels.ProducerScope
+
+@ExperimentalCoroutinesApi
+class GoldfingerKtxCallback(
+ private val goldfinger: Goldfinger,
+ private val producerScope: ProducerScope,
+) : Goldfinger.Callback {
+ override fun onResult(result: Goldfinger.Result) {
+ with(producerScope) {
+ if (!isClosedForSend) {
+ channel.trySend(result)
+ if (result.type() == Goldfinger.Type.SUCCESS || result.type() == Goldfinger.Type.ERROR) {
+ channel.close()
+ }
+ } else {
+ goldfinger.cancel()
+ }
+ }
+ }
+
+ override fun onError(e: Exception) {
+ producerScope.channel.close(e)
+ }
+}
\ No newline at end of file
diff --git a/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt
new file mode 100644
index 0000000..87ac49d
--- /dev/null
+++ b/ktx/src/main/java/co/infinum/goldfinger/ktx/GoldfingerKtxImpl.kt
@@ -0,0 +1,73 @@
+package co.infinum.goldfinger.ktx
+
+import co.infinum.goldfinger.Goldfinger
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.buffer
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.cancellable
+
+@ExperimentalCoroutinesApi
+class GoldfingerKtxImpl(private val goldfinger: Goldfinger) : GoldfingerKtx {
+
+ private fun inGoldfingerFlow(doWithCallback: (GoldfingerKtxCallback) -> Unit) =
+ callbackFlow {
+ doWithCallback(
+ GoldfingerKtxCallback(
+ goldfinger,
+ this,
+ )
+ )
+ awaitClose { goldfinger.cancel() }
+ }
+ .buffer(
+ capacity = 1,
+ onBufferOverflow = BufferOverflow.DROP_OLDEST,
+ )
+ .cancellable()
+
+ override fun hasFingerprintHardware(): Boolean = goldfinger.hasFingerprintHardware()
+
+ override fun hasEnrolledFingerprint(): Boolean = goldfinger.hasEnrolledFingerprint()
+
+ override fun canAuthenticate(): Boolean = goldfinger.canAuthenticate()
+
+ override fun authenticate(params: Goldfinger.PromptParams): Flow = inGoldfingerFlow { callback ->
+ goldfinger.authenticate(
+ params,
+ callback,
+ )
+ }
+
+ override fun encrypt(
+ params: Goldfinger.PromptParams,
+ key: String,
+ value: String,
+ ): Flow = inGoldfingerFlow { callback ->
+ goldfinger.encrypt(
+ params,
+ key,
+ value,
+ callback,
+ )
+ }
+
+ override fun decrypt(
+ params: Goldfinger.PromptParams,
+ key: String,
+ value: String,
+ ): Flow = inGoldfingerFlow { callback ->
+ goldfinger.decrypt(
+ params,
+ key,
+ value,
+ callback,
+ )
+ }
+
+ override fun cancel() {
+ goldfinger.cancel()
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index e741f1f..e6db287 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':core', ':example', ':rx'
+include ':core', ':example', ':rx', ':ktx'