diff --git a/.github/publish/publish-mavencentral.gradle b/.github/publish/publish-mavencentral.gradle index 8b5d12f..76e610d 100644 --- a/.github/publish/publish-mavencentral.gradle +++ b/.github/publish/publish-mavencentral.gradle @@ -36,10 +36,11 @@ afterEvaluate { groupId publishedGroupId artifactId artifact version libraryVersion + if (project.plugins.findPlugin("com.android.library")) { - from components.release + from(components.findByName("release")) } else { - from components.java + from(components.java) } artifact androidSourcesJar diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a598e9d..a7734a3 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,11 +23,11 @@ jobs: restore-keys: | ${{ runner.os }}-gradle- - - name: set up JDK 11 + - name: set up JDK 17 uses: actions/setup-java@v2 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - name: Build with Gradle run: ./gradlew build diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml deleted file mode 100644 index 1691409..0000000 --- a/.github/workflows/codeql-analysis.yml +++ /dev/null @@ -1,71 +0,0 @@ -# For most projects, this workflow file will not need changing; you simply need -# to commit it to your repository. -# -# You may wish to alter this file to override the set of languages analyzed, -# or to provide custom queries or build logic. -# -# ******** NOTE ******** -# We have attempted to detect the languages in your repository. Please check -# the `language` matrix defined below to confirm you have the correct set of -# supported CodeQL languages. -# -name: "CodeQL" - -on: - push: - branches: [ main ] - pull_request: - # The branches below must be a subset of the branches above - branches: [ main ] - schedule: - - cron: '37 2 * * 3' - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - - strategy: - fail-fast: false - matrix: - language: [ 'java' ] - # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] - # Learn more: - # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed - - steps: - - name: Checkout repository - uses: actions/checkout@v2 - - # Initializes the CodeQL tools for scanning. - - name: Initialize CodeQL - uses: github/codeql-action/init@v1 - with: - languages: ${{ matrix.language }} - # If you wish to specify custom queries, you can do so here or in a config file. - # By default, queries listed here will override any specified in a config file. - # Prefix the list here with "+" to use these queries and those in the config file. - # queries: ./path/to/local/query, your-org/your-repo/queries@main - - # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). - # If this step fails, then you should remove it and run the build manually (see below) - - name: Autobuild - uses: github/codeql-action/autobuild@v1 - - # â„šī¸ Command-line programs to run using the OS shell. - # 📚 https://git.io/JvXDl - - # âœī¸ If the Autobuild fails above, remove it and uncomment the following three lines - # and modify them (or add more) to build your code if your project - # uses a compiled language - - #- run: | - # make bootstrap - # make release - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@v1 diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f99b1d5..5c14f91 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -12,11 +12,11 @@ jobs: steps: - uses: actions/checkout@v2 - - name: set up JDK 11 + - name: set up JDK 17 uses: actions/setup-java@v2 with: distribution: 'temurin' - java-version: '11' + java-version: '17' - name: Build run: ./gradlew build diff --git a/README.md b/README.md index 927834e..294da64 100644 --- a/README.md +++ b/README.md @@ -5,22 +5,10 @@ *LibSimprints is the library used to pass data to and from the Simprints ID application.* -**Installation from maven** +**Installation** -Gradle ``` -implementation 'com.simprints:libsimprints:2023.4.1' +implementation 'com.simprints:libsimprints:2024.8.1' ``` -Maven -``` - - com.simprints - libsimprints - 2023.4.1 - pom - -``` - -**Documentation** -https://sites.google.com/simprints.com/simprints-for-developers/integrating-w-simprints/getting-started +[Documentation](https://simprints.gitbook.io/docs/development/simprints-for-developers/integrating-with-simprints) diff --git a/build.gradle b/build.gradle index 37f5b57..cd3a9ed 100644 --- a/build.gradle +++ b/build.gradle @@ -5,30 +5,50 @@ buildscript { maven { url "https://plugins.gradle.org/m2/" } } dependencies { - classpath "com.android.tools.build:gradle:7.4.0" - classpath "io.github.gradle-nexus:publish-plugin:1.3.0" + classpath "com.android.tools.build:gradle:8.5.2" + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:2.0.0" + classpath "io.github.gradle-nexus:publish-plugin:2.0.0" } } apply plugin: "com.android.library" +apply plugin: "org.jetbrains.kotlin.android" +apply plugin: "kotlin-parcelize" repositories { + google() mavenCentral() } -project.version = "2024.2.2" +project.version = "2024.8.1" android { - compileSdkVersion 33 - buildToolsVersion "30.0.3" + namespace = "com.simprints.libsimprints" + compileSdk = 35 defaultConfig { - minSdkVersion 19 - targetSdkVersion 33 - versionCode 1 + minSdkVersion 23 + targetSdkVersion 35 + + versionCode 2 versionName project.version + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_17 + targetCompatibility = JavaVersion.VERSION_17 + } + + kotlinOptions { + jvmTarget = JavaVersion.VERSION_17.toString() + } + + buildFeatures { + buildConfig true + } + buildTypes { debug { minifyEnabled false @@ -52,16 +72,13 @@ android { } } -repositories { - mavenCentral() - google() -} - dependencies { - annotationProcessor "com.google.auto.value:auto-value:1.10.4" - api "androidx.annotation:annotation:1.7.1" - androidTestImplementation "junit:junit:4.13.2" - androidTestImplementation "androidx.test.ext:junit:1.1.5" + implementation "org.jetbrains.kotlin:kotlin-stdlib:2.0.0" + + testImplementation "junit:junit:4.13.2" + testImplementation "androidx.test.ext:junit:1.2.1" + testImplementation "androidx.test:core:1.6.1" + testImplementation "org.robolectric:robolectric:4.13" } apply plugin: "io.github.gradle-nexus.publish-plugin" diff --git a/gradle.properties b/gradle.properties index 646c51b..5bac8ac 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,2 +1 @@ android.useAndroidX=true -android.enableJetifier=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 388c646..bfe6bc5 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Jan 24 14:55:27 CET 2023 +#Thu Aug 15 11:50:19 EEST 2024 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-all.zip distributionPath=wrapper/dists -zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists diff --git a/src/main/java/com/simprints/libsimprints/Constants.java b/src/main/java/com/simprints/libsimprints/Constants.java deleted file mode 100644 index 4c6da69..0000000 --- a/src/main/java/com/simprints/libsimprints/Constants.java +++ /dev/null @@ -1,111 +0,0 @@ -package com.simprints.libsimprints; - -import android.app.Activity; - -@SuppressWarnings({"unused", "WeakerAccess"}) -public class Constants { - - // Intents - final public static String SIMPRINTS_REGISTER_INTENT = "com.simprints.id.REGISTER"; - final public static String SIMPRINTS_IDENTIFY_INTENT = "com.simprints.id.IDENTIFY"; - final public static String SIMPRINTS_UPDATE_INTENT = "com.simprints.id.UPDATE"; - final public static String SIMPRINTS_VERIFY_INTENT = "com.simprints.id.VERIFY"; - final public static String SIMPRINTS_SELECT_GUID_INTENT = "com.simprints.id.CONFIRM_IDENTITY"; - final public static String SIMPRINTS_REGISTER_LAST_BIOMETRICS_INTENT = "com.simprints.id.REGISTER_LAST_BIOMETRICS"; - - // Mandatory extras - final public static String SIMPRINTS_PROJECT_ID = "projectId"; - final public static String SIMPRINTS_USER_ID = "userId"; - final public static String SIMPRINTS_MODULE_ID = "moduleId"; - - // Mandatory for SIMPRINTS_UPDATE_INTENT - final public static String SIMPRINTS_UPDATE_GUID = "updateGuid"; - - // Mandatory for SIMPRINTS_VERIFY_INTENT - final public static String SIMPRINTS_VERIFY_GUID = "verifyGuid"; - - // Mandatory for SIMPRINTS_SELECT_GUID_INTENT - final public static String SIMPRINTS_SELECTED_GUID = "selectedGuid"; - final public static String SIMPRINTS_SESSION_ID = "sessionId"; - - // Optional extras - final public static String SIMPRINTS_CALLING_PACKAGE = "packageName"; - final public static String SIMPRINTS_BIOMETRIC_DATA_SOURCE = "biometricDataSource"; - final public static String SIMPRINTS_METADATA = "metadata"; - - // Optional keys in SIMPRINTS_METADATA - final public static String SIMPRINTS_SUBJECT_AGE = "subjectAge"; - - // Custom callout parameters for particular integrations: Don't include if not needed - final public static String SIMPRINTS_RESULT_FORMAT = "resultFormat"; - final public static String SIMPRINTS_ODK_RESULT_FORMAT_V01 = "ODKv01"; - final public static String SIMPRINTS_ODK_RESULT_FORMAT_V01_SEPARATOR = " "; - - // Result codes - final public static int SIMPRINTS_OK = Activity.RESULT_OK; - final public static int SIMPRINTS_CANCELLED = Activity.RESULT_CANCELED; - final public static int SIMPRINTS_MISSING_USER_ID = Activity.RESULT_FIRST_USER + 2; - final public static int SIMPRINTS_MISSING_MODULE_ID = Activity.RESULT_FIRST_USER + 4; - final public static int SIMPRINTS_INVALID_INTENT_ACTION = Activity.RESULT_FIRST_USER + 6; - final public static int SIMPRINTS_INVALID_UPDATE_GUID = Activity.RESULT_FIRST_USER + 7; - final public static int SIMPRINTS_MISSING_UPDATE_GUID = Activity.RESULT_FIRST_USER + 8; - final public static int SIMPRINTS_MISSING_VERIFY_GUID = Activity.RESULT_FIRST_USER + 9; - final public static int SIMPRINTS_INVALID_METADATA = Activity.RESULT_FIRST_USER + 10; - final public static int SIMPRINTS_VERIFY_GUID_NOT_FOUND_ONLINE = Activity.RESULT_FIRST_USER + 11; - final public static int SIMPRINTS_VERIFY_GUID_NOT_FOUND_OFFLINE = Activity.RESULT_FIRST_USER + 12; - final public static int SIMPRINTS_INVALID_VERIFY_GUID = Activity.RESULT_FIRST_USER + 13; - final public static int SIMPRINTS_INVALID_RESULT_FORMAT = Activity.RESULT_FIRST_USER + 14; - final public static int SIMPRINTS_INVALID_MODULE_ID = Activity.RESULT_FIRST_USER + 15; - final public static int SIMPRINTS_INVALID_USER_ID = Activity.RESULT_FIRST_USER + 16; - final public static int SIMPRINTS_INVALID_CALLING_PACKAGE = Activity.RESULT_FIRST_USER + 17; - final public static int SIMPRINTS_MISSING_PROJECT_ID = Activity.RESULT_FIRST_USER + 18; - final public static int SIMPRINTS_INVALID_PROJECT_ID = Activity.RESULT_FIRST_USER + 19; - final public static int SIMPRINTS_DIFFERENT_PROJECT_ID = Activity.RESULT_FIRST_USER + 20; - final public static int SIMPRINTS_DIFFERENT_USER_ID = Activity.RESULT_FIRST_USER + 21; - final public static int SIMPRINTS_ROOTED_DEVICE = Activity.RESULT_FIRST_USER + 22; - final public static int SIMPRINTS_UNEXPECTED_ERROR = Activity.RESULT_FIRST_USER + 23; - final public static int SIMPRINTS_BLUETOOTH_NOT_SUPPORTED = Activity.RESULT_FIRST_USER + 24; - final public static int SIMPRINTS_INVALID_SELECTED_ID = Activity.RESULT_FIRST_USER + 25; - final public static int SIMPRINTS_INVALID_SESSION_ID = Activity.RESULT_FIRST_USER + 26; - final public static int SIMPRINTS_LOGIN_NOT_COMPLETE = Activity.RESULT_FIRST_USER + 27; - final public static int SIMPRINTS_INVALID_STATE_FOR_INTENT_ACTION = Activity.RESULT_FIRST_USER + 28; - final public static int SIMPRINTS_ENROLMENT_LAST_BIOMETRICS_FAILED= Activity.RESULT_FIRST_USER + 29; - final public static int SIMPRINTS_LICENSE_MISSING = Activity.RESULT_FIRST_USER + 30; - final public static int SIMPRINTS_LICENSE_INVALID = Activity.RESULT_FIRST_USER + 31; - final public static int SIMPRINTS_SETUP_OFFLINE_DURING_MODALITY_DOWNLOAD = Activity.RESULT_FIRST_USER + 32; - final public static int SIMPRINTS_SETUP_MODALITY_DOWNLOAD_CANCELLED = Activity.RESULT_FIRST_USER + 33; - final public static int SIMPRINTS_FINGERPRINT_CONFIGURATION_ERROR = Activity.RESULT_FIRST_USER + 34; - final public static int SIMPRINTS_FACE_CONFIGURATION_ERROR = Activity.RESULT_FIRST_USER + 35; - final public static int SIMPRINTS_BACKEND_MAINTENANCE_ERROR = Activity.RESULT_FIRST_USER + 36; - final public static int SIMPRINTS_PROJECT_PAUSED = Activity.RESULT_FIRST_USER + 37; - final public static int SIMPRINTS_PROJECT_ENDING = Activity.RESULT_FIRST_USER + 38; - final public static int SIMPRINTS_BLUETOOTH_NO_PERMISSION = Activity.RESULT_FIRST_USER + 39; - final public static int SIMPRINTS_AGE_GROUP_NOT_SUPPORTED = Activity.RESULT_FIRST_USER + 40; - - // Result extras - final public static String SIMPRINTS_REGISTRATION = "registration"; - final public static String SIMPRINTS_IDENTIFICATIONS = "identification"; - final public static String SIMPRINTS_VERIFICATION = "verification"; - final public static String SIMPRINTS_VERIFICATION_SUCCESS = "verificationSuccess"; - final public static String SIMPRINTS_REFUSAL_FORM = "refusalForm"; - - // When SIMPRINTS_BIOMETRICS_COMPLETE_CHECK is true, the user has completed the Simprints flow - final public static String SIMPRINTS_BIOMETRICS_COMPLETE_CHECK = "biometricsComplete"; - - // These two values represent data that could be null. They only apply to projects using cosync - final public static String SIMPRINTS_COSYNC_EVENT = "events"; - final public static String SIMPRINTS_COSYNC_SUBJECT_ACTIONS = "subjectActions"; - - // Deprecated extras - /** @deprecated use {@link #SIMPRINTS_PROJECT_ID} instead. */ - @Deprecated - final public static String SIMPRINTS_API_KEY = "apiKey"; - - // Deprecated result codes - /** @deprecated use {@link #SIMPRINTS_MISSING_PROJECT_ID} instead. */ - @Deprecated - final public static int SIMPRINTS_MISSING_API_KEY = Activity.RESULT_FIRST_USER; - /** @deprecated use {@link #SIMPRINTS_INVALID_PROJECT_ID} instead. */ - @Deprecated - final public static int SIMPRINTS_INVALID_API_KEY = Activity.RESULT_FIRST_USER + 1; -} diff --git a/src/main/java/com/simprints/libsimprints/Constants.kt b/src/main/java/com/simprints/libsimprints/Constants.kt new file mode 100644 index 0000000..f2ae264 --- /dev/null +++ b/src/main/java/com/simprints/libsimprints/Constants.kt @@ -0,0 +1,105 @@ +package com.simprints.libsimprints; + +import android.app.Activity; + +@SuppressWarnings("unused", "WeakerAccess") +object Constants { + + // Intents + const val SIMPRINTS_REGISTER_INTENT = "com.simprints.id.REGISTER"; + const val SIMPRINTS_IDENTIFY_INTENT = "com.simprints.id.IDENTIFY"; + const val SIMPRINTS_VERIFY_INTENT = "com.simprints.id.VERIFY"; + const val SIMPRINTS_SELECT_GUID_INTENT = "com.simprints.id.CONFIRM_IDENTITY"; + const val SIMPRINTS_REGISTER_LAST_BIOMETRICS_INTENT = "com.simprints.id.REGISTER_LAST_BIOMETRICS"; + + // Mandatory extras + const val SIMPRINTS_PROJECT_ID = "projectId"; + const val SIMPRINTS_USER_ID = "userId"; + const val SIMPRINTS_MODULE_ID = "moduleId"; + + // Mandatory for SIMPRINTS_VERIFY_INTENT + const val SIMPRINTS_VERIFY_GUID = "verifyGuid"; + + // Mandatory for SIMPRINTS_SELECT_GUID_INTENT + const val SIMPRINTS_SELECTED_GUID = "selectedGuid"; + const val SIMPRINTS_SESSION_ID = "sessionId"; + + // Optional extras + const val SIMPRINTS_CALLING_PACKAGE = "packageName"; + const val SIMPRINTS_BIOMETRIC_DATA_SOURCE = "biometricDataSource"; + const val SIMPRINTS_METADATA = "metadata"; + + // Optional keys in SIMPRINTS_METADATA + const val SIMPRINTS_SUBJECT_AGE = "subjectAge"; + + // Custom callout parameters for particular integrations: Don't include if not needed + const val SIMPRINTS_RESULT_FORMAT = "resultFormat"; + const val SIMPRINTS_ODK_RESULT_FORMAT_V01 = "ODKv01"; + const val SIMPRINTS_ODK_RESULT_FORMAT_V01_SEPARATOR = " "; + + // Result codes + const val SIMPRINTS_OK = Activity.RESULT_OK; + const val SIMPRINTS_CANCELLED = Activity.RESULT_CANCELED; + const val SIMPRINTS_MISSING_USER_ID = Activity.RESULT_FIRST_USER + 2; + const val SIMPRINTS_MISSING_MODULE_ID = Activity.RESULT_FIRST_USER + 4; + const val SIMPRINTS_INVALID_INTENT_ACTION = Activity.RESULT_FIRST_USER + 6; + const val SIMPRINTS_INVALID_UPDATE_GUID = Activity.RESULT_FIRST_USER + 7; + const val SIMPRINTS_MISSING_UPDATE_GUID = Activity.RESULT_FIRST_USER + 8; + const val SIMPRINTS_MISSING_VERIFY_GUID = Activity.RESULT_FIRST_USER + 9; + const val SIMPRINTS_INVALID_METADATA = Activity.RESULT_FIRST_USER + 10; + const val SIMPRINTS_VERIFY_GUID_NOT_FOUND_ONLINE = Activity.RESULT_FIRST_USER + 11; + const val SIMPRINTS_VERIFY_GUID_NOT_FOUND_OFFLINE = Activity.RESULT_FIRST_USER + 12; + const val SIMPRINTS_INVALID_VERIFY_GUID = Activity.RESULT_FIRST_USER + 13; + const val SIMPRINTS_INVALID_RESULT_FORMAT = Activity.RESULT_FIRST_USER + 14; + const val SIMPRINTS_INVALID_MODULE_ID = Activity.RESULT_FIRST_USER + 15; + const val SIMPRINTS_INVALID_USER_ID = Activity.RESULT_FIRST_USER + 16; + const val SIMPRINTS_INVALID_CALLING_PACKAGE = Activity.RESULT_FIRST_USER + 17; + const val SIMPRINTS_MISSING_PROJECT_ID = Activity.RESULT_FIRST_USER + 18; + const val SIMPRINTS_INVALID_PROJECT_ID = Activity.RESULT_FIRST_USER + 19; + const val SIMPRINTS_DIFFERENT_PROJECT_ID = Activity.RESULT_FIRST_USER + 20; + const val SIMPRINTS_DIFFERENT_USER_ID = Activity.RESULT_FIRST_USER + 21; + const val SIMPRINTS_ROOTED_DEVICE = Activity.RESULT_FIRST_USER + 22; + const val SIMPRINTS_UNEXPECTED_ERROR = Activity.RESULT_FIRST_USER + 23; + const val SIMPRINTS_BLUETOOTH_NOT_SUPPORTED = Activity.RESULT_FIRST_USER + 24; + const val SIMPRINTS_INVALID_SELECTED_ID = Activity.RESULT_FIRST_USER + 25; + const val SIMPRINTS_INVALID_SESSION_ID = Activity.RESULT_FIRST_USER + 26; + const val SIMPRINTS_LOGIN_NOT_COMPLETE = Activity.RESULT_FIRST_USER + 27; + const val SIMPRINTS_INVALID_STATE_FOR_INTENT_ACTION = Activity.RESULT_FIRST_USER + 28; + const val SIMPRINTS_ENROLMENT_LAST_BIOMETRICS_FAILED = Activity.RESULT_FIRST_USER + 29; + const val SIMPRINTS_LICENSE_MISSING = Activity.RESULT_FIRST_USER + 30; + const val SIMPRINTS_LICENSE_INVALID = Activity.RESULT_FIRST_USER + 31; + const val SIMPRINTS_SETUP_OFFLINE_DURING_MODALITY_DOWNLOAD = Activity.RESULT_FIRST_USER + 32; + const val SIMPRINTS_SETUP_MODALITY_DOWNLOAD_CANCELLED = Activity.RESULT_FIRST_USER + 33; + const val SIMPRINTS_FINGERPRINT_CONFIGURATION_ERROR = Activity.RESULT_FIRST_USER + 34; + const val SIMPRINTS_FACE_CONFIGURATION_ERROR = Activity.RESULT_FIRST_USER + 35; + const val SIMPRINTS_BACKEND_MAINTENANCE_ERROR = Activity.RESULT_FIRST_USER + 36; + const val SIMPRINTS_PROJECT_PAUSED = Activity.RESULT_FIRST_USER + 37; + const val SIMPRINTS_PROJECT_ENDING = Activity.RESULT_FIRST_USER + 38; + const val SIMPRINTS_BLUETOOTH_NO_PERMISSION = Activity.RESULT_FIRST_USER + 39; + const val SIMPRINTS_AGE_GROUP_NOT_SUPPORTED = Activity.RESULT_FIRST_USER + 40; + + // Result extras + const val SIMPRINTS_REGISTRATION = "registration"; + const val SIMPRINTS_IDENTIFICATIONS = "identification"; + const val SIMPRINTS_VERIFICATION = "verification"; + const val SIMPRINTS_VERIFICATION_SUCCESS = "verificationSuccess"; + const val SIMPRINTS_REFUSAL_FORM = "refusalForm"; + + // When SIMPRINTS_BIOMETRICS_COMPLETE_CHECK is true, the user has completed the Simprints flow + const val SIMPRINTS_BIOMETRICS_COMPLETE_CHECK = "biometricsComplete"; + + // These two values represent data that could be null. They only apply to projects using cosync + const val SIMPRINTS_COSYNC_EVENT = "events"; + const val SIMPRINTS_COSYNC_SUBJECT_ACTIONS = "subjectActions"; + + // Deprecated extras + @Deprecated("Use {@link #SIMPRINTS_PROJECT_ID} instead.") + const val SIMPRINTS_API_KEY = "apiKey"; + + // Deprecated result codes + @Deprecated("Use {@link #SIMPRINTS_MISSING_PROJECT_ID} instead.") + const val SIMPRINTS_MISSING_API_KEY = Activity.RESULT_FIRST_USER; + + @Deprecated("Use {@link #SIMPRINTS_INVALID_PROJECT_ID} instead.") + const val SIMPRINTS_INVALID_API_KEY = Activity.RESULT_FIRST_USER + 1; +} diff --git a/src/main/java/com/simprints/libsimprints/FingerIdentifier.java b/src/main/java/com/simprints/libsimprints/FingerIdentifier.kt similarity index 89% rename from src/main/java/com/simprints/libsimprints/FingerIdentifier.java rename to src/main/java/com/simprints/libsimprints/FingerIdentifier.kt index 4d39b64..d717dfa 100644 --- a/src/main/java/com/simprints/libsimprints/FingerIdentifier.java +++ b/src/main/java/com/simprints/libsimprints/FingerIdentifier.kt @@ -1,7 +1,7 @@ package com.simprints.libsimprints; @SuppressWarnings("unused") -public enum FingerIdentifier { +enum class FingerIdentifier { RIGHT_5TH_FINGER, RIGHT_4TH_FINGER, RIGHT_3RD_FINGER, diff --git a/src/main/java/com/simprints/libsimprints/Identification.java b/src/main/java/com/simprints/libsimprints/Identification.java deleted file mode 100644 index 3c63d62..0000000 --- a/src/main/java/com/simprints/libsimprints/Identification.java +++ /dev/null @@ -1,120 +0,0 @@ -package com.simprints.libsimprints; - -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.NonNull; - -@SuppressWarnings("unused") -public class Identification implements Parcelable, Comparable { - - private String guid; - private int confidence; - private Tier tier; - - /** - * Empty constructor - */ - public Identification() { - - } - - /** - * This constructor creates a new identification - * - * @param guid A string containing the guid - * @param confidence An int containing the (matching) confidence - */ - public Identification(String guid, int confidence, Tier tier) { - this.guid = guid; - this.confidence = confidence; - this.tier = tier; - } - - protected Identification(Parcel in) { - guid = in.readString(); - confidence = in.readInt(); - tier = Tier.values()[in.readInt()]; - } - - public static final Creator CREATOR = new Creator() { - @Override - public Identification createFromParcel(Parcel in) { - return new Identification(in); - } - - @Override - public Identification[] newArray(int size) { - return new Identification[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(this.guid); - dest.writeInt(this.confidence); - dest.writeInt(this.tier.ordinal()); - } - - public String getGuid() { - return guid; - } - - public void setGuid(String guid) { - this.guid = guid; - } - - public float getConfidence() { - return confidence; - } - - public void setConfidence(int confidence) { - this.confidence = confidence; - } - - public Tier getTier() { - return tier; - } - - public void setTier(Tier tier) { - this.tier = tier; - } - - @Override - public int compareTo(@NonNull Identification otherId) { - if (confidence == otherId.confidence) { - return 0; - } else if (confidence < otherId.confidence) { - return 1; - } else { - return -1; - } - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (o instanceof Identification) { - Identification other = (Identification) o; - return (guid.equals(other.guid) && - confidence == other.confidence && - tier.equals(other.tier)); - } - return false; - } - - @Override - public int hashCode() { - int hash = guid.hashCode(); - hash = hash * 17 + confidence; - hash = hash * 17 + tier.hashCode(); - return hash; - } -} diff --git a/src/main/java/com/simprints/libsimprints/Identification.kt b/src/main/java/com/simprints/libsimprints/Identification.kt new file mode 100644 index 0000000..730b627 --- /dev/null +++ b/src/main/java/com/simprints/libsimprints/Identification.kt @@ -0,0 +1,28 @@ +package com.simprints.libsimprints; + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +/** + * This constructor creates a new identification + * + * @param guid Global unique id of the verified person + * @param confidence An int containing the (matching) confidence + * @param tier The tier score derived from the confidence + */ +@SuppressWarnings("unused") +@Parcelize +data class Identification( + val guid: String, + private val confidence: Int, + val tier: Tier, +) : Parcelable, Comparable { + + fun getConfidence(): Float = confidence.toFloat() + + override fun compareTo(other: Identification): Int = when { + confidence == other.confidence -> 0 + confidence < other.confidence -> 1 + else -> -1 + } +} diff --git a/src/main/java/com/simprints/libsimprints/Metadata.java b/src/main/java/com/simprints/libsimprints/Metadata.kt similarity index 51% rename from src/main/java/com/simprints/libsimprints/Metadata.java rename to src/main/java/com/simprints/libsimprints/Metadata.kt index cb2c29f..c01ceb8 100644 --- a/src/main/java/com/simprints/libsimprints/Metadata.java +++ b/src/main/java/com/simprints/libsimprints/Metadata.kt @@ -1,12 +1,7 @@ -package com.simprints.libsimprints; +package com.simprints.libsimprints - -import org.json.JSONException; -import org.json.JSONObject; - -import java.util.Iterator; - -import androidx.annotation.NonNull; +import org.json.JSONException +import org.json.JSONObject /** * A set of key/value mappings. Keys are unique, non-null strings. Values may be any mix of non null strings, booleans, longs or finite doubles. @@ -15,21 +10,14 @@ *

* Example: one could attach the age of the enrollee and the city they were enrolled, in order to find out the average age of beneficiaries for each city. */ -@SuppressWarnings({"WeakerAccess", "unused"}) -public class Metadata { - - public class InvalidMetadataException extends Exception { - /** - * Constructs a new exception with the specified detail message. - * - * @param message the detail message. The detail message is saved for later retrieval by the getMessage() method. - */ - InvalidMetadataException(String message) { - super(message); - } - } +data class Metadata( + private var json: JSONObject = JSONObject(), +) { - final private JSONObject json; + /** + * Thrown when provided meta-data cannot be marshalled or unmarshalled from the intent extras. + */ + class InvalidMetadataException(message: String) : RuntimeException(message) /** * Constructs a new Metadata object with key/value mappings from a JSON object string. @@ -39,29 +27,22 @@ public class InvalidMetadataException extends Exception { * @throws InvalidMetadataException if the passed string is not a valid JSON object string, * or it contains nested arrays or key/value mappings. */ - public Metadata(@NonNull String jsonString) throws InvalidMetadataException { + constructor(jsonString: String) : this() { // Parse the JSON-encoded string try { - json = new JSONObject(jsonString); - } catch (JSONException e) { - throw new InvalidMetadataException("The metadata string is not a valid JSON object string."); + json = JSONObject(jsonString) + } catch (e: JSONException) { + throw InvalidMetadataException("The metadata string is not a valid JSON object string.") } // Make sure the metadata string does not contain nested arrays or key-value mappings - Iterator keys = json.keys(); + val keys = json.keys(); while (keys.hasNext()) { - String key = keys.next(); + val key = keys.next(); if (json.optJSONArray(key) != null || json.optJSONObject(key) != null) - throw new InvalidMetadataException("Only boolean, string, integer and floating point values are allowed."); + throw InvalidMetadataException("Only boolean, string, integer and floating point values are allowed."); } } - /** - * Constructs a new empty Metadata object. - */ - public Metadata() { - json = new JSONObject(); - } - /** * Adds a new key/boolean value mapping to this metadata object, replacing any mapping with the same key. * @@ -69,10 +50,7 @@ public Metadata() { * @param value a boolean. * @return this object. */ - @NonNull - public Metadata put(@NonNull String key, boolean value) { - return putObject(key, value); - } + fun put(key: String, value: Boolean) = putObject(key, value) /** * Adds a new key/double value mapping to this metadata object, replacing any mapping with the same key. @@ -81,10 +59,7 @@ public Metadata put(@NonNull String key, boolean value) { * @param value a finite double. May not be NaNs or infinities. * @return this object. */ - @NonNull - public Metadata put(@NonNull String key, double value) { - return putObject(key, value); - } + fun put(key: String, value: Double) = putObject(key, value) /** * Adds a new key/long value mapping to this metadata object, replacing any mapping with the same key. @@ -93,10 +68,7 @@ public Metadata put(@NonNull String key, double value) { * @param value a long. * @return this object. */ - @NonNull - public Metadata put(@NonNull String key, long value) { - return putObject(key, value); - } + fun put(key: String, value: Long) = putObject(key, value) /** * Adds a new key/string value mapping to this metadata object, replacing any mapping with the same key. @@ -105,9 +77,15 @@ public Metadata put(@NonNull String key, long value) { * @param value a non-null string. * @return this object. */ - @NonNull - public Metadata put(@NonNull String key, @NonNull String value) { - return putObject(key, value); + fun put(key: String, value: String) = putObject(key, value) + + private fun putObject(key: String, value: Any): Metadata { + try { + json.put(key, value); + } catch (e: JSONException) { + throw RuntimeException(e); + } + return this } /** @@ -115,25 +93,5 @@ public Metadata put(@NonNull String key, @NonNull String value) { * * @return a string representation of the object. */ - @NonNull - public String toString() { - return json.toString(); - } - - /** - * Adds a new key/value mapping to this metadata object, replacing any mapping with the same key. - * - * @param key a non-null string. - * @param value a boolean, long, finite double, or non-null string. - * @return this object. - */ - @NonNull - private Metadata putObject(@NonNull String key, @NonNull Object value) { - try { - json.put(key, value); - } catch (JSONException e) { - throw new RuntimeException(e); - } - return this; - } + override fun toString() = json.toString() } diff --git a/src/main/java/com/simprints/libsimprints/RefusalForm.java b/src/main/java/com/simprints/libsimprints/RefusalForm.java deleted file mode 100644 index 4c28b61..0000000 --- a/src/main/java/com/simprints/libsimprints/RefusalForm.java +++ /dev/null @@ -1,64 +0,0 @@ -package com.simprints.libsimprints; - -import android.os.Parcel; -import android.os.Parcelable; - -@SuppressWarnings({"WeakerAccess", "unused"}) -public class RefusalForm implements Parcelable { - private String reason; - private String extra; - - public RefusalForm(String reason, String extra) { - this.reason = reason; - this.extra = extra; - } - - protected RefusalForm(Parcel in) { - this.reason = in.readString(); - this.extra = in.readString(); - } - - public String getReason() { - return this.reason; - } - - public String getExtra() { - return this.extra; - } - - public static final Creator CREATOR = new Creator() { - @Override - public RefusalForm createFromParcel(Parcel in) { - return new RefusalForm(in); - } - - @Override - public RefusalForm[] newArray(int size) { - return new RefusalForm[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(reason); - dest.writeString(extra); - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (o instanceof RefusalForm) { - RefusalForm other = (RefusalForm) o; - return (reason.equals(other.reason) && - extra.equals(other.extra)); - } - return false; - } -} diff --git a/src/main/java/com/simprints/libsimprints/RefusalForm.kt b/src/main/java/com/simprints/libsimprints/RefusalForm.kt new file mode 100644 index 0000000..20771e6 --- /dev/null +++ b/src/main/java/com/simprints/libsimprints/RefusalForm.kt @@ -0,0 +1,11 @@ +package com.simprints.libsimprints; + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@SuppressWarnings("WeakerAccess", "unused") +@Parcelize +data class RefusalForm( + val reason: String, + val extra: String, +) : Parcelable diff --git a/src/main/java/com/simprints/libsimprints/Registration.java b/src/main/java/com/simprints/libsimprints/Registration.java deleted file mode 100644 index e9bfe49..0000000 --- a/src/main/java/com/simprints/libsimprints/Registration.java +++ /dev/null @@ -1,112 +0,0 @@ -package com.simprints.libsimprints; - -import android.os.Parcel; -import android.os.Parcelable; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; - -import androidx.annotation.NonNull; - -@SuppressWarnings({"unused", "WeakerAccess"}) -public class Registration implements Parcelable { - - private String guid; - private Map templates; - - /** - * This constructor creates a new registration - * - * @param guid Global user id - */ - public Registration(String guid) { - this.guid = guid; - templates = new HashMap<>(); - } - - protected Registration(Parcel in) { - this.guid = in.readString(); - int nbOfTemplates = in.readInt(); - this.templates = new HashMap<>(nbOfTemplates); - for (int i = 0; i < nbOfTemplates; i++) { - FingerIdentifier fingerId = FingerIdentifier.values()[in.readInt()]; - byte[] fingerTemplate = new byte[in.readInt()]; - in.readByteArray(fingerTemplate); - this.templates.put(fingerId, fingerTemplate); - } - } - - public static final Creator CREATOR = new Creator() { - @Override - public Registration createFromParcel(Parcel in) { - return new Registration(in); - } - - @Override - public Registration[] newArray(int size) { - return new Registration[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeString(guid); - dest.writeInt(templates.size()); - for (Map.Entry e : templates.entrySet()) { - dest.writeInt(e.getKey().ordinal()); - dest.writeInt(e.getValue().length); - dest.writeByteArray(e.getValue()); - } - } - - public String getGuid() { - return guid; - } - - public void setTemplate(FingerIdentifier fingerId, @NonNull byte[] fingerTemplate) { - this.templates.put(fingerId, fingerTemplate); - } - - public byte[] getTemplate(FingerIdentifier fingerId) { - if (templates.containsKey(fingerId)) { - return templates.get(fingerId); - } else { - return new byte[0]; - } - } - - @Override - public boolean equals(Object o) { - if (o == this) { - return true; - } - if (!(o instanceof Registration)) { - return false; - } - Registration other = (Registration) o; - if (!guid.equals(other.guid)) { - return false; - } - for (FingerIdentifier fingerId : FingerIdentifier.values()) { - if (!Arrays.equals(templates.get(fingerId), other.templates.get(fingerId))) { - return false; - } - } - return true; - } - - @Override - public int hashCode() { - int hash = guid.hashCode(); - for (FingerIdentifier fingerId : FingerIdentifier.values()) { - hash = hash * 17 + Arrays.hashCode(templates.get(fingerId)); - } - return hash; - } -} diff --git a/src/main/java/com/simprints/libsimprints/Registration.kt b/src/main/java/com/simprints/libsimprints/Registration.kt new file mode 100644 index 0000000..7c4bacd --- /dev/null +++ b/src/main/java/com/simprints/libsimprints/Registration.kt @@ -0,0 +1,35 @@ +package com.simprints.libsimprints; + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +@SuppressWarnings("unused", "WeakerAccess") +@Parcelize +data class Registration @JvmOverloads constructor( + val guid: String, + private val templates: MutableMap = mutableMapOf() +) : Parcelable { + + fun setTemplate(fingerId: FingerIdentifier, fingerTemplate: ByteArray) { + templates[fingerId] = fingerTemplate + } + + fun getTemplate(fingerId: FingerIdentifier): ByteArray = templates[fingerId] ?: byteArrayOf() + + override fun hashCode(): Int { + var result = super.hashCode() + result = 31 * result + guid.hashCode() + result = 31 * result + templates.hashCode() + return result + } + + override fun equals(other: Any?): Boolean { + if (other === this) return true + if (other !is Registration) return false + if (guid != other.guid) return false + for (fingerId in FingerIdentifier.entries) { + templates[fingerId] == (other.templates[fingerId] ?: return false) + } + return true; + } +} diff --git a/src/main/java/com/simprints/libsimprints/SimHelper.java b/src/main/java/com/simprints/libsimprints/SimHelper.java deleted file mode 100644 index 554a8a7..0000000 --- a/src/main/java/com/simprints/libsimprints/SimHelper.java +++ /dev/null @@ -1,213 +0,0 @@ -package com.simprints.libsimprints; - -import android.content.Context; -import android.content.Intent; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -/** - * A helper class facilitating the construction of an {@link Intent} to call Simprints ID. - *

- * Two call-outs are currently available: - *

    - *
  • A registration call-out will collect fingerprints and link them to a new GUID. - * The call-back data will either contain a {@link Registration} object with the GUID and the fingerprint templates, or a {@link RefusalForm} object with additional refusal data. - *
  • An identification call-out will collect fingerprints and search through a group of people. - * The call-back data will either contain an array of {@link Identification} objects, or a {@link RefusalForm} object with additional refusal data. - *
  • A verify call-out will collect fingerprints and verify a specific user. The call-back will return a {@link Verification} object, or additional data such as errors and refusal data. - *
  • (COMING SOON) An update call-out will collect new fingerprints and link them to an existing GUID. - *

- */ -@SuppressWarnings({"unused", "WeakerAccess"}) -public class SimHelper { - - final private String projectId; - final private String userId; - - /** - * Constructs a new helper for making call-outs to Simprints ID with the specified project id and user id. - * - * @param projectId identifies the project that is making the call-out. Will be checked if it matches the scanned project id upon signing-in. - * @param userId identifies which user is making a request to Simprints ID. Can be any arbitrary String. - */ - public SimHelper(@NonNull String projectId, @NonNull String userId) { - this.projectId = projectId; - this.userId = userId; - } - - /** - * Builds a new {@link Intent} to make a registration call-out to Simprints ID. - * This intent will start an activity that returns a {@link Registration} object. - * - * @param moduleId identifies which module to register into. - * @return a new registration {@link Intent}. - */ - @NonNull - public Intent register(@NonNull String moduleId) { - return new Intent(Constants.SIMPRINTS_REGISTER_INTENT) - .putExtra(Constants.SIMPRINTS_PROJECT_ID, projectId) - .putExtra(Constants.SIMPRINTS_USER_ID, userId) - .putExtra(Constants.SIMPRINTS_MODULE_ID, moduleId); - } - - /** - * Builds a new {@link Intent} to make a registration call-out to Simprints ID - * with additional arbitrary {@link Metadata}. - * This intent will start an activity that returns a {@link Registration} object. - * - * @param moduleId identifies which module to register into. - * @param metadata optional metadata to attach to the registration. - * @return a new registration {@link Intent}. - */ - @NonNull - public Intent register(@NonNull String moduleId, @NonNull Metadata metadata) { - return register(moduleId) - .putExtra(Constants.SIMPRINTS_METADATA, metadata.toString()); - } - - /** - * (COMING SOON) Builds a new {@link Intent} to make an update call-out to Simprints ID. - * - * @param moduleId identifies which module to update. - * @param updateId identifies which beneficiary to update. - * @return a new update {@link Intent}. - */ - @NonNull - public Intent update(@NonNull String moduleId, @NonNull String updateId) { - return new Intent(Constants.SIMPRINTS_UPDATE_INTENT) - .putExtra(Constants.SIMPRINTS_PROJECT_ID, projectId) - .putExtra(Constants.SIMPRINTS_USER_ID, userId) - .putExtra(Constants.SIMPRINTS_MODULE_ID, moduleId) - .putExtra(Constants.SIMPRINTS_UPDATE_GUID, updateId); - } - - /** - * (COMING SOON) Builds a new {@link Intent} to make an update call-out to Simprints ID - * with additional arbitrary {@link Metadata}. - * - * @param moduleId identifies which module to update. - * @param updateId identifies which beneficiary to update. - * @param metadata optional metadata to attach to the update. - * @return a new update {@link Intent}. - */ - @NonNull - public Intent update(@NonNull String moduleId, @NonNull String updateId, @NonNull Metadata metadata) { - return update(moduleId, updateId) - .putExtra(Constants.SIMPRINTS_METADATA, metadata.toString()); - } - - /** - * Builds a new {@link Intent} to make an identification call-out to Simprints ID. - * This intent will start an activity that returns an ArrayList of {@link Identification} objects. - * - * @param moduleId identifies which module to search in. - * @return a new identification {@link Intent}. - */ - @NonNull - public Intent identify(@NonNull String moduleId) { - Intent intent = new Intent(Constants.SIMPRINTS_IDENTIFY_INTENT); - intent.putExtra(Constants.SIMPRINTS_PROJECT_ID, projectId); - intent.putExtra(Constants.SIMPRINTS_USER_ID, userId); - intent.putExtra(Constants.SIMPRINTS_MODULE_ID, moduleId); - return intent; - } - - /** - * Builds a new {@link Intent} to make an identification call-out to Simprints ID with - * additional arbitrary {@link Metadata}. - * This intent will start an activity that returns an ArrayList of {@link Identification} objects. - * - * @param moduleId identifies which module to search in. - * @param metadata optional metadata to attach to the identification. - * @return a new identification {@link Intent}. - */ - @NonNull - public Intent identify(@NonNull String moduleId, @NonNull Metadata metadata) { - return identify(moduleId) - .putExtra(Constants.SIMPRINTS_METADATA, metadata.toString()); - } - - /** - * Sends which GUID was confirmed in a session back to SimprintsId. - * - * @param sessionId identifies the identification session. - * @param selectedGuid the GUID that was confirmed in the host app. - * @return a new confirm indentity {@link Intent}. - */ - public Intent confirmIdentity(@NonNull String sessionId, @Nullable String selectedGuid) { - Intent intent = new Intent(Constants.SIMPRINTS_SELECT_GUID_INTENT); - intent.putExtra(Constants.SIMPRINTS_PROJECT_ID, projectId); - intent.putExtra(Constants.SIMPRINTS_SESSION_ID, sessionId); - intent.putExtra(Constants.SIMPRINTS_SELECTED_GUID, selectedGuid); - return intent; - } - - /** - * Builds a new {@link Intent} to register the templates captured during - * the last Simprints ID session, if that was an identification. - * Used to register a new record after an identification that hasn't produced - * valid results without capturing the templates again. - * - * @param moduleId identifies which module to register into. - * @param sessionId identifies the identification session. - * @return a new registration for last biometrics {@link Intent}. - */ - public Intent registerLastBiometrics(@NonNull String moduleId, @NonNull String sessionId) { - return new Intent(Constants.SIMPRINTS_REGISTER_LAST_BIOMETRICS_INTENT) - .putExtra(Constants.SIMPRINTS_PROJECT_ID, projectId) - .putExtra(Constants.SIMPRINTS_USER_ID, userId) - .putExtra(Constants.SIMPRINTS_MODULE_ID, moduleId) - .putExtra(Constants.SIMPRINTS_SESSION_ID, sessionId); - } - - /** - * Builds a new {@link Intent} to register the templates captured during - * the last Simprints ID session, if that was an identification. - * Used to register a new record after an identification that hasn't produced - * valid results without capturing the templates again. - * - * @param moduleId identifies which module to register into. - * @param metadata metadata to attach to the registration. - * @param sessionId identifies the identification session. - * @return a new registration for last biometrics {@link Intent}. - */ - public Intent registerLastBiometrics(@NonNull String moduleId, @NonNull String sessionId, @NonNull Metadata metadata) { - return registerLastBiometrics(moduleId, sessionId) - .putExtra(Constants.SIMPRINTS_METADATA, metadata.toString()); - } - - /** - * Builds a new {@link Intent} to make a verification call-out to Simprints ID. - * This intent will start an activity that returns a {@link Verification} object. - * - * @param moduleId identifies which module contains the registered beneficiary to verify. - * @param verifyId identifies which registered beneficiary to verify. - * @return a new verification {@link Intent}. - */ - @NonNull - public Intent verify(@NonNull String moduleId, @NonNull String verifyId) { - Intent intent = new Intent(Constants.SIMPRINTS_VERIFY_INTENT); - intent.putExtra(Constants.SIMPRINTS_PROJECT_ID, projectId); - intent.putExtra(Constants.SIMPRINTS_USER_ID, userId); - intent.putExtra(Constants.SIMPRINTS_MODULE_ID, moduleId); - intent.putExtra(Constants.SIMPRINTS_VERIFY_GUID, verifyId); - return intent; - } - - /** - * Builds a new {@link Intent} to make a verification call-out to Simprints ID with - * additional arbitrary {@link Metadata}. - * This intent will start an activity that returns a {@link Verification} object. - * - * @param moduleId identifies which module contains the registered beneficiary to verify. - * @param verifyId identifies which registered beneficiary to verify. - * @param metadata optional metadata to attach to the verification. - * @return a new verification {@link Intent}. - */ - @NonNull - public Intent verify(@NonNull String moduleId, @NonNull String verifyId, @NonNull Metadata metadata) { - return verify(moduleId, verifyId) - .putExtra(Constants.SIMPRINTS_METADATA, metadata.toString()); - } -} diff --git a/src/main/java/com/simprints/libsimprints/SimHelper.kt b/src/main/java/com/simprints/libsimprints/SimHelper.kt new file mode 100644 index 0000000..a51a740 --- /dev/null +++ b/src/main/java/com/simprints/libsimprints/SimHelper.kt @@ -0,0 +1,119 @@ +package com.simprints.libsimprints; + +import android.content.Intent + +/** + * A helper class facilitating the construction of an {@link Intent} to call Simprints ID. + *

+ * Two call-outs are currently available: + *

    + *
  • A registration call-out will collect fingerprints and link them to a new GUID. + * The call-back data will either contain a {@link Registration} object with the GUID and the fingerprint templates, or a {@link RefusalForm} object with additional refusal data. + *
  • An identification call-out will collect fingerprints and search through a group of people. + * The call-back data will either contain an array of {@link Identification} objects, or a {@link RefusalForm} object with additional refusal data. + *
  • A verify call-out will collect fingerprints and verify a specific user. The call-back will return a {@link Verification} object, or additional data such as errors and refusal data. + *

+ * + * @param projectId identifies the project that is making the call-out. Will be checked if it matches the scanned project id upon signing-in. + * @param userId identifies which user is making a request to Simprints ID. Can be any arbitrary String. + */ +@SuppressWarnings("unused", "WeakerAccess") +data class SimHelper( + private val projectId: String, + private val userId: String +) { + + /** + * Builds a new {@link Intent} to make a registration call-out to Simprints ID. + * This intent will start an activity that returns a {@link Registration} object. + * + * @param moduleId identifies which module to register into. + * @param metadata optional metadata to attach to the registration if provided. + * @return a new registration {@link Intent}. + */ + @JvmOverloads + fun register( + moduleId: String, + metadata: Metadata? = null, + ) = createBaseIntent(Constants.SIMPRINTS_REGISTER_INTENT) + .putExtra(Constants.SIMPRINTS_MODULE_ID, moduleId) + .appendOptionalMetadata(metadata) + + /** + * Builds a new {@link Intent} to make an identification call-out to Simprints ID. + * This intent will start an activity that returns an ArrayList of {@link Identification} objects. + * + * @param moduleId identifies which module to search in. + * @param metadata optional metadata to attach to the identification if provided. + * @return a new identification {@link Intent}. + */ + @JvmOverloads + fun identify( + moduleId: String, + metadata: Metadata? = null, + ) = createBaseIntent(Constants.SIMPRINTS_IDENTIFY_INTENT) + .putExtra(Constants.SIMPRINTS_MODULE_ID, moduleId) + .appendOptionalMetadata(metadata) + + /** + * Builds a new {@link Intent} to make a verification call-out to Simprints ID. + * This intent will start an activity that returns a {@link Verification} object. + * + * @param moduleId identifies which module contains the registered beneficiary to verify. + * @param verifyId identifies which registered beneficiary to verify. + * @param metadata optional metadata to attach to the verification if provided. + * @return a new verification {@link Intent}. + */ + @JvmOverloads + fun verify( + moduleId: String, + verifyId: String, + metadata: Metadata? = null, + ) = createBaseIntent(Constants.SIMPRINTS_VERIFY_INTENT) + .putExtra(Constants.SIMPRINTS_MODULE_ID, moduleId) + .putExtra(Constants.SIMPRINTS_VERIFY_GUID, verifyId) + .appendOptionalMetadata(metadata) + + /** + * Sends which GUID was confirmed in a session back to SimprintsId. + * + * @param sessionId identifies the identification session. + * @param selectedGuid the GUID that was confirmed in the host app. + * @return a new confirm indentity {@link Intent}. + */ + fun confirmIdentity( + sessionId: String, + selectedGuid: String, + ) = createBaseIntent(Constants.SIMPRINTS_SELECT_GUID_INTENT) + .putExtra(Constants.SIMPRINTS_SESSION_ID, sessionId) + .putExtra(Constants.SIMPRINTS_SELECTED_GUID, selectedGuid) + + /** + * Builds a new {@link Intent} to register the templates captured during + * the last Simprints ID session, if that was an identification. + * Used to register a new record after an identification that hasn't produced + * valid results without capturing the templates again. + * + * @param moduleId identifies which module to register into. + * @param sessionId identifies the identification session. + * @param metadata metadata to attach to the registration if provided. + * @return a new registration for last biometrics {@link Intent}. + */ + @JvmOverloads + fun registerLastBiometrics( + moduleId: String, + sessionId: String, + metadata: Metadata? = null, + ) = createBaseIntent(Constants.SIMPRINTS_REGISTER_LAST_BIOMETRICS_INTENT) + .putExtra(Constants.SIMPRINTS_MODULE_ID, moduleId) + .putExtra(Constants.SIMPRINTS_SESSION_ID, sessionId) + .appendOptionalMetadata(metadata) + + private fun createBaseIntent(action: String) = Intent(action) + .putExtra(Constants.SIMPRINTS_PROJECT_ID, projectId) + .putExtra(Constants.SIMPRINTS_USER_ID, userId) + + private fun Intent.appendOptionalMetadata(metadata: Metadata?) = + if (metadata == null) this + else putExtra(Constants.SIMPRINTS_METADATA, metadata.toString()) +} diff --git a/src/main/java/com/simprints/libsimprints/Tier.java b/src/main/java/com/simprints/libsimprints/Tier.kt similarity index 83% rename from src/main/java/com/simprints/libsimprints/Tier.java rename to src/main/java/com/simprints/libsimprints/Tier.kt index 6aa03bc..ba6f0e2 100644 --- a/src/main/java/com/simprints/libsimprints/Tier.java +++ b/src/main/java/com/simprints/libsimprints/Tier.kt @@ -1,6 +1,6 @@ package com.simprints.libsimprints; -public enum Tier { +enum class Tier { TIER_1, TIER_2, TIER_3, diff --git a/src/main/java/com/simprints/libsimprints/Verification.java b/src/main/java/com/simprints/libsimprints/Verification.java deleted file mode 100644 index d5a188e..0000000 --- a/src/main/java/com/simprints/libsimprints/Verification.java +++ /dev/null @@ -1,91 +0,0 @@ -package com.simprints.libsimprints; - -import android.os.Parcel; -import android.os.Parcelable; - -import androidx.annotation.NonNull; - -@SuppressWarnings({"unused", "WeakerAccess"}) -public class Verification implements Parcelable { - - private int confidence; - private Tier tier; - private String guid; - - - /** - * Empty Constructor - */ - public Verification() { - - } - - /** - * This constructor creates a new verification - * - * @param confidence An int containing the (matching) confidence - * @param tier The tier score derived from the confidence - * @param guid Global unique id of the verified person - */ - public Verification(int confidence, @NonNull Tier tier, @NonNull String guid) { - this.confidence = confidence; - this.tier = tier; - this.guid = guid; - } - - protected Verification(Parcel in) { - confidence = in.readInt(); - tier = Tier.values()[in.readInt()]; - guid = in.readString(); - } - - public static final Creator CREATOR = new Creator() { - @Override - public Verification createFromParcel(Parcel in) { - return new Verification(in); - } - - @Override - public Verification[] newArray(int size) { - return new Verification[size]; - } - }; - - @Override - public int describeContents() { - return 0; - } - - @Override - public void writeToParcel(Parcel dest, int flags) { - dest.writeInt(this.confidence); - dest.writeInt(this.tier.ordinal()); - dest.writeString(guid); - } - - public float getConfidence() { - return confidence; - } - - public void setConfidence(int confidence) { - this.confidence = confidence; - } - - @NonNull - public Tier getTier() { - return tier; - } - - public void setTier(@NonNull Tier tier) { - this.tier = tier; - } - - @NonNull - public String getGuid() { - return guid; - } - - public void setGuid(@NonNull String guid) { - this.guid = guid; - } -} diff --git a/src/main/java/com/simprints/libsimprints/Verification.kt b/src/main/java/com/simprints/libsimprints/Verification.kt new file mode 100644 index 0000000..ab9f1ce --- /dev/null +++ b/src/main/java/com/simprints/libsimprints/Verification.kt @@ -0,0 +1,22 @@ +package com.simprints.libsimprints + +import android.os.Parcelable +import kotlinx.parcelize.Parcelize + +/** + * This constructor creates a new verification + * + * @param confidence An int containing the (matching) confidence + * @param tier The tier score derived from the confidence + * @param guid Global unique id of the verified person + */ +@SuppressWarnings("unused", "WeakerAccess") +@Parcelize +data class Verification( + private val confidence: Int, + val tier: Tier, + val guid: String, +) : Parcelable { + + fun getConfidence(): Float = confidence.toFloat() +} diff --git a/src/androidTest/java/com/simprints/libsimprints/IdentificationTest.java b/src/test/java/com/simprints/libsimprints/IdentificationTest.java similarity index 100% rename from src/androidTest/java/com/simprints/libsimprints/IdentificationTest.java rename to src/test/java/com/simprints/libsimprints/IdentificationTest.java diff --git a/src/androidTest/java/com/simprints/libsimprints/RefusalFormTest.java b/src/test/java/com/simprints/libsimprints/RefusalFormTest.java similarity index 100% rename from src/androidTest/java/com/simprints/libsimprints/RefusalFormTest.java rename to src/test/java/com/simprints/libsimprints/RefusalFormTest.java diff --git a/src/androidTest/java/com/simprints/libsimprints/RegistrationTest.java b/src/test/java/com/simprints/libsimprints/RegistrationTest.java similarity index 95% rename from src/androidTest/java/com/simprints/libsimprints/RegistrationTest.java rename to src/test/java/com/simprints/libsimprints/RegistrationTest.java index 91bd2a5..91b35ab 100644 --- a/src/androidTest/java/com/simprints/libsimprints/RegistrationTest.java +++ b/src/test/java/com/simprints/libsimprints/RegistrationTest.java @@ -26,8 +26,7 @@ public void testRegistrationParcelling() { final byte[] rightIndex = {0}; - Registration exampleRegistration = - new Registration("case-id"); + Registration exampleRegistration = new Registration("case-id"); exampleRegistration.setTemplate(FingerIdentifier.LEFT_THUMB, leftThumb); exampleRegistration.setTemplate(FingerIdentifier.LEFT_INDEX_FINGER, leftIndex); exampleRegistration.setTemplate(FingerIdentifier.LEFT_3RD_FINGER, left3rd); diff --git a/src/test/java/com/simprints/libsimprints/regression/JavaRegressionTests.java b/src/test/java/com/simprints/libsimprints/regression/JavaRegressionTests.java new file mode 100644 index 0000000..e3a0ea5 --- /dev/null +++ b/src/test/java/com/simprints/libsimprints/regression/JavaRegressionTests.java @@ -0,0 +1,275 @@ +package com.simprints.libsimprints.regression; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Parcelable; + +import androidx.annotation.NonNull; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import com.simprints.libsimprints.Constants; +import com.simprints.libsimprints.FingerIdentifier; +import com.simprints.libsimprints.Identification; +import com.simprints.libsimprints.Metadata; +import com.simprints.libsimprints.RefusalForm; +import com.simprints.libsimprints.Registration; +import com.simprints.libsimprints.SimHelper; +import com.simprints.libsimprints.Tier; +import com.simprints.libsimprints.Verification; + +import org.junit.Assert; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; + +/** + * This test class represents the recommended/documented way to integrate LibSimprints within the caller app. + * Contents of this test file MUST NOT change during any refactoring as it would mean + * a breaking change in the API and potential issues if the calling app updates the version. + */ +@RunWith(AndroidJUnit4.class) +public class JavaRegressionTests { + + @Test + public void enrolmentSetUp() { + Intent intent = createSimHelper().register("module-id"); + + Assert.assertEquals(Constants.SIMPRINTS_REGISTER_INTENT, intent.getAction()); + Assert.assertEquals( + new HashSet<>(Arrays.asList( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID + )), + Objects.requireNonNull(intent.getExtras()).keySet() + ); + } + + @Test + public void enrolmentWithMetaDataSetUp() { + Metadata metadata = createMetadata(); + Intent intent = createSimHelper().register("module-id", metadata); + + Assert.assertEquals(Constants.SIMPRINTS_REGISTER_INTENT, intent.getAction()); + Assert.assertEquals( + new HashSet<>(Arrays.asList( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_METADATA + )), + Objects.requireNonNull(intent.getExtras()).keySet() + ); + Assert.assertEquals( + KEY_VALUE_JSON, + intent.getStringExtra(Constants.SIMPRINTS_METADATA) + ); + } + + @Test + public void identificationSetUp() { + Intent intent = createSimHelper().identify("module-id"); + + Assert.assertEquals(Constants.SIMPRINTS_IDENTIFY_INTENT, intent.getAction()); + Assert.assertEquals( + new HashSet<>(Arrays.asList( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID + )), + Objects.requireNonNull(intent.getExtras()).keySet() + ); + } + + @Test + public void identificationDataSetUp() { + Metadata metadata = createMetadata(); + Intent intent = createSimHelper().identify("module-id", metadata); + + Assert.assertEquals(Constants.SIMPRINTS_IDENTIFY_INTENT, intent.getAction()); + Assert.assertEquals( + new HashSet<>(Arrays.asList( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_METADATA + )), + Objects.requireNonNull(intent.getExtras()).keySet() + ); + Assert.assertEquals( + KEY_VALUE_JSON, + intent.getStringExtra(Constants.SIMPRINTS_METADATA) + ); + } + + @Test + public void verificationSetUp() { + Intent intent = createSimHelper().verify("module-id", "guid"); + + Assert.assertEquals(Constants.SIMPRINTS_VERIFY_INTENT, intent.getAction()); + Assert.assertEquals( + new HashSet<>(Arrays.asList( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_VERIFY_GUID + )), + Objects.requireNonNull(intent.getExtras()).keySet() + ); + } + + @Test + public void verificationWithMetaDataSetUp() { + Metadata metadata = createMetadata(); + Intent intent = createSimHelper().verify("module-id", "guid", metadata); + + Assert.assertEquals(Constants.SIMPRINTS_VERIFY_INTENT, intent.getAction()); + Assert.assertEquals( + new HashSet<>(Arrays.asList( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_VERIFY_GUID, + Constants.SIMPRINTS_METADATA + )), + Objects.requireNonNull(intent.getExtras()).keySet() + ); + Assert.assertEquals( + KEY_VALUE_JSON, + intent.getStringExtra(Constants.SIMPRINTS_METADATA) + ); + } + + @Test + public void confirmSetUp() { + Intent intent = createSimHelper().confirmIdentity("module-id", "guid"); + + Assert.assertEquals(Constants.SIMPRINTS_SELECT_GUID_INTENT, intent.getAction()); + Assert.assertEquals( + new HashSet<>(Arrays.asList( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_SESSION_ID, + Constants.SIMPRINTS_SELECTED_GUID + )), + Objects.requireNonNull(intent.getExtras()).keySet() + ); + } + + @Test + public void enrolLastSetUp() { + Intent intent = createSimHelper().registerLastBiometrics("module-id", "session-id"); + + Assert.assertEquals(Constants.SIMPRINTS_REGISTER_LAST_BIOMETRICS_INTENT, intent.getAction()); + Assert.assertEquals( + new HashSet<>(Arrays.asList( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_SESSION_ID + )), + Objects.requireNonNull(intent.getExtras()).keySet() + ); + } + + @Test + public void enrolLastWithMetaDataSetUp() { + Metadata metadata = createMetadata(); + Intent intent = createSimHelper().registerLastBiometrics("module-id", "session-id", metadata); + + Assert.assertEquals(Constants.SIMPRINTS_REGISTER_LAST_BIOMETRICS_INTENT, intent.getAction()); + Assert.assertEquals( + new HashSet<>(Arrays.asList( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_SESSION_ID, + Constants.SIMPRINTS_METADATA + )), + Objects.requireNonNull(intent.getExtras()).keySet() + ); + Assert.assertEquals( + KEY_VALUE_JSON, + intent.getStringExtra(Constants.SIMPRINTS_METADATA) + ); + } + + @Test + public void enrolmentResultHandling() { + Registration registration = new Registration("guid-id"); + registration.setTemplate(FingerIdentifier.LEFT_3RD_FINGER, new byte[]{3, 4, 5}); + registration.setTemplate(FingerIdentifier.RIGHT_3RD_FINGER, new byte[]{1, 2, 3}); + + Intent intent = createIntentWithExtra(Constants.SIMPRINTS_REGISTRATION, registration); + + Registration result = intent.getParcelableExtra(Constants.SIMPRINTS_REGISTRATION); + Assert.assertEquals(registration, result); + Assert.assertEquals("guid-id", registration.getGuid()); + } + + @Test + public void identificationResultHandling() { + Identification identification = new Identification("guid-id", 12, Tier.TIER_1); + ArrayList identificationList = new ArrayList<>(); + identificationList.add(identification); + Intent intent = createIntentWithExtra(Constants.SIMPRINTS_IDENTIFICATIONS, identificationList); + + List result = intent.getParcelableArrayListExtra(Constants.SIMPRINTS_IDENTIFICATIONS); + Assert.assertEquals(identification, Objects.requireNonNull(result).get(0)); + Assert.assertEquals("guid-id", identification.getGuid()); + Assert.assertEquals(12.0, identification.getConfidence(), 0.00001); + Assert.assertEquals(Tier.TIER_1, identification.getTier()); + } + + @Test + public void verificationResultHandling() { + Verification verification = new Verification(42, Tier.TIER_3, "guid-id"); + Intent intent = createIntentWithExtra(Constants.SIMPRINTS_VERIFICATION, verification); + + Verification result = intent.getParcelableExtra(Constants.SIMPRINTS_VERIFICATION); + Assert.assertEquals(verification, result); + Assert.assertEquals("guid-id", verification.getGuid()); + Assert.assertEquals(42.0, verification.getConfidence(), 0.00001); + Assert.assertEquals(Tier.TIER_3, verification.getTier()); + } + + @Test + public void refusalResultHandling() { + RefusalForm refusalForm = new RefusalForm("reason", "extra"); + Intent intent = createIntentWithExtra(Constants.SIMPRINTS_REFUSAL_FORM, refusalForm); + + RefusalForm result = intent.getParcelableExtra(Constants.SIMPRINTS_REFUSAL_FORM); + Assert.assertEquals(refusalForm, result); + Assert.assertEquals("reason", refusalForm.getReason()); + Assert.assertEquals("extra", refusalForm.getExtra()); + } + + private static @NonNull SimHelper createSimHelper() { + return new SimHelper("project-id", "user-id"); + } + + public static final String KEY_VALUE_JSON = "{\"key\":\"value\"}"; + + private static @NonNull Metadata createMetadata() { + Metadata metadata = new Metadata(); + metadata.put("key", "value"); + return metadata; + } + + private static Intent createIntentWithExtra(String key, Parcelable extras) { + Bundle bundle = new Bundle(); + bundle.putParcelable(key, extras); + return new Intent().putExtras(bundle); + } + + private static Intent createIntentWithExtra(String key, ArrayList extras) { + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList(key, extras); + return new Intent().putExtras(bundle); + } +} diff --git a/src/test/java/com/simprints/libsimprints/regression/KotlinRegressionTests.kt b/src/test/java/com/simprints/libsimprints/regression/KotlinRegressionTests.kt new file mode 100644 index 0000000..f15acbb --- /dev/null +++ b/src/test/java/com/simprints/libsimprints/regression/KotlinRegressionTests.kt @@ -0,0 +1,233 @@ +package com.simprints.libsimprints.regression + +import android.content.Intent +import android.os.Bundle +import androidx.test.ext.junit.runners.AndroidJUnit4 +import com.simprints.libsimprints.Constants +import com.simprints.libsimprints.FingerIdentifier +import com.simprints.libsimprints.Identification +import com.simprints.libsimprints.Metadata +import com.simprints.libsimprints.RefusalForm +import com.simprints.libsimprints.Registration +import com.simprints.libsimprints.SimHelper +import com.simprints.libsimprints.Tier +import com.simprints.libsimprints.Verification +import org.junit.Assert.* +import org.junit.Test +import org.junit.runner.RunWith +import kotlin.also +import kotlin.apply + +/** + * This test class represents the recommended/documented way to integrate LibSimprints within the caller app. + * Contents of this test file MUST NOT change during any refactoring as it would mean + * a breaking change in the API and potential issues if the calling app updates the version. + */ +@RunWith(AndroidJUnit4::class) +class KotlinRegressionTests { + + @Test + fun enrolmentSetUp() { + val intent = SimHelper("project-id", "user-id").register("module-id") + + assertEquals(Constants.SIMPRINTS_REGISTER_INTENT, intent.getAction()) + assertEquals( + setOf( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID + ), + intent.getExtras()?.keySet() + ) + } + + @Test + fun enrolmentWithMetaDataSetUp() { + val intent = SimHelper("project-id", "user-id").register("module-id", createMetadata()) + + assertEquals(Constants.SIMPRINTS_REGISTER_INTENT, intent.getAction()) + assertEquals( + setOf( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_METADATA + ), + intent.getExtras()?.keySet() + ) + assertEquals(KEY_VALUE_JSON, intent.getStringExtra(Constants.SIMPRINTS_METADATA)) + } + + @Test + fun identificationSetUp() { + val intent = SimHelper("project-id", "user-id").identify("module-id") + + assertEquals(Constants.SIMPRINTS_IDENTIFY_INTENT, intent.getAction()) + assertEquals( + setOf( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID + ), + intent.getExtras()?.keySet() + ) + } + + @Test + fun identificationWithMetaDataSetUp() { + val intent = SimHelper("project-id", "user-id").identify("module-id", createMetadata()) + + assertEquals(Constants.SIMPRINTS_IDENTIFY_INTENT, intent.getAction()) + assertEquals( + setOf( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_METADATA + ), + intent.getExtras()?.keySet() + ) + assertEquals(KEY_VALUE_JSON, intent.getStringExtra(Constants.SIMPRINTS_METADATA)) + } + + @Test + fun verificationSetUp() { + val intent = SimHelper("project-id", "user-id").verify("module-id", "guid") + + assertEquals(Constants.SIMPRINTS_VERIFY_INTENT, intent.getAction()) + assertEquals( + setOf( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_VERIFY_GUID, + ), + intent.getExtras()?.keySet() + ) + } + + @Test + fun verificationWithMetaDataSetUp() { + val intent = SimHelper("project-id", "user-id") + .verify("module-id", "guid", createMetadata()) + + assertEquals(Constants.SIMPRINTS_VERIFY_INTENT, intent.getAction()) + assertEquals( + setOf( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_VERIFY_GUID, + Constants.SIMPRINTS_METADATA + ), + intent.getExtras()?.keySet() + ) + assertEquals(KEY_VALUE_JSON, intent.getStringExtra(Constants.SIMPRINTS_METADATA)) + } + + @Test + fun confirmSetUp() { + val intent = SimHelper("project-id", "user-id").confirmIdentity("module-id", "guid") + + assertEquals(Constants.SIMPRINTS_SELECT_GUID_INTENT, intent.getAction()) + assertEquals( + setOf( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_SESSION_ID, + Constants.SIMPRINTS_SELECTED_GUID + ), + intent.getExtras()?.keySet() + ) + } + + @Test + fun enrolLastSetUp() { + val intent = SimHelper("project-id", "user-id").registerLastBiometrics("module-id", "guid") + + assertEquals(Constants.SIMPRINTS_REGISTER_LAST_BIOMETRICS_INTENT, intent.getAction()) + assertEquals( + setOf( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_SESSION_ID + ), + intent.getExtras()?.keySet() + ) + } + + @Test + fun enrolLastWithMetaDataSetUp() { + val intent = SimHelper("project-id", "user-id") + .registerLastBiometrics("module-id", "guid", createMetadata()) + + assertEquals(Constants.SIMPRINTS_REGISTER_LAST_BIOMETRICS_INTENT, intent.getAction()) + assertEquals( + setOf( + Constants.SIMPRINTS_PROJECT_ID, + Constants.SIMPRINTS_USER_ID, + Constants.SIMPRINTS_MODULE_ID, + Constants.SIMPRINTS_SESSION_ID, + Constants.SIMPRINTS_METADATA, + ), + intent.getExtras()?.keySet() + ) + assertEquals(KEY_VALUE_JSON, intent.getStringExtra(Constants.SIMPRINTS_METADATA)) + } + + @Test + fun enrolmentResultHandling() { + val registration = Registration("case-id").apply { + setTemplate(FingerIdentifier.LEFT_3RD_FINGER, byteArrayOf(1, 2, 3)) + setTemplate(FingerIdentifier.RIGHT_3RD_FINGER, byteArrayOf(4, 5, 6)) + } + val intent = Intent().putExtras(Bundle().apply { + putParcelable(Constants.SIMPRINTS_REGISTRATION, registration) + }) + + val result = intent.getParcelableExtra(Constants.SIMPRINTS_REGISTRATION) + assertEquals(registration, result) + } + + @Test + fun identificationResultHandling() { + val identification = Identification("case-id", 12, Tier.TIER_1) + val intent = Intent().putExtras(Bundle().apply { + putParcelableArrayList(Constants.SIMPRINTS_IDENTIFICATIONS, arrayListOf(identification)) + }) + + val result = + intent.getParcelableArrayListExtra(Constants.SIMPRINTS_IDENTIFICATIONS) + assertEquals(identification, result?.get(0)) + } + + @Test + fun verificationResultHandling() { + val verification = Verification(42, Tier.TIER_3, "case-id") + val intent = Intent().putExtras(Bundle().apply { + putParcelable(Constants.SIMPRINTS_VERIFICATION, verification) + }) + + val result = + intent.getParcelableExtra(Constants.SIMPRINTS_VERIFICATION) + assertEquals(verification, result) + } + + @Test + fun refusalResultHandling() { + val refusalForm = RefusalForm("reason", "extra") + val intent = Intent().putExtras(Bundle().apply { + putParcelable(Constants.SIMPRINTS_REFUSAL_FORM, refusalForm) + }) + + val result = intent.getParcelableExtra(Constants.SIMPRINTS_REFUSAL_FORM) + assertEquals(refusalForm, result) + } + + private fun createMetadata(): Metadata = Metadata().also { it.put("key", "value") } + + companion object { + private const val KEY_VALUE_JSON = """{"key":"value"}""" + } +}