From cb1a7b3d0fd38db1882d74aa8b0dc63ff0a8530b Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Thu, 20 Mar 2025 11:21:53 +0200 Subject: [PATCH 1/6] Remove ambiguity in AuxData contents by using IntArray directly --- .../biometrics/polyprotect/ArrayConverter.kt | 25 ++----------------- .../biometrics/polyprotect/AuxData.kt | 4 +-- .../biometrics/polyprotect/PolyProtect.kt | 19 +++++++------- .../polyprotect/PolyProtectUnitTest.kt | 24 +++++++++++------- 4 files changed, 28 insertions(+), 44 deletions(-) diff --git a/src/main/kotlin/com/simprints/biometrics/polyprotect/ArrayConverter.kt b/src/main/kotlin/com/simprints/biometrics/polyprotect/ArrayConverter.kt index e1a9dd7..ea8b2be 100644 --- a/src/main/kotlin/com/simprints/biometrics/polyprotect/ArrayConverter.kt +++ b/src/main/kotlin/com/simprints/biometrics/polyprotect/ArrayConverter.kt @@ -1,3 +1,5 @@ +package com.simprints.biometrics.polyprotect + import java.nio.ByteBuffer import java.nio.ByteOrder @@ -26,27 +28,4 @@ object ArrayConverter { return DoubleArray(doubleBuffer.remaining()).apply { doubleBuffer.get(this) } } - /** - * Converts an IntArray to a ByteArray. - * - * @param intArray The IntArray to convert. - * @return A ByteArray representing the IntArray. - */ - fun intArrayToByteArray(intArray: IntArray): ByteArray { - val byteBuffer = ByteBuffer.allocate(intArray.size * 4).order(ByteOrder.nativeOrder()) - byteBuffer.asIntBuffer().put(intArray) - return byteBuffer.array() - } - - /** - * Converts a ByteArray back to an IntArray. - * - * @param byteArray The ByteArray to convert. - * @return An IntArray reconstructed from the ByteArray. - */ - fun byteArrayToIntArray(byteArray: ByteArray): IntArray { - val byteBuffer = ByteBuffer.wrap(byteArray).order(ByteOrder.nativeOrder()) - val intBuffer = byteBuffer.asIntBuffer() - return IntArray(intBuffer.remaining()).apply { intBuffer.get(this) } - } } diff --git a/src/main/kotlin/com/simprints/biometrics/polyprotect/AuxData.kt b/src/main/kotlin/com/simprints/biometrics/polyprotect/AuxData.kt index 9ddbba3..11138a1 100644 --- a/src/main/kotlin/com/simprints/biometrics/polyprotect/AuxData.kt +++ b/src/main/kotlin/com/simprints/biometrics/polyprotect/AuxData.kt @@ -8,6 +8,6 @@ package com.simprints.biometrics.polyprotect * @param exponents of a polynomial function */ data class AuxData( - val coefficients: ByteArray, - val exponents: ByteArray, + val coefficients: IntArray, + val exponents: IntArray, ) diff --git a/src/main/kotlin/com/simprints/biometrics/polyprotect/PolyProtect.kt b/src/main/kotlin/com/simprints/biometrics/polyprotect/PolyProtect.kt index 3d4f52f..d62e690 100644 --- a/src/main/kotlin/com/simprints/biometrics/polyprotect/PolyProtect.kt +++ b/src/main/kotlin/com/simprints/biometrics/polyprotect/PolyProtect.kt @@ -48,30 +48,29 @@ class PolyProtect( ): ByteArray { val (coefficients, exponents) = auxData // For convenience require(exponents.size == coefficients.size) { "Auxiliary data sizes must be equal." } - require(ArrayConverter.byteArrayToIntArray(exponents).size == polynomialDegree) { + require(exponents.size == polynomialDegree) { "Auxiliary data sizes must be equal to polynomial degree." } // Converting from ByteArray - val unprotectedTemplateDoubleArray = ArrayConverter.byteArrayToDoubleArray(unprotectedTemplate) - val coefficientsIntArray = ArrayConverter.byteArrayToIntArray(coefficients) - val exponentsIntArray = ArrayConverter.byteArrayToIntArray(exponents) + val unprotectedTemplateDoubleArray = + ArrayConverter.byteArrayToDoubleArray(unprotectedTemplate) - val stepSize = exponentsIntArray.size - overlap + val stepSize = exponents.size - overlap val protectedTemplate = mutableListOf() for (templateIndex in 0..(unprotectedTemplateDoubleArray.lastIndex - overlap) step stepSize) { - val s = exponentsIntArray.indices.map { i -> + val s = exponents.indices.sumOf { i -> // If the target element is out of bounds, consider it 0 since 0^n==0 // This would be the same as padding the provided array up to certain size if (templateIndex + i > unprotectedTemplateDoubleArray.lastIndex) { 0.0 } else { unprotectedTemplateDoubleArray[templateIndex + i] - .pow(exponentsIntArray[i]) - .times(coefficientsIntArray[i]) + .pow(exponents[i]) + .times(coefficients[i]) } - }.sum() + } protectedTemplate.add(s) } return ArrayConverter.doubleArrayToByteArray(protectedTemplate.toDoubleArray()) @@ -95,7 +94,7 @@ class PolyProtect( // Shuffle the list randomly val exponents = exponentRange.shuffled().toIntArray() - return AuxData(ArrayConverter.intArrayToByteArray(coefficients), ArrayConverter.intArrayToByteArray(exponents)) + return AuxData(coefficients, exponents) } companion object { diff --git a/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectUnitTest.kt b/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectUnitTest.kt index 90aba73..ba160ca 100644 --- a/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectUnitTest.kt +++ b/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectUnitTest.kt @@ -21,20 +21,24 @@ class PolyProtectUnitTest { val secrets1 = polyProtect.generateAuxData() assertEquals( - "Exponents count is same as provided polynomial degree", 7, ArrayConverter.byteArrayToIntArray(secrets1.exponents).size + "Exponents count is same as provided polynomial degree", 7, secrets1.exponents.size ) assertTrue( "The exponents should include values from 1 to PolyProtect.POLYNOMIALDEGREE.", - ArrayConverter.byteArrayToIntArray(secrets1.exponents).sortedArray().contentEquals(IntArray(7) { it + 1 }) + secrets1.exponents.sortedArray().contentEquals(IntArray(7) { it + 1 }) ) assertEquals( - "Coefficient count is same as provided polynomial degree", 7, ArrayConverter.byteArrayToIntArray(secrets1.coefficients).size + "Coefficient count is same as provided polynomial degree", 7, secrets1.coefficients.size + ) + assertTrue( + "The coefficient values should not be outside the allowed range", + secrets1.coefficients.all { it in -100..100 } + ) + assertTrue( + "The coefficient values must not be 0", + secrets1.coefficients.none { it == 0 } ) - assertTrue("The coefficient values should not be outside the allowed range", - ArrayConverter.byteArrayToIntArray(secrets1.coefficients).all { it in -100..100 }) - assertTrue("The coefficient values must not be 0", ArrayConverter.byteArrayToIntArray(secrets1.coefficients).none { it == 0 }) - } @Test @@ -45,7 +49,8 @@ class PolyProtectUnitTest { val exponents = intArrayOf(1, 5, 3, 4, 6, 2, 7) val subjectSecretAuxData = AuxData( - coefficients = ArrayConverter.intArrayToByteArray(coefficients), exponents = ArrayConverter.intArrayToByteArray(exponents) + coefficients = coefficients, + exponents = exponents, ) // Custom parameters (relevant to the generation of secret auxiliary data record) @@ -59,7 +64,8 @@ class PolyProtectUnitTest { val unprotectedTemplateDoubleArray = DoubleArray(512) { Random.nextDouble() - 0.5 } // Transformation of unprotected template into ByteArray - val unprotectedTemplate = ArrayConverter.doubleArrayToByteArray(unprotectedTemplateDoubleArray) + val unprotectedTemplate = + ArrayConverter.doubleArrayToByteArray(unprotectedTemplateDoubleArray) // PolyProtect transformation: the unprotected templates are transformed using the // subject-specific secret auxiliary data From b491195445fc33ac46857d0d6a129505a30f3756 Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Thu, 20 Mar 2025 11:54:44 +0200 Subject: [PATCH 2/6] Make it explicit that byte stream of float array is expected --- .../biometrics/polyprotect/ArrayConverter.kt | 27 ++++++++++--------- .../biometrics/polyprotect/PolyProtect.kt | 12 ++++----- .../biometrics/polyprotect/SimilarityScore.kt | 14 +++++----- .../polyprotect/ComputeSimilarityScoreTest.kt | 8 +++--- .../polyprotect/PolyProtectUnitTest.kt | 4 +-- 5 files changed, 33 insertions(+), 32 deletions(-) diff --git a/src/main/kotlin/com/simprints/biometrics/polyprotect/ArrayConverter.kt b/src/main/kotlin/com/simprints/biometrics/polyprotect/ArrayConverter.kt index ea8b2be..17a4c50 100644 --- a/src/main/kotlin/com/simprints/biometrics/polyprotect/ArrayConverter.kt +++ b/src/main/kotlin/com/simprints/biometrics/polyprotect/ArrayConverter.kt @@ -3,29 +3,30 @@ package com.simprints.biometrics.polyprotect import java.nio.ByteBuffer import java.nio.ByteOrder -object ArrayConverter { +internal object ArrayConverter { /** - * Converts a DoubleArray to a ByteArray. + * Converts a FloatArray to a ByteArray. * - * @param doubleArray The DoubleArray to convert. - * @return A ByteArray representing the DoubleArray. + * @param floatArray The float array to convert. + * @return A byte stream representing the contents of float array. */ - fun doubleArrayToByteArray(doubleArray: DoubleArray): ByteArray { - val byteBuffer = ByteBuffer.allocate(doubleArray.size * 8).order(ByteOrder.nativeOrder()) - byteBuffer.asDoubleBuffer().put(doubleArray) + internal fun floatArrayToByteArray(floatArray: FloatArray): ByteArray { + val byteBuffer = + ByteBuffer.allocate(floatArray.size * Float.SIZE_BYTES).order(ByteOrder.nativeOrder()) + byteBuffer.asFloatBuffer().put(floatArray) return byteBuffer.array() } /** - * Converts a ByteArray back to a DoubleArray. + * Converts a ByteArray back to a FloatArray. * - * @param byteArray The ByteArray to convert. - * @return A DoubleArray reconstructed from the ByteArray. + * @param byteArray The byte stream representation of float array + * @return A float array reconstructed from the byte stream. */ - fun byteArrayToDoubleArray(byteArray: ByteArray): DoubleArray { + internal fun byteArrayToFloatArray(byteArray: ByteArray): FloatArray { val byteBuffer = ByteBuffer.wrap(byteArray).order(ByteOrder.nativeOrder()) - val doubleBuffer = byteBuffer.asDoubleBuffer() - return DoubleArray(doubleBuffer.remaining()).apply { doubleBuffer.get(this) } + val floatBuffer = byteBuffer.asFloatBuffer() + return FloatArray(floatBuffer.remaining()).apply { floatBuffer.get(this) } } } diff --git a/src/main/kotlin/com/simprints/biometrics/polyprotect/PolyProtect.kt b/src/main/kotlin/com/simprints/biometrics/polyprotect/PolyProtect.kt index d62e690..9569c02 100644 --- a/src/main/kotlin/com/simprints/biometrics/polyprotect/PolyProtect.kt +++ b/src/main/kotlin/com/simprints/biometrics/polyprotect/PolyProtect.kt @@ -37,7 +37,7 @@ class PolyProtect( * * **NOTE**: The size of the protected templates depends on `polynomialDegree` and `overlap`. * - * @param unprotectedTemplateByteArray + * @param unprotectedTemplate byte stream representation of template's array of FLOAT32 values * @param auxData a set of coefficients and exponents associated with specific biometric record * * @return protected template @@ -52,13 +52,13 @@ class PolyProtect( "Auxiliary data sizes must be equal to polynomial degree." } - // Converting from ByteArray + // Converting from ByteArray to Floats (as per template spec) and to doubles for more precision during calculations val unprotectedTemplateDoubleArray = - ArrayConverter.byteArrayToDoubleArray(unprotectedTemplate) + ArrayConverter.byteArrayToFloatArray(unprotectedTemplate).map { it.toDouble() } val stepSize = exponents.size - overlap - val protectedTemplate = mutableListOf() + val protectedTemplate = mutableListOf() for (templateIndex in 0..(unprotectedTemplateDoubleArray.lastIndex - overlap) step stepSize) { val s = exponents.indices.sumOf { i -> // If the target element is out of bounds, consider it 0 since 0^n==0 @@ -71,9 +71,9 @@ class PolyProtect( .times(coefficients[i]) } } - protectedTemplate.add(s) + protectedTemplate.add(s.toFloat()) // We can lose some precision now } - return ArrayConverter.doubleArrayToByteArray(protectedTemplate.toDoubleArray()) + return ArrayConverter.floatArrayToByteArray(protectedTemplate.toFloatArray()) } /** diff --git a/src/main/kotlin/com/simprints/biometrics/polyprotect/SimilarityScore.kt b/src/main/kotlin/com/simprints/biometrics/polyprotect/SimilarityScore.kt index bf7b10d..9e65db6 100644 --- a/src/main/kotlin/com/simprints/biometrics/polyprotect/SimilarityScore.kt +++ b/src/main/kotlin/com/simprints/biometrics/polyprotect/SimilarityScore.kt @@ -5,19 +5,19 @@ import kotlin.math.sqrt /** * Calculates a similarity score based on cosine distance. * - * @param array1 first biometric template - * @param array2 another biometric template + * @param template1 byte stream representation of the first template's array of FLOAT32 values + * @param template2 byte stream representation of the second template's array of FLOAT32 values * * @return a value in in the `[0,1]` range */ fun computeSimilarityScore( - array1ByteArray: ByteArray, - array2ByteArray: ByteArray, + template1: ByteArray, + template2: ByteArray, ): Double { - require(array1ByteArray.size == array2ByteArray.size) { "Arrays must be of the same size." } + require(template1.size == template2.size) { "Arrays must be of the same size." } - val array1 = ArrayConverter.byteArrayToDoubleArray(array1ByteArray) - val array2 = ArrayConverter.byteArrayToDoubleArray(array2ByteArray) + val array1 = ArrayConverter.byteArrayToFloatArray(template1) + val array2 = ArrayConverter.byteArrayToFloatArray(template2) // Calculate the dot product of array1 and array2 val dotProduct = array1.zip(array2) { x, y -> x * y }.sum() diff --git a/src/test/java/com/simprints/biometrics/polyprotect/ComputeSimilarityScoreTest.kt b/src/test/java/com/simprints/biometrics/polyprotect/ComputeSimilarityScoreTest.kt index 02ce4cc..b24196c 100644 --- a/src/test/java/com/simprints/biometrics/polyprotect/ComputeSimilarityScoreTest.kt +++ b/src/test/java/com/simprints/biometrics/polyprotect/ComputeSimilarityScoreTest.kt @@ -10,11 +10,11 @@ class ComputeSimilarityScoreTest { @Test fun `similarity between two protected templates should be between 0 and 1`() { // Creation of two unprotected templates (randomly generated) - val unprotectedTemplateDoubleArray1 = DoubleArray(512) { Random.nextDouble() - 0.5 } - val unprotectedTemplateDoubleArray2 = DoubleArray(512) { Random.nextDouble() - 0.5 } + val unprotectedTemplateArray1 = FloatArray(512) { Random.nextFloat() - 0.5f } + val unprotectedTemplateArray2 = FloatArray(512) { Random.nextFloat() - 0.5f } - val unprotectedTemplate1 = ArrayConverter.doubleArrayToByteArray(unprotectedTemplateDoubleArray1) - val unprotectedTemplate2 = ArrayConverter.doubleArrayToByteArray(unprotectedTemplateDoubleArray2) + val unprotectedTemplate1 = ArrayConverter.floatArrayToByteArray(unprotectedTemplateArray1) + val unprotectedTemplate2 = ArrayConverter.floatArrayToByteArray(unprotectedTemplateArray2) // Custom parameters diff --git a/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectUnitTest.kt b/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectUnitTest.kt index ba160ca..152ce2c 100644 --- a/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectUnitTest.kt +++ b/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectUnitTest.kt @@ -61,11 +61,11 @@ class PolyProtectUnitTest { ) // Creation of two unprotected templates (randomly generated) - val unprotectedTemplateDoubleArray = DoubleArray(512) { Random.nextDouble() - 0.5 } + val unprotectedTemplateDoubleArray = FloatArray(512) { Random.nextFloat() - 0.5f } // Transformation of unprotected template into ByteArray val unprotectedTemplate = - ArrayConverter.doubleArrayToByteArray(unprotectedTemplateDoubleArray) + ArrayConverter.floatArrayToByteArray(unprotectedTemplateDoubleArray) // PolyProtect transformation: the unprotected templates are transformed using the // subject-specific secret auxiliary data From d799f66bf8a05bca726fc5613f3c69ee5d613f84 Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Thu, 20 Mar 2025 11:57:00 +0200 Subject: [PATCH 3/6] Add test for calculation correctness based on known correct calculations --- ...PolyProtectTemplateEncoderParameterTest.kt | 174 ++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100644 src/test/java/com/simprints/biometrics/polyprotect/PolyProtectTemplateEncoderParameterTest.kt diff --git a/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectTemplateEncoderParameterTest.kt b/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectTemplateEncoderParameterTest.kt new file mode 100644 index 0000000..e09614c --- /dev/null +++ b/src/test/java/com/simprints/biometrics/polyprotect/PolyProtectTemplateEncoderParameterTest.kt @@ -0,0 +1,174 @@ +package com.simprints.biometrics.polyprotect + +import junit.framework.TestCase.assertEquals +import org.junit.Assert.assertTrue +import org.junit.Test +import org.junit.runner.RunWith +import org.junit.runners.Parameterized +import org.junit.runners.Parameterized.Parameters +import kotlin.math.abs + +@RunWith(Parameterized::class) +class PolyProtectTemplateEncoderParameterTest( + private val given: Pair, AuxData>, + private val expected: List +) { + + private val subject = PolyProtect( + polynomialDegree = 5, + coefficientAbsMax = 100, + overlap = 2, + ) + + @Test + fun `encode template works correctly`() { + val (template, aux) = given + val encoded = subject.transformTemplate( + ArrayConverter.floatArrayToByteArray(template.toFloatArray()), + aux + ) + .let { ArrayConverter.byteArrayToFloatArray(it) } // Converting to compare actual float values + + println("expected: $expected") + println("actual: ${encoded.joinToString(", ", prefix = "[", postfix = "]") { it.toString() }} ") + + assertEquals(expected.size, encoded.size) + assertTrue( + expected.toFloatArray() + .zip(encoded) { e, a -> abs(e - a) < PRECISION } + .all { it } + ) + } + + companion object { + private const val PRECISION = 1e-5f + + @JvmStatic + @Parameters + fun data(): Collection> = listOf( + // Full template with overlap 2 and no padding + arrayOf( + // Given + listOf( + 0.1331335545f, + 0.4449820169f, + -0.2204751117f, + 0.02803098769f, + 0.0488200593f, + 0.1831083583f, + -0.007320145106f, + 0.3660261928f, + -0.3799865143f, + 0.2509288685f, + -0.1363977355f, + 0.4834820974f, + 0.4518768993f, + 0.3874402622f, + 0.002547916374f, + 0.1281368887f, + -0.2143639432f, + -0.4538202661f, + 0.0495447296f, + -0.2834924903f, + 0.2892785979f, + 0.3398633496f, + -0.09878652073f, + ) to AuxData( + exponents = intArrayOf(1, 2, 3, 4, 5), + coefficients = intArrayOf(10, 20, 30, 40, 50), + ), + // Expected + listOf( + 4.970039955f, + 0.8406559131f, + 1.116541916f, + 8.376161797f, + 7.509119748f, + -0.6948732895f, + 3.362235598f, + ) + ), + // This template needs to be padded + arrayOf( + // Given + listOf( + 0.1331335545f, + 0.4449820169f, + -0.2204751117f, + 0.02803098769f, + 0.0488200593f, + 0.1831083583f, + -0.007320145106f, + 0.3660261928f, + -0.3799865143f, + 0.2509288685f, + -0.1363977355f, + 0.4834820974f, + 0.4518768993f, + 0.3874402622f, + 0.002547916374f, + 0.1281368887f, + -0.2143639432f, + -0.4538202661f, + 0.0495447296f, + -0.2834924903f, + 0.2892785979f, + ) to AuxData( + exponents = intArrayOf(1, 2, 3, 4, 5), + coefficients = intArrayOf(10, 20, 30, 40, 50), + ), + // Expected + listOf( + 4.970039955f, + 0.8406559131f, + 1.116541916f, + 8.376161797f, + 7.509119748f, + -0.6948732895f, + 2.829030416f, + ) + ), + // Template with some padding and randomised C and E values + arrayOf( + // Given + listOf( + 0.4952767838f, + 0.04582746275f, + 0.4912871269f, + -0.05188964656f, + 0.1710497578f, + 0.4828839484f, + 0.4789628756f, + -0.1757431758f, + -0.1946878787f, + -0.1893160354f, + -0.2281576101f, + -0.3595243313f, + 0.144228172f, + -0.4046463718f, + 0.08317913623f, + -0.4290612621f, + -0.03695776633f, + -0.1710147956f, + -0.2621668255f, + -0.00713160069f, + 0.2892785979f, + 0.4425149409f, + ) to AuxData( + exponents = intArrayOf(3, 5, 1, 2, 4), + coefficients = intArrayOf(35, -83, -27, 79, 12), + ), + // Expected + listOf( + -8.789603428f, + 5.079566739f, + 11.98009351f, + 11.48605497f, + 13.30302774f, + 7.28262971f, + 7.02854756f, + ) + ), + ) + } +} From 2fe2bd9713f598e2227b84f7477fdc79dbf0dea6 Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Thu, 20 Mar 2025 12:20:42 +0200 Subject: [PATCH 4/6] Adjust version numbers to be in line with SID --- build.gradle.kts | 12 ++++++------ gradle/libs.versions.toml | 16 +++------------- gradle/wrapper/gradle-wrapper.properties | 4 ++-- 3 files changed, 11 insertions(+), 21 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 8a9af89..9564e6a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -10,21 +10,21 @@ val projectVersion = "2024.4.2" android { namespace = "$projectGroupId.$projectArtifactId" - compileSdk = 34 + compileSdk = 35 defaultConfig { - minSdk = 24 + minSdk = 23 } compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 } kotlinOptions { - jvmTarget = "1.8" + jvmTarget = "17" } } dependencies { - testImplementation(libs.junit) + testImplementation(libs.testing.junit) } publishing { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4bc77e2..bb0ea3a 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,20 +1,10 @@ [versions] -agp = "8.6.1" -kotlin = "1.9.0" -coreKtx = "1.13.1" +agp = "8.9.0" +kotlin = "2.0.20" junit = "4.13.2" -junitVersion = "1.2.1" -espressoCore = "3.6.1" -appcompat = "1.7.0" -material = "1.12.0" [libraries] -androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" } -junit = { group = "junit", name = "junit", version.ref = "junit" } -androidx-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" } -androidx-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } -androidx-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" } -material = { group = "com.google.android.material", name = "material", version.ref = "material" } +testing-junit = { group = "junit", name = "junit", version.ref = "junit" } [plugins] diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 4aeadec..e2cf2ed 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Thu Oct 17 16:27:57 CEST 2024 +#Thu Mar 20 12:18:10 EET 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists From 0f1fb056998f5e035e0e419e8c63e3e037172d0f Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Thu, 20 Mar 2025 12:21:01 +0200 Subject: [PATCH 5/6] Bump library version --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 9564e6a..3386400 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { val projectGroupId = "com.simprints.biometrics" val projectArtifactId = "polyprotect" -val projectVersion = "2024.4.2" +val projectVersion = "2025.1.1" android { namespace = "$projectGroupId.$projectArtifactId" From f0b64d57a7d7e66c07a220dd606a7ee43d31b28f Mon Sep 17 00:00:00 2001 From: Sergejs Luhmirins Date: Thu, 20 Mar 2025 12:27:26 +0200 Subject: [PATCH 6/6] Fix GH action cache issue --- .github/workflows/ci.yml | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a7734a3..79f4b83 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,14 +14,15 @@ jobs: steps: - uses: actions/checkout@v2 - - name: Cache + - name: Restore gradle global directory + uses: actions/cache/restore@v4 id: cache - uses: actions/cache@v1 with: - path: ~/.gradle/caches - key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*') }} - restore-keys: | - ${{ runner.os }}-gradle- + path: | + ~/.gradle/ + .gradle/ + key: global-gradle- + restore-keys: global-gradle- - name: set up JDK 17 uses: actions/setup-java@v2