<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.biometrid</groupId>
  <artifactId>biometridfull</artifactId>
  <version>3.1.2</version>
  <packaging>aar</packaging>
  <name>BiometridFull</name>
  <description><![CDATA[
# BiometridFull - Android Integration Guide

## Overview

BiometridFull is a comprehensive identity verification SDK that provides a complete, WebView-based verification flow. It integrates all BiometridStandard modules (Liveness, NFC, AutoCapture) into a single, unified interface. The SDK manages the entire verification process through a web interface while leveraging native device capabilities for biometric operations.

## Prerequisites

- Android API Level 26+ (Android 8.0)
- Kotlin 2.2.0+
- AndroidX AppCompat
- Camera, Microphone and NFC permissions declared in `AndroidManifest.xml`

## Installation

### 1. Add Repositories

Add the following repositories to your project-level `build.gradle.kts` (or `settings.gradle.kts`):

```kotlin
repositories {
    google()
    mavenCentral()
    maven { url = uri("https://dl.cloudsmith.io/public/biometrid/mobile/maven/") }
    maven { url = uri("https://dl.cloudsmith.io/public/biometrid/mobile-test/maven/") }
    maven { url = uri("https://dl.cloudsmith.io/public/biometrid/face01-liveness/maven/") }
    maven { url = uri("https://maven.innovatrics.com/releases") }
    maven { url = uri("https://raw.githubusercontent.com/iProov/android/master/maven/") }
    maven { url = uri("https://maven.regulaforensics.com/RegulaDocumentReader/") }
    maven { url = uri("https://jitpack.io") }
}
```

### 2. Add Dependency

Add the BiometridFull dependency to your app's `build.gradle.kts`:

```kotlin
dependencies {
    implementation("com.biometrid:biometridfull:3.1.2")
}
```

### 3. Required Permissions

Add the following permissions to your `AndroidManifest.xml`:

```xml
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />

<uses-feature android:name="android.hardware.nfc" android:required="false" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-feature android:name="android.hardware.camera.front" android:required="false" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
```

### 4. Register Required Activities

The SDK uses internal activities that must be declared in your `AndroidManifest.xml` inside the `<application>` tag:

```xml
<activity
    android:name="com.biometrid.biometridfull.ui.BiometridFullComposeActivity"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"
    android:exported="false" />
<activity
    android:name="com.biometrid.autocapture.screens.ml.CameraActivity"
    android:exported="false" />
<activity
    android:name="com.biometrid.autocapture.screens.simple.SimpleCameraActivity"
    android:exported="false" />
<activity
    android:name="com.biometrid.biometridfull.webview.AndroidWebViewActivity"
    android:theme="@style/Theme.AppCompat.Light.NoActionBar"
    android:exported="false" />
<activity
    android:name="com.biometrid.biometridstandardnfc.activity.BiometridNFCActivity"
    android:exported="false" />
```

## Initialization

```kotlin
import com.biometrid.biometridfull.BiometridFull
import com.biometrid.biometridfull.callbacks.BiometridFullCallback
import com.biometrid.biometridfull.helpers.ScreenType
import com.biometrid.biometridstandard.enums.Language
import com.biometrid.biometridstandard.model.BiometridErrorInfo

// 1. Create your callback implementation
val callback = object : BiometridFullCallback {
    override val url: String = "your-url"
    override val app: String = "your-app-id"
    override val appUrl: String = "your-app-url"
    override val credential: String = "your-credential"
    override val language: Language = Language.English
    override val customHeaders: Map<Any?, *>? = null

    override fun initialized(status: Boolean, error: BiometridErrorInfo?) {
        // Handle initialization result
    }

    override fun processCreated(processId: String) {
        // Handle process creation
    }

    override fun processUpdated(processId: String, stepId: String, action: String) {
        // Handle step update — process moved to the next step
    }

    override fun processFinished(processId: String) {
        // Handle process completion
    }

    override fun error(status: Boolean, error: BiometridErrorInfo) {
        // Handle errors
    }
}

// 2. Create the BiometridFull instance
val biometridFull = BiometridFull(callback)
```

## Available Methods

### `initialize()`

Initializes the SDK by connecting to the Biometrid backend and preparing all required services.

```kotlin
suspend fun initialize()
```

This method must be called before `start()`. It performs backend authentication using the provided `url`, `app`, and `credential` from the callback. The result is delivered through the `initialized` callback.

---

### `start(processId, screenType)`

Starts the identity verification process and presents the WebView interface.

```kotlin
suspend fun start(processId: String?, screenType: ScreenType)
```

| Parameter | Type | Description |
|-----------|------|-------------|
| `processId` | `String?` | Optional process ID. Pass `null` to create a new process, or provide an existing ID to resume. |
| `screenType` | `ScreenType` | Platform-specific screen context. On Android, wrap the current `Context`. |

---

### `stop()`

Stops the current verification process and cleans up all resources.

```kotlin
fun stop()
```

Stops any active WebView sessions, cancels pending native operations (Liveness, NFC, AutoCapture), and releases associated resources. Safe to call at any point.

## Callback Interface

### **BiometridFullCallback**

The callback interface that must be implemented to receive SDK lifecycle events and provide configuration.

#### Properties

| Property | Type | Description |
|----------|------|-------------|
| `url` | `String` | The Biometrid API base URL (e.g., `https://api.biometrid.com/`) |
| `app` | `String` | Your application identifier provided by Biometrid |
| `appUrl` | `String` | The Biometrid web application URL (e.g., `https://app.biometrid.com/`) |
| `credential` | `String` | Your credential key provided by Biometrid |
| `language` | `Language` | The language for the verification interface |
| `customHeaders` | `Map<Any?, *>?` | Optional custom HTTP headers to include in API requests |

#### Methods

| Method | Description |
|--------|-------------|
| `initialized(status: Boolean, error: BiometridErrorInfo?)` | Called when SDK initialization completes. `status` is `true` on success. |
| `processCreated(processId: String)` | Called when a new verification process is created. Returns the process ID. |
| `processUpdated(processId: String, stepId: String, action: String)` | Called when a step is successfully updated and the process moves to the next step. Returns the completed step's ID and action type. |
| `processFinished(processId: String)` | Called when the verification process completes successfully. Returns the process ID. |
| `error(status: Boolean, error: BiometridErrorInfo)` | Called when an error occurs during the verification process. |

## Data Models

### **BiometridErrorInfo**

```kotlin
data class BiometridErrorInfo(
    val code: String? = null,
    val message: String? = null,
    val data: JsonElement? = null
)
```

| Property | Type | Description |
|----------|------|-------------|
| `code` | `String?` | Error code identifier (e.g., `"MBF001"`) |
| `message` | `String?` | Human-readable error description |
| `data` | `JsonElement?` | Optional additional error data |

---

### **ScreenType**

Platform-specific screen context wrapper used to present the verification interface.

```kotlin
// Android
class ScreenType(val context: Context)
```

| Property | Type | Description |
|----------|------|-------------|
| `context` | `Context` | The Android Context (typically an Activity) used to present the WebView |

## Enums

### **Language**

```kotlin
enum class Language(val value: String) {
    English("en-GB"),
    Portuguese("pt-PT"),
    French("fr-FR"),
    Spanish("es-ES"),
    Italian("it-IT")
}
```

## Error Handling

Errors are delivered through the `error` method of `BiometridFullCallback`. Each error includes a `BiometridErrorInfo` object with a code and descriptive message.

Error codes follow the prefix convention:
- `MBF` - BiometridFull module errors

Handle errors in the callback:

```kotlin
override fun error(status: Boolean, error: BiometridErrorInfo) {
    val errorCode = error.code ?: "Unknown"
    val errorMessage = error.message ?: "An unknown error occurred"
    // Handle or display the error
}
```

## Usage Example

### ViewModel Integration

```kotlin
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.biometrid.biometridfull.BiometridFull
import com.biometrid.biometridfull.callbacks.BiometridFullCallback
import com.biometrid.biometridfull.helpers.ScreenType
import com.biometrid.biometridstandard.enums.Language
import com.biometrid.biometridstandard.model.BiometridErrorInfo
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch

class BiometridFullVM : ViewModel() {

    private val _isInitialized = MutableStateFlow(false)
    val isInitialized: StateFlow<Boolean> = _isInitialized

    private val _error = MutableStateFlow<String?>(null)
    val error: StateFlow<String?> = _error

    private val _isProcessCompleted = MutableStateFlow(false)
    val isProcessCompleted: StateFlow<Boolean> = _isProcessCompleted

    private val biometridFull = BiometridFull(object : BiometridFullCallback {
        override val url = "your-url"
        override val app = "your-app-id"
        override val appUrl = "your-app-url"
        override val credential = "your-credential"
        override val language = Language.English
        override val customHeaders: Map<Any?, *>? = null

        override fun initialized(status: Boolean, error: BiometridErrorInfo?) {
            _isInitialized.value = status
            error?.let { _error.value = it.message }
        }

        override fun processCreated(processId: String) {
            // Store processId if needed
        }

        override fun processUpdated(processId: String, stepId: String, action: String) {
            // Step updated, process moved to next step
        }

        override fun processFinished(processId: String) {
            _isProcessCompleted.value = true
        }

        override fun error(status: Boolean, error: BiometridErrorInfo) {
            _error.value = error.message
        }
    })

    fun initialize() {
        viewModelScope.launch {
            biometridFull.initialize()
        }
    }

    fun start(context: android.content.Context) {
        viewModelScope.launch {
            biometridFull.start(
                processId = null,
                screenType = ScreenType(context)
            )
        }
    }

    fun stop() {
        biometridFull.stop()
    }

    override fun onCleared() {
        super.onCleared()
        biometridFull.stop()
    }
}
```

### Activity Usage

```kotlin
class MainActivity : AppCompatActivity() {

    private val viewModel: BiometridFullVM by viewModels()

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Observe state
        lifecycleScope.launch {
            viewModel.isInitialized.collect { initialized ->
                if (initialized) {
                    // SDK is ready, enable start button
                }
            }
        }

        lifecycleScope.launch {
            viewModel.error.collect { error ->
                error?.let {
                    // Show error to user
                }
            }
        }

        lifecycleScope.launch {
            viewModel.isProcessCompleted.collect { completed ->
                if (completed) {
                    // Verification process completed
                }
            }
        }

        // Initialize the SDK
        viewModel.initialize()

        // Start verification when ready (e.g., on button click)
        startButton.setOnClickListener {
            viewModel.start(this)
        }
    }

    override fun onDestroy() {
        super.onDestroy()
        viewModel.stop()
    }
}
```

]]></description>
  <url>https://biometrid.com</url>
  <dependencies>
    <dependency>
      <groupId>io.ktor</groupId>
      <artifactId>ktor-client-android</artifactId>
      <version>2.3.7</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.ktor</groupId>
      <artifactId>ktor-client-okhttp</artifactId>
      <version>2.3.7</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.ktor</groupId>
      <artifactId>ktor-client-core</artifactId>
      <version>2.3.7</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.ktor</groupId>
      <artifactId>ktor-client-content-negotiation</artifactId>
      <version>2.3.7</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.ktor</groupId>
      <artifactId>ktor-serialization-kotlinx-json</artifactId>
      <version>2.3.7</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.ktor</groupId>
      <artifactId>ktor-client-websockets</artifactId>
      <version>2.3.7</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.socket</groupId>
      <artifactId>socket.io-client</artifactId>
      <version>2.0.1</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>dev.icerock.moko</groupId>
      <artifactId>socket-io</artifactId>
      <version>0.6.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.lifecycle</groupId>
      <artifactId>lifecycle-viewmodel-compose</artifactId>
      <version>2.6.2</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.security</groupId>
      <artifactId>security-crypto</artifactId>
      <version>1.1.0-alpha06</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.webkit</groupId>
      <artifactId>webkit</artifactId>
      <version>1.8.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.activity</groupId>
      <artifactId>activity-compose</artifactId>
      <version>1.9.3</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.compose.ui</groupId>
      <artifactId>ui-android</artifactId>
      <version>1.7.8</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.appcompat</groupId>
      <artifactId>appcompat</artifactId>
      <version>1.7.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.compose.material3</groupId>
      <artifactId>material3-android</artifactId>
      <version>1.3.2</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.compose.components</groupId>
      <artifactId>components-resources</artifactId>
      <version>1.8.2</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlinx</groupId>
      <artifactId>kotlinx-datetime</artifactId>
      <version>0.6.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlinx</groupId>
      <artifactId>kotlinx-coroutines-core</artifactId>
      <version>1.8.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>org.jetbrains.kotlinx</groupId>
      <artifactId>kotlinx-coroutines-android</artifactId>
      <version>1.8.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>com.russhwolf</groupId>
      <artifactId>multiplatform-settings</artifactId>
      <version>1.1.1</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>com.russhwolf</groupId>
      <artifactId>multiplatform-settings-coroutines</artifactId>
      <version>1.1.1</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.coil-kt</groupId>
      <artifactId>coil-compose</artifactId>
      <version>2.4.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.coil-kt</groupId>
      <artifactId>coil-svg</artifactId>
      <version>2.4.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>com.biometrid.face01</groupId>
      <artifactId>biometrid-android-active-liveness</artifactId>
      <version>9.7.110</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>com.iproov.sdk</groupId>
      <artifactId>iproov</artifactId>
      <version>11.0.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>org.tensorflow</groupId>
      <artifactId>tensorflow-lite</artifactId>
      <version>2.14.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>com.microsoft.onnxruntime</groupId>
      <artifactId>onnxruntime-android</artifactId>
      <version>1.23.2</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.camera</groupId>
      <artifactId>camera-core</artifactId>
      <version>1.4.2</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.camera</groupId>
      <artifactId>camera-camera2</artifactId>
      <version>1.4.2</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.camera</groupId>
      <artifactId>camera-lifecycle</artifactId>
      <version>1.4.2</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.camera</groupId>
      <artifactId>camera-view</artifactId>
      <version>1.4.2</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.exifinterface</groupId>
      <artifactId>exifinterface</artifactId>
      <version>1.3.7</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>androidx.concurrent</groupId>
      <artifactId>concurrent-futures</artifactId>
      <version>1.2.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>com.innovatrics.dot</groupId>
      <artifactId>dot-nfc</artifactId>
      <version>8.15.1</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>com.innovatrics.dot</groupId>
      <artifactId>dot-document</artifactId>
      <version>8.15.1</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.dyte</groupId>
      <artifactId>core-android</artifactId>
      <version>2.1.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.livekit</groupId>
      <artifactId>livekit-android</artifactId>
      <version>2.11.1</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>com.google.mediapipe</groupId>
      <artifactId>tasks-vision</artifactId>
      <version>0.20230731</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>io.sentry</groupId>
      <artifactId>sentry-kotlin-multiplatform</artifactId>
      <version>0.12.0</version>
      <scope>implementation</scope>
    </dependency>
    <dependency>
      <groupId>com.regula.documentreader.core</groupId>
      <artifactId>mrzrfid</artifactId>
      <version>7.7.+</version>
      <type>aar</type>
      <scope>compile</scope>
    </dependency>
    <dependency>
      <groupId>com.regula.documentreader</groupId>
      <artifactId>api</artifactId>
      <version>7.7.+</version>
      <type>aar</type>
      <scope>compile</scope>
    </dependency>
  </dependencies>
  <repositories>
    <repository>
      <id>biometrid-face01-liveness</id>
      <url>https://dl.cloudsmith.io/public/biometrid/face01-liveness/maven/</url>
    </repository>
    <repository>
      <id>iproov</id>
      <url>https://raw.githubusercontent.com/iProov/android/master/maven/</url>
    </repository>
    <repository>
      <id>regula-document-reader</id>
      <url>https://maven.regulaforensics.com/RegulaDocumentReader</url>
    </repository>
    <repository>
      <id>innovatrics</id>
      <url>https://maven.innovatrics.com/releases</url>
    </repository>
  </repositories>
</project>
