> For the complete documentation index, see [llms.txt](https://docs.caf.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.caf.io/caf-sdk/caf-sdk-pt-br/android/getting-started-with-the-sdk-1.md).

# Introdução legada ao SDK

{% hint style="warning" %}
A versão 7.14.0 traz uma forma opcional e mais rápida de inicializar o SDK com menos linhas de código. Junto com essa atualização de código, lançamos uma nova página de documentação, mais fácil de ler. Para adotar essa nova configuração, [confira o guia atualizado](/caf-sdk/caf-sdk-pt-br/android/installation-guide.md).
{% endhint %}

## Sobre o CafSDK

Esta documentação técnica cobre a **implementação do CafSDK para Android**, detalhando a configuração, a inicialização, a execução dos fluxos de captura e as personalizações avançadas.

Atualmente, o CafSDK integra vários módulos: **Face Liveness (FL)**, **Document Detector (DD)** executados sequencialmente com uma interface de configuração unificada. As versões recentes incluem recursos de segurança aprimorados, melhor desempenho, melhor tratamento de erros e personalização de upload aprimorada.

### O que é Face Liveness

É o módulo que valida a autenticidade de um rosto capturado por uma câmera, garantindo que a imagem corresponda a uma pessoa real.

**Características técnicas:**

* `caffaceliveness` é a base compartilhada. Você deve declarar **pelo menos um** **`caffaceliveness-providers-*`** artefato dos provedores de liveness que seu produto usa (**iProov**, **PayFace**, **FaceTec**, …). **`caffaceliveness-ui`** é **opcional** e adiciona **a interface de Face Liveness da Caf** mais **personalização** hooks; omita-o se seu app controlar toda a interface.
* Configuração de URL para autenticação (`authBaseUrl`) e verificação de liveness (`livenessBaseUrl`).
* Endereços de proxy reverso e certificados de segurança (opcional).
* Flags para habilitar captura de tela e modo de depuração.
* Suporte a vários provedores de liveness quando você declara as dependências correspondentes.

### O que é Document Detector

É o módulo que permite a captura e o processamento de documentos (por exemplo, RG, cartão do SUS, passaporte etc.).

**Características técnicas:**

* Configuração de um fluxo passo a passo definido por `DocumentDetectorStep` para captura de documentos.
* Parâmetros operacionais, como timeout, flags de captura manual e outras configurações.
* Possibilidade de usar a câmera para validações de enquadramento ou upload de arquivo de documento.

***

## Comece a usar o SDK

### Adicionar a dependência

Para que seu projeto Android utilize o CafSDK, é necessário configurar corretamente os repositórios Maven e declarar as dependências do SDK no seu projeto. Esta etapa garante que os artefatos (bibliotecas) sejam baixados e integrados durante a compilação.

### Requisitos para adicionar

Os requisitos mínimos para todos os módulos do CafSDK incluem:

| Requisito                                           | Versão |
| --------------------------------------------------- | ------ |
| Android SDK API - versão mínima (minSdk)            | 26     |
| Android SDK API - versão de compilação (compileSDK) | 36     |
| Kotlin                                              | 1.9.10 |
| Gradle                                              | 8.4    |
| Android Gradle Plugin (AGP)                         | 8.3.2  |

{% hint style="warning" %}
`versionName` e `versionCode` são obrigatórios para o funcionamento correto do SDK.
{% endhint %}

**Requisitos específicos do módulo**

* Compatível com **iProov**, **PayFace**e **FaceTec 2D** como dependências explícitas do provedor de liveness (veja [Etapa 2 - Inclua a dependência do CafSDK](#step-2-include-the-cafsdk-dependency))
* Baseado em TensorFlow Lite para processamento de documentos
* Suporta vários tipos de documentos e fluxos de captura
* Inclui algoritmos avançados de validação de qualidade
* Recursos aprimorados de personalização de upload
* Mecanismo de repetição aprimorado com melhor feedback ao usuário
* Recursos de segurança aprimorados
* Gerenciamento de instâncias aprimorado para evitar travamentos

### Passo a passo para adicionar

### Etapa 1 - Adicione o repositório Maven

Nesta etapa, você precisa informar ao Gradle onde localizar os artefatos do CafSDK e dependências adicionais que possam ser usadas (como as relacionadas ao Caf Face Liveness, DocumentDetector ou FingerPrintJS).

Para isso, configure o arquivo settings.gradle.kts do projeto (normalmente localizado na raiz), incluindo os seguintes repositórios:

* **Repositório Caf:** onde os artefatos do CafSDK estão hospedados.
* **Repositório iProov:** necessário apenas se você incluir o **iProov** provedor de liveness (`caffaceliveness-providers-iproov-lite` ou `caffaceliveness-providers-iproov-full`).
* **Repositório FingerPrintJS:** dependência interna dos módulos.
* **JitPack:** para dependências hospedadas via JitPack (GitHub).
* **Repositório Fortface:** necessário apenas se você incluir o **PayFace** provedor de liveness (`caffaceliveness-providers-payface`).

**Exemplo de configuração:**

```kotlin
repositories {
    // Repositório Caf
    maven { url = uri("https://repo.combateafraude.com/android/release") }
    
    // Repositório iProov
    maven { url = uri("https://raw.githubusercontent.com/iProov/android/master/maven/") }
    
    // Repositório FingerPrintJS
    maven { setUrl("https://maven.fpregistry.io/releases") }
    
    // JitPack
    maven { setUrl("https://jitpack.io") }

    // Repositório Fortface - necessário para usar o provedor PayFace
    maven {
        url = uri("https://cdn-fortface-sdk.fortface.com.br")
        credentials(HttpHeaderCredentials::class) {
            name = "X-Sdk"
            value = "CAF"
        }
        authentication {
            create<HttpHeaderAuthentication>("header")
        }
    }
    
}
```

#### Mais detalhes

* **Flexibilidade:** esta configuração permite que o projeto baixe todas as dependências necessárias de diferentes fontes, garantindo compatibilidade e versões atualizadas.
* **Manutenção:** se houver atualizações nos repositórios ou mudanças na estrutura de publicação, basta atualizar esta seção para refletir as novas URLs.
* **Contexto:** a inclusão dos repositórios é feita apenas uma vez no nível do projeto, garantindo que todos os módulos possam acessar os artefatos necessários.

### Etapa 2 - Inclua a dependência do CafSDK <a href="#step-2-include-the-cafsdk-dependency" id="step-2-include-the-cafsdk-dependency"></a>

Depois de configurar os repositórios, é necessário declarar as dependências específicas do CafSDK no arquivo build.gradle.kts do módulo da sua aplicação. Esta etapa declara quais módulos do SDK serão usados, permitindo que o Gradle gerencie versões e resolva as dependências corretamente.

**Exemplo de declaração de dependências:**

```kotlin
dependencies {
    implementation(platform("io.caf.sdk:caf-sdk-bom:7.19.0"))

    // Face Liveness — módulo base (obrigatório ao usar Face Liveness)
    implementation("io.caf.sdk:caffaceliveness")
    // caffaceliveness-ui opcional: telas de Face Liveness da Caf + APIs de personalização da UI; omita para uma UI totalmente personalizada
    implementation("io.caf.sdk:caffaceliveness-ui")

    // caffaceliveness-providers-* — obrigatório: pelo menos um artefato de provedor para sua integração
    implementation("io.caf.sdk:caffaceliveness-providers-iproov-lite")   // iProov + Protobuf JavaLite
    // implementation("io.caf.sdk:caffaceliveness-providers-iproov-full") // iProov + Protobuf Java (completo)
    // implementation("io.caf.sdk:caffaceliveness-providers-payface")
    // implementation("io.caf.sdk:caffaceliveness-providers-facetec")

    // Document Detector
    implementation("io.caf.sdk:document-detector") // ou "io.caf.sdk:document-detector-ui" para a UI da Caf
}
```

**iProov e Protobuf**

* Use `caffaceliveness-providers-iproov-lite` quando seu app padronizar em **Protobuf JavaLite** (padrão típico para menor footprint).
* Use `caffaceliveness-providers-iproov-full` quando você precisar usar **Protobuf Java** (completo) junto com o iProov.

Você pode combinar **vários provedores** no mesmo app declarando mais de uma `caffaceliveness-providers-*` dependência, se sua integração exigir isso.

{% hint style="warning" %}
Se o seu projeto usa o provedor Payface (caffaceliveness-providers-payface), você deve usar a versão lite do iProov: implementation("io.caf.sdk:caffaceliveness-providers-iproov-lite") Isso acontece porque o Payface é construído usando Protobuf JavaLite. Misturá-lo com a versão "completa" do iProov causará conflitos de dependência durante o processo de compilação.
{% endhint %}

**Importante**

**Caf BoM (Lista de Materiais)**

Usar o BoM ajuda a centralizar o gerenciamento de versões de todos os módulos do CafSDK. Assim, todas as dependências relacionadas ao SDK usarão a mesma versão definida, evitando conflitos e facilitando atualizações.

**Módulos de captura**

* **Caf Face Liveness:** sempre declare **`caffaceliveness`** (base compartilhada) e **pelo menos um** **`caffaceliveness-providers-*`** o módulo para os provedores usados pela sua integração. **`caffaceliveness`** e uma dependência do provedor são ambos **obrigatórios**; a base não inclui os SDKs dos fornecedores por padrão. **`caffaceliveness-ui`** é **opcional**: ele adiciona **a interface de Face Liveness da Caf** e **personalização** hooks; omita-o para um fluxo totalmente personalizado ou sem interface.
* **Caf Document Detector:** escolha o módulo padrão ou o com a UI da Caf (`document-detector-ui`), de acordo com suas necessidades de UX.

### Problemas conhecidos

#### Conflitos de classes duplicadas com TensorFlow Lite ou LiteRT

Se sua aplicação usa outros SDKs que incluem dependências de TensorFlow Lite ou LiteRT (como ML Kit, Firebase ML ou outros SDKs baseados em ML), você pode encontrar `classe duplicada` erros durante a compilação.

**Solução:**

Exclua as dependências conflitantes do módulo Document Detector adicionando a seguinte configuração ao seu `build.gradle.kts`:

```kotlin
dependencies {
    implementation(platform("io.caf.sdk:caf-sdk-bom:7.0.0"))
    implementation("io.caf.sdk:document-detector") {
        exclude(group = "com.google.ai.edge.litert", module = "litert-support")
        exclude(group = "com.google.ai.edge.litert", module = "litert")
    }
}
```

**Observação:** Esta solução é recomendada quando você usa outros SDKs que já fornecem essas dependências no seu projeto.

**Verificação de versão**

Sempre verifique a versão mais recente do CafSDK nas [notas de versão](#release-notes) para garantir que você esteja usando as versões mais atualizadas e compatíveis.

**Versões atuais dos módulos**

A seguir estão as versões atuais dos módulos independentes:

| Módulo | Versão atual | Descrição                     |
| ------ | ------------ | ----------------------------- |
| CafSDK | 7.10.0       | Módulo unificado de validação |

Esta configuração garante que seu projeto esteja preparado para integrar o CafSDK, assegurando que todos os artefatos necessários sejam localizados e incorporados durante a compilação. Se houver alterações nos repositórios ou novas dependências forem introduzidas, atualize as configurações.

***

## Como inicializar o SDK

### Permissões

Para que os módulos funcionem corretamente, algumas permissões precisam ser declaradas no **AndroidManifest.xml** arquivo, confira:

**Para Face Liveness**

| Permissão                     | Descrição                                                                               | Necessidade |
| ----------------------------- | --------------------------------------------------------------------------------------- | ----------- |
| `android.permission.CAMERA`   | Permite acesso à câmera para capturar imagens e realizar verificação facial (liveness). | Obrigatória |
| `android.permission.INTERNET` | Permite comunicação com serviços de autenticação e verificação (HTTPS/WSS).             | Obrigatória |

**Para Document Detector**

| Permissão                                  | Descrição                                                                                       | Necessidade          |
| ------------------------------------------ | ----------------------------------------------------------------------------------------------- | -------------------- |
| `android.permission.CAMERA`                | Permite acesso à câmera para capturar imagens de documentos.                                    | Somente para captura |
| `android.permission.INTERNET`              | Permite que as imagens capturadas sejam enviadas aos servidores para processamento e validação. | Obrigatória          |
| `android.permission.READ_EXTERNAL_STORAGE` | Permite acesso a arquivos e imagens armazenados para processamento, se necessário.              | Somente para upload  |

### Configurações

É necessário configurar o SDK para que ele entenda o fluxo de execução e os parâmetros específicos de cada módulo. O processo de inicialização é dividido em duas partes: configuração global e configuração específica do módulo.

**Configuração global**

Nesta etapa, você cria um objeto do tipo `CafSdkConfiguration`, que serve como um contêiner central para todas as configurações do fluxo de captura.

1. **Ordem de apresentação dos módulos (presentationOrder):**

* Defina a sequência em que os módulos serão executados. Essa ordem é crucial para garantir que o fluxo de captura siga a lógica de negócio definida pelo seu projeto.
* Por exemplo, se o fluxo exigir que o documento seja capturado antes da verificação de liveness, a ordem deve colocar o **módulo Document Detector** antes do **Face Liveness**.
* Importante: dependendo da implementação, pode haver variações nos nomes, como `CafModuleType.FACE_LIVENESS` ou `CafModuleType.FACE_LIVENESS_UI`, que indicam se será usada uma versão sem interface ou uma versão com interface.

2. **Módulo de segurança (enableSecurityModule):**

* Ativa ou desativa o módulo de segurança. Opcional, o padrão é `true`.

**Exemplo de código para criar a configuração global:**

```kotlin
val sdkConfiguration = CafSdkConfiguration(
    presentationOrder = listOf(
        CafModuleType.FACE_LIVENESS,     // ou CafModuleType.FACE_LIVENESS_UI
        CafModuleType.DOCUMENT_DETECTOR, // ou CafModuleType.DOCUMENT_DETECTOR
    ),
    enableSecurityModule = true,        // Opcional, o padrão é true
    waitForAllServices = true            // Opcional, o padrão é true
)
```

**Configuração específica do módulo**

Depois de definir as configurações globais, é necessário configurar os módulos individualmente. Essa configuração específica permite ajustar parâmetros operacionais específicos, garantindo que eles se comportem de acordo com os requisitos do seu fluxo de captura.

**Configuração do Document Detector**

O **módulo Document Detector** é responsável pela captura e processamento de documentos. Sua configuração envolve vários parâmetros.

**Parâmetro obrigatório:**

* **Fluxo de captura (flow):**
  * Define uma lista de etapas ([`DocumentDetectorStep`](#documentdetectorstep)) que especifica qual documento será capturado.
  * Esse fluxo pode ser personalizado de acordo com os tipos de documentos que serão validados pela aplicação.

**Parâmetros operacionais:**

* `useAdb`, `useDebug`e `useDeveloperMode` são flags que ativam modos específicos para testes e desenvolvimento, permitindo maior flexibilidade durante a fase de integração.
* `manualCaptureEnabled` e `manualCaptureTime` controlam se a captura manual é permitida e, se for, definem o limite de tempo (em segundos) para o usuário executar a ação manualmente.
* `requestTimeout` define o tempo máximo (em segundos) que o sistema aguardará por uma resposta do servidor.
* `showPopup` determina se um pop-up de confirmação ou instrução será exibido ao usuário após a captura do documento.

**Exemplo de código para a configuração do Document Detector:**

```kotlin
sdkConfiguration.setDocumentDetectorConfig(
    CafDocumentDetectorConfig(
        flow = listOf(DocumentDetectorStep(Document.RG_FRONT), DocumentDetectorStep(Document.RG_BACK)),
        useAdb = true,
        useDebug = true,
        useDeveloperMode = true,
        manualCaptureEnabled = true,
        manualCaptureTime = 45,
        requestTimeout = 60,
        showPopup = true
    )
)
```

**Configuração de Face Liveness**

A configuração do módulo Face Liveness é essencial para garantir a segurança e a confiabilidade do processo de verificação facial, pois ele tem a função de validar se o rosto capturado pertence a uma pessoa real. Os principais parâmetros são:

* **Carregamento (tela de carregamento):**
  * O `loading` flag define se uma tela de carregamento deve ser exibida enquanto o módulo realiza o processamento. Isso melhora a experiência do usuário, informando que o processo está em andamento.
* **Configuração de proxy reverso**
  * `authBaseUrl` e `livenessBaseUrl` são endpoints opcionais para os serviços de autenticação e verificação de liveness, respectivamente.
  * Uma vez configurados, esses valores devem ser definidos com URLs válidas, onde `authBaseUrl` normalmente usa o protocolo HTTPS por segurança, e `livenessBaseUrl` usa WSS (WebSocket seguro).
  * **Certificados:**
    * Ao atribuir valores às URLs dos serviços, também é necessário fornecer a `lista de certificados` e garantir comunicações seguras com servidores confiáveis (ao usar proxy reverso).
* **Opções adicionais:**
  * `screenCaptureEnabled` ativa ou desativa a capacidade de capturar a tela durante o processo de verificação.
  * `debugModeEnabled` permite que logs e informações adicionais fiquem disponíveis durante a execução, facilitando a depuração.
  * `executeFaceAuth` define se a autenticação facial será executada.
  * `maxRetryAttempts` define o número máximo de tentativas de repetição para a validação de liveness facial. Se definido como -1, permite tentativas ilimitadas.

**Exemplo de código para a configuração de Face Liveness:**

```kotlin
sdkConfiguration.setFaceLivenessConfig(
    CafFaceLivenessConfig(
        loading = true,                                                             // Exibe a tela de carregamento durante o processamento
        reverseProxyConfig = CafReverseProxyConfig(
            authBaseUrl = "https://my.proxy.io/v1/faces/",                          // Opcional, endpoint para autenticação
            livenessBaseUrl = "wss://my.proxy.io/ws/",                              // Opcional, endpoint para verificação de liveness
            certificates = listOf("4d69f16113bed7d62ca56feb68d32a0fcb7293d3960=")   // Opcional, usado apenas com proxy reverso
        )
        screenCaptureEnabled = true,                                                // Permite captura de tela, se necessário
        debugModeEnabled = true,                                                    // Ativa o modo de depuração para logs detalhados
        executeFaceAuth = false,                                                    // Define se a autenticação facial será executada.
        maxRetryAttempts = 3                                                        // Define quantas vezes a tela de nova tentativa será exibida.
    )
)
```

Essas configurações iniciais são fundamentais para garantir que o SDK opere como esperado. Cada parâmetro foi projetado para oferecer flexibilidade e segurança, permitindo adaptar o fluxo de captura às necessidades específicas da sua aplicação.

Após concluir essas configurações, o SDK estará pronto para ser inicializado e executado, garantindo uma integração robusta e eficiente com os módulos.

***

## Inicializando o Builder

A inicialização do Builder é a etapa em que o fluxo de captura do CafSDK é configurado para execução. Usando a classe CafSdkProvider.Builder, você configura os parâmetros essenciais que definem o comportamento do fluxo e preparam o SDK para ser iniciado.

**Parâmetros essenciais**

* **mobileToken**: token que autentica a solicitação e garante que apenas clientes autorizados iniciem o fluxo.
* **personId**: identificador único do usuário para o qual o fluxo será executado.
* **environment**: define o ambiente de execução, por exemplo, CafEnvironment.PROD para produção. Isso permite alternar entre os ambientes de desenvolvimento, homologação e produção.
* **configuration**: o objeto CafSdkConfiguration configurado anteriormente, que contém tanto a ordem de execução dos módulos quanto as configurações específicas.
* **callback**: um callback unificado, no qual todos os eventos gerados pelos módulos (como carregamento, sucesso, erro e cancelamento) são tratados de forma centralizada.

**Exemplo de código detalhado:**

```kotlin
val sdkBuilder = CafSdkProvider.Builder(
    mobileToken = "mobile-token",        // Token de autenticação
    personId = "person-id",              // Identificador do usuário
    environment = CafEnvironment.PROD,   // Ambiente de produção
    configuration = sdkConfiguration,    // Configuração global com ordem e parâmetros dos módulos
    callback = ::callbackEvent           // Retorno dos eventos do SDK
).build()
```

### Callback unificado

O callback unificado é um dos pilares do CafSDK, responsável por notificar a aplicação sobre o estado de cada etapa do fluxo de captura. Ele centraliza os eventos disparados pelos módulos e permite que o desenvolvedor implemente lógicas de resposta, registros de log e tratamento de erros.

**Tipos de eventos do callback:**

* **Log:** captura mensagens de log com diferentes níveis (DEBUG, USAGE, INFO). Essas mensagens ajudam a identificar o comportamento interno do fluxo.
* **Loading:** indica o início do processamento do módulo. Útil para exibir indicadores visuais de progresso.
* **Loaded:** confirma que uma determinada ação foi concluída. Útil para ocultar indicadores visuais de progresso.
* **Success:** após a conclusão bem-sucedida, cada módulo dispara um evento contendo um [CafUnifiedResponse](#cafunifiedresponse) objeto.
* **Failure:** se ocorrer uma falha durante a execução, este evento é disparado com uma mensagem descritiva e o tipo da falha.
* **Error:** se ocorrer um problema durante a execução, este evento é disparado com a mensagem de erro, permitindo que a aplicação trate o erro.
* **Cancelled:** indica que o usuário ou o sistema interrompeu o fluxo, permitindo ações de recuperação ou notificações.

**Exemplos de código:**

```kotlin
private fun callbackEvent(event: CafUnifiedEvent): Unit = when(event) {
        is CafUnifiedEvent.Log -> {
            // Logs informativos, úteis para depuração e monitoramento
            log("[LOG] ${event.level}: ${event.message}")
        }
        is CafUnifiedEvent.Loading -> {
            // Indica que alguma execução foi iniciada internamente (pode exibir uma tela de carregamento)
            log("[LOADING]")
        }
        is CafUnifiedEvent.Loaded -> {
            // Indica que a execução interna foi concluída (pode ocultar uma tela de carregamento)
            log("[LOADED]")
        }
        is CafUnifiedEvent.Success -> {
            // Quando o módulo é concluído com sucesso, o callback recebe o nome do módulo e os resultados
            event.response.forEach {
                log("[SUCCESS] moduleName: ${it.moduleName}")
                log("[SUCCESS] signedResponse: ${it.signedResponse}")
            }
        }
        is CafUnifiedEvent.Failure -> {
            // Captura falhas que ocorrem durante a execução e permite implementar lógica de tratamento de falhas
            log("[FAILURE] ${event.response}")
            log("[FAILURE] ${event.type}")
            log("[FAILURE] ${event.description}")
        }
        is CafUnifiedEvent.Error -> {
            // Captura erros que ocorrem durante a execução e permite implementar lógica de tratamento de falhas
            log("[ERROR] ${event.response}")
            log("[ERROR] ${event.type}")
            log("[ERROR] ${event.description}")
        }
        is CafUnifiedEvent.Cancelled -> {
            // Informa que a operação foi cancelada pelo usuário ou devido a uma falha de execução
            log("[CANCELLED]")
        }
    }
```

**Tratamento de eventos da sessão**

O callback do builder retorna um conjunto de eventos definidos pela `CafUnifiedEvent` enumeração. Esses eventos incluem:

* `Loading`: Indica uma solicitação de carregamento do SDK
* `Loaded`: Indica uma solicitação de carregamento do SDK concluída
* `Success(responses: List<CafUnifiedResponse>)`: Resultados finais (quando `waitForAllServices=true`)
* `Failure(response: String, type: CafFailureType, description: String)`: Falhas específicas do módulo
* `Error(response: String, type: CafErrorType, description: String)`: Erros críticos de execução
* `Cancelled`: Cancelamento iniciado pelo usuário
* `Log(level: CafLogLevel, message: String)`: Informações de depuração

### Detalhamento dos tipos de erro

### Tipos de falha (CafFailureType)

|     Caso do enum    | Condição de acionamento          | GPA |  LA |
| :-----------------: | -------------------------------- | :-: | :-: |
|      `UNKNOWN`      | Falha genérica                   |  ✅  |  ❌  |
| `TOO_MUCH_MOVEMENT` | Movimento excessivo da cabeça    |  ✅  |  ❌  |
|     `TOO_BRIGHT`    | Excesso de iluminação            |  ✅  |  ❌  |
|      `TOO_DARK`     | Condições de pouca luz           |  ✅  |  ❌  |
|  `MISALIGNED_FACE`  | Falha no alinhamento do rosto    |  ✅  |  ❌  |
|    `FACE_TOO_FAR`   | Rosto muito distante             |  ✅  |  ❌  |
|   `FACE_TOO_CLOSE`  | Rosto muito próximo              |  ✅  |  ❌  |
|     `SUNGLASSES`    | Óculos que obstruem os olhos     |  ✅  |  ❌  |
|   `OBSCURED_FACE`   | Obstrução parcial do rosto       |  ✅  |  ✅  |
|    `EYES_CLOSED`    | Olhos fechados durante a captura |  ✅  |  ✅  |
|   `MULTIPLE_FACES`  | Vários rostos detectados         |  ✅️ |  ✅️ |
|  `BACKGROUND_ISSUE` | Plano de fundo inadequado        |  ❌  |  ✅  |
|    `DEVICE_ISSUE`   | Dispositivo incompatível         |  ❌  |  ✅  |
|      `EYEWEAR`      | Óculos detectados                |  ❌  |  ✅  |
|   `FACE_NOT_FOUND`  | Falha na detecção do rosto       |  ❌  |  ✅  |
|   `FRAMES_BLURRY`   | Frames borrados detectados       |  ❌  |  ✅  |
|    `MOTION_ISSUE`   | Erro de movimento do dispositivo |  ❌  |  ✅  |
|  `LIGHTING_ISSUES`  | Condições de iluminação ruins    |  ❌  |  ✅  |
|      `REJECTED`     | Transação rejeitada              |  ❌  |  ✅  |
|    `SYSTEM_ERROR`   | Erro interno do sistema          |  ❌  |  ✅  |
|      `TIMEOUT`      | Tempo limite da sessão           |  ❌  |  ✅  |
|   `USER_NOT_FOUND`  | Falha na busca do usuário        |  ❌  |  ✅  |
|   `DEVICE_RESTART`  | Erro no estado do dispositivo    |  ❌  |  ✅  |
|  `PROCESSING_FAULT` | Erro de processamento            |  ❌  |  ✅  |

Legenda: ✅ = suportado, ❌ = não suportado

```kotlin
when (result) {
    is Failure -> {
        when (result.type) {
            FailureType.EYES_CLOSED -> showAlert("Mantenha os olhos abertos")
            FailureType.MULTIPLE_FACES -> showAlert("Apenas um rosto é permitido")
        // Tratar outros casos
        }
    }
}
```

***

### Tipos de erro (CafErrorType)

| Caso do enum            | Condição de acionamento                                          |
| ----------------------- | ---------------------------------------------------------------- |
| GENERIC\_ERROR          | Ocorre um erro genérico                                          |
| UNKNOWN                 | Erro não classificado                                            |
| SEQUENCE\_INVALID       | Quando a lista de sequência na execução do CafSDK está vazia     |
| CAMERA\_PERMISSION      | Acesso à câmera negado                                           |
| NETWORK\_EXCEPTION      | Problemas de conectividade de rede                               |
| SERVER\_EXCEPTION       | Falha no processamento no backend                                |
| TOKEN\_EXCEPTION        | Token inválido/expirado                                          |
| LIVENESS\_EXCEPTION     | Quando ocorre um problema de liveness                            |
| UNSUPPORTED\_DEVICE     | Especificações do dispositivo não suportadas                     |
| FINGERPRINT\_EXCEPTION  | Quando a impressão digital do dispositivo apresenta um problema  |
| CANCELLATION            | Quando o usuário cancela a execução                              |
| LIBRARY\_EXCEPTION      | Erro de baixo nível do framework                                 |
| STORAGE\_EXCEPTION      | Não há espaço no armazenamento interno do dispositivo do usuário |
| PERMISSION\_EXCEPTION   | Permissões do sistema ausentes                                   |
| PROXY\_EXCEPTION        | Quando ocorre um problema ao usar o proxy configurado            |
| SECURITY\_EXCEPTION     | Quando o SDK não pode ser iniciado por um motivo de segurança    |
| AVAILABILITY\_EXCEPTION | O SDK ainda não está disponível para uso.                        |
| INVALID\_EXCEPTION      | Quando o token é inválido                                        |
| FACE\_AUTHENTICATION    | Quando ocorre um problema de autenticação facial                 |

```kotlin
when (result) {
    is Error -> {
        when (result.type) {
            CafErrorType.CAMERA_PERMISSION -> requestCameraAccess()
            CafErrorType.NETWORK_EXCEPTION -> showRetryButton()
            CafErrorType.SERVER_EXCEPTION -> showAlert("Resposta inválida recebida do servidor")
        // Tratar outros casos
        }
    }
}
```

### Retornos de segurança <a href="#security-returns" id="security-returns"></a>

Estamos constantemente tomando medidas para tornar o produto mais seguro, mitigando muitos ataques observados nos processos de captura e reduzindo ao máximo possível as tentativas de fraude de identidade. Os erros descritos aqui são retornados no `campo message` da `classe SecurityReason` .

**Desabilitando verificações de segurança**

* **Erros 300–400:** Você pode desabilitar essas verificações individualmente pelos métodos por verificação do Builder do SDK (por exemplo, `.setUseDeveloperMode(bool use)` para 300, `.setUseAdb(bool use)` para 400). Não é necessária nenhuma alteração no módulo de segurança global.
* **Erros 500–699:** Essas verificações são aplicadas dentro do módulo de segurança. Para desabilitá-las, você deve definir `enableSecurityModule = false` em `CafSdkConfiguration`. Quando existir um método de Builder por verificação, use-o também: `.setUseDebug(bool use)` para 500, `.checkAppSignature(use: Boolean)` para 600. Para 601, 602 e 699 não há método por verificação; desabilitar o módulo de segurança via `enableSecurityModule = false` é necessário.

#### Erro 300 <a href="#error-300" id="error-300"></a>

Representa o bloqueio de dispositivos com o modo desenvolvedor ativo.

O modo desenvolvedor permite que os usuários acessem configurações avançadas, como depuração de apps via USB. Por padrão, os SDKs bloqueiam dispositivos no modo desenvolvedor.

Para desabilitar essa validação, use o `.setUseDeveloperMode(bool use)` método no Builder do SDK.

#### Erro 400 <a href="#error-400" id="error-400"></a>

Representa o bloqueio de dispositivos com o Android Debug Bridge (ADB) ativado.

O ADB permite que os usuários instalem e depurem apps e acessem um shell Unix. Por padrão, os SDKs bloqueiam dispositivos com ADB ativado.

Para desabilitar essa validação, use o `.setUseAdb(bool use)` método no Builder do SDK.

#### Erro 500 <a href="#error-500" id="error-500"></a>

Representa o bloqueio de dispositivos com o modo de depuração ativado.

O modo de depuração permite que os usuários depurem aplicativos via USB, possibilitando contornar os fluxos do SDK. Por padrão, os SDKs bloqueiam dispositivos no modo de depuração.

Para desabilitar essa validação, use o `.setUseDebug(bool use)` método no Builder do SDK e defina `enableSecurityModule = false` em CafSdkConfiguration.

#### Erro 600 <a href="#error-600" id="error-600"></a>

Representa o bloqueio de dispositivos com assinaturas de apps fraudulentas ou ferramentas de adulteração detectadas.

A verificação de assinatura bloqueia ataques de engenharia reversa e todos os outros ataques maliciosos que podem ser realizados após esse processo, no qual a assinatura original do app é alterada. Por isso, os SDKs realizam esse bloqueio por padrão.

Se você quiser desabilitar essa validação, use o `.checkAppSignature(use: Boolean)` método no Builder do SDK e defina `enableSecurityModule = false` em CafSdkConfiguration.

#### Erro 601 <a href="#error-601" id="error-601"></a>

Representa o bloqueio de dispositivos com root ou com frameworks de gerenciamento de root.

O acesso root contorna a sandbox de segurança do Android e permite controle total do dispositivo e do ambiente da aplicação.

Para desabilitar essa validação, defina `enableSecurityModule = false` em CafSdkConfiguration.

#### Erro 602 <a href="#error-602" id="error-602"></a>

Representa um erro de validação de segurança.

Retornado quando o processo de validação de segurança falha inesperadamente ou quando um detector de segurança falha ao ser executado.

Para evitar esse erro em desenvolvimento ou se os detectores estiverem falhando, desabilite o módulo de segurança em CafSdkConfiguration com `enableSecurityModule = false`.

#### Erro 699 <a href="#error-699" id="error-699"></a>

Representa um erro de segurança desconhecido ou não catalogado.

Esse código é usado quando o módulo de segurança detecta uma condição que não corresponde a nenhuma das categorias definidas (500, 600, 601, 602).

Para evitar esse erro em desenvolvimento, você pode desabilitar o módulo de segurança em CafSdkConfiguration com `enableSecurityModule = false`.

### **Pré-carregamento da sessão (opcional)**

O `loadSession()` método permite pré-carregar a sessão do usuário antes de iniciar o fluxo do SDK. Isso melhora o tempo de abertura do SDK Face Liveness ao preparar com antecedência a sessão e a inicialização da câmera, resultando em uma inicialização mais rápida do SDK quando `start()` for chamado.

**Quando usar:**

* Quando você quiser otimizar a experiência do usuário reduzindo o tempo inicial de carregamento
* Quando você tiver a oportunidade de pré-carregar a sessão antes de o usuário realmente precisar iniciar o fluxo
* Particularmente útil para a inicialização do módulo Face Liveness

**Exemplo de código:**

```kotlin
val sdkBuilder = CafSdkProvider.Builder(
    mobileToken = "mobile-token",
    personId = "person-id",
    environment = CafEnvironment.PROD,
    configuration = sdkConfiguration,
    callback = ::callbackEvent
).build()

// Pré-carrega a sessão (opcional)
sdkBuilder.loadSession(this)

// Depois, quando estiver pronto para iniciar o fluxo
sdkBuilder.start(this)
```

**Observações importantes:**

* Este método é opcional e pode ser chamado depois de `build()` mas antes de `start()`
* o parâmetro de contexto deve ser um contexto de aplicação válido
* Pré-carregar a sessão ajuda a reduzir o tempo inicial de carregamento quando `start()` for eventualmente chamado
* Isso é particularmente benéfico para a inicialização do módulo Face Liveness

### **Início do fluxo configurado**

Após construir o `sdkBuilder` objeto com todas as configurações e o callback definido, o fluxo de captura é iniciado chamando o `start()` método. Esse método recebe o contexto (o contexto da aplicação é recomendado) e inicia a execução sequencial dos módulos configurados.

**Código para iniciar o fluxo:**

```kotlin
sdkBuilder.start(this)
```

### Detalhes do processo

* **Contexto:** o parâmetro passado para `start()` deve ser um contexto válido (por exemplo, a `aplicação` atual), permitindo que o SDK exiba as telas de captura e gerencie as transições de UI.
* **Execução sequencial:** o SDK inicia os módulos na ordem definida em `presentationOrder`. Cada módulo é executado sequencialmente e, ao ser concluído, dispara o próximo, garantindo que o fluxo siga a lógica estabelecida.
* **Integração do callback:** durante a execução, o SDK usa o callback unificado para enviar os eventos correspondentes (loading, loaded, success, etc.), permitindo que a aplicação reaja em tempo real de acordo com o estado do fluxo.

### Concluir uma sessão

A conclusão de uma sessão no CafSDK ocorre quando todos os módulos configurados foram executados ou quando ocorre um erro/cancelamento no fluxo.

**Definição de conclusão da sessão**

* **Execução completa:** a sessão é considerada concluída quando cada módulo no fluxo de captura dispara um `Success` evento, indicando que todas as operações foram realizadas com sucesso.
* **Interrupção do fluxo:** se ocorrer um erro ou se o usuário cancelar o processo a qualquer momento, a sessão é interrompida, e o `Erro` ou `Cancelled` evento é acionado, permitindo que a aplicação tome as medidas necessárias.

**Eventos de conclusão**

* **Success:**
  * Retorna resultados após a conclusão de todos os módulos quando `waitForAllServices` está habilitado; caso contrário, cada módulo que termina com sucesso envia um `CafUnifiedEvent.Success` evento, que inclui:
    * `moduleName:` identifica o módulo que concluiu a operação (ex.: `"documentDetector"` ou `"faceLiveness"`).
    * `signedResponse:` um token JWT contendo os dados de resultado obtidos pela execução do módulo. Esses dados podem incluir informações relevantes para o processo, como imagens capturadas ou resultados de validação.
* **Failure:**
  * Se um módulo falhar ao concluir sua operação, ele aciona um `CafUnifiedEvent.Failure` evento, que inclui:
    * `response:` um token JWT contendo os dados de resultado obtidos pela execução do módulo. Esses dados podem incluir informações relevantes para o processo, como imagens capturadas ou resultados de validação.
    * `type:` o tipo de falha.
    * `description:` uma mensagem descritiva explicando a falha, permitindo o tratamento apropriado do erro ou notificações ao usuário.
* **Error:**
  * Se o fluxo for interrompido devido a uma falha ou cancelamento:
    * **Error:** um `CafUnifiedEvent.Error` evento é acionado com uma mensagem descritiva do problema, permitindo a implementação de lógica de recuperação ou notificações ao usuário.
      * `response:` um token JWT contendo os dados de resultado obtidos pela execução do módulo. Esses dados podem incluir informações relevantes para o processo, como imagens capturadas ou resultados de validação.
      * `type:` o tipo de erro.
      * `description:` uma mensagem descritiva explicando a falha, permitindo o tratamento apropriado do erro ou notificações ao usuário.
* **Cancelled:**
  * Se o processo for cancelado (ex.: pelo usuário), o `CafUnifiedEvent.Cancelled` evento é acionado, permitindo a limpeza de recursos ou a exibição de mensagens informativas.

Essas etapas garantem que você tenha uma visão completa e técnica do processo de inicialização e conclusão do fluxo do CafSDK, permitindo uma integração simplificada e a implementação de estratégias adequadas para lidar com cada etapa do fluxo de captura.

{% hint style="info" %}
Essas etapas garantem que você tenha uma visão completa e técnica do processo de inicialização e conclusão do fluxo do CafSDK, permitindo uma integração simplificada e a implementação de estratégias adequadas para lidar com cada etapa do fluxo de captura.
{% endhint %}

***

## Personalização avançada do fluxo

Saiba como personalizar e ajustar o fluxo de captura do CafSDK para atender a requisitos específicos de negócio e experiência do usuário.

**Ordem de execução**

* A ordem em que os módulos serão executados é definida no `presentationOrder` da `CafSdkConfiguration` objeto.
* Essa sequência é fundamental, pois impacta diretamente a lógica do fluxo. Por exemplo, se o processo exigir que o documento seja capturado antes da verificação facial, a ordem deve refletir essa prioridade.

### Configuração específica

Para personalizar os módulos individualmente, use os `setDocumentDetectorConfig` e `setFaceLivenessConfig` métodos. Eles permitem ajustar parâmetros críticos, como:

* **Tempo de captura:** define o tempo limite para o usuário realizar a captura manual.
* **Tempo limite:** estabelece o limite máximo de espera por uma resposta do serviço.
* **Flags de depuração:** ativam ou desativam modos de depuração para facilitar a identificação de problemas durante o desenvolvimento.
* **Layout e outros parâmetros:** permitem configurar elementos visuais e operacionais específicos de cada módulo.

**Personalização visual**

Com o `CafColorConfiguration` objeto, é possível alinhar a identidade visual do fluxo de captura com a marca da sua aplicação. Essa personalização garante que os elementos visuais (botões, fundos e indicadores) mantenham consistência com o design da aplicação.

**Registro e monitoramento**

O callback unificado implementa diferentes níveis de log (DEBUG, USAGE, INFO), o que permite uma visão detalhada de cada etapa do fluxo. Esses logs são essenciais para integração com ferramentas de monitoramento, ajuste de desempenho ou identificação de problemas em tempo real.

## Exemplo de implementação

```kotlin
    private fun startCaf() {
        val sdkConfiguration = CafSdkConfiguration(
            presentationOrder = listOf(CafModuleType.FACE_LIVENESS, CafModuleType.DOCUMENT_DETECTOR),
            colorConfig = CafColorConfiguration(primaryColor = "#0000FF", secondaryColor = "#00FF00"),
            enableSecurityModule = true,
            waitForAllServices = true // Opcional, padrão é true
        ).apply {
            setDocumentDetectorConfig(
                CafDocumentDetectorConfig(
                    flow = listOf(DocumentDetectorStep(Document.RG_FRONT), DocumentDetectorStep(Document.RG_BACK)),
                    useAdb = true,
                    useDebug = true,
                    useDeveloperMode = true,
                    manualCaptureEnabled = true,
                    manualCaptureTime = 45,
                    requestTimeout = 60,
                    showPopup = true,
                    instructionsEnabled = true
                )
            )
            setFaceLivenessConfig(
                CafFaceLivenessConfig(
                    loading = true,
                    debugModeEnabled = true
                )
            )
        }
        CafSdkProvider.Builder(
            mobileToken = MOBILE_TOKEN,
            personId = PERSON_ID,
            environment = CafEnvironment.PROD,
            configuration = sdkConfiguration,
            callback = ::callbackEvent
        )
            .build()
            .start(requireContext().applicationContext)
    }

    private fun callbackEvent(event: CafUnifiedEvent): Unit = when (event) {
        is CafUnifiedEvent.Log -> {
            // Logs informativos, úteis para depuração e monitoramento
            log("[LOG] ${event.level}: ${event.message}")
        }

        is CafUnifiedEvent.Loading -> {
            // Indica que alguma execução foi iniciada internamente (pode exibir uma tela de carregamento)
            log("[LOADING]")
        }

        is CafUnifiedEvent.Loaded -> {
            // Indica que a execução interna foi concluída (pode ocultar uma tela de carregamento)
            log("[LOADED]")
        }

        is CafUnifiedEvent.Success -> {
            // Quando o módulo é concluído com sucesso, o callback recebe o nome do módulo e os resultados
            event.response.forEach {
                log("[SUCCESS] moduleName: ${it.moduleName}")
                log("[SUCCESS] signedResponse: ${it.signedResponse}")
            }
        }

        is CafUnifiedEvent.Failure -> {
            // Captura falhas que ocorrem durante a execução e permite implementar lógica de tratamento de falhas
            log("[FAILURE] ${event.response}")
            log("[FAILURE] ${event.type}")
            log("[FAILURE] ${event.description}")
        }

        is CafUnifiedEvent.Error -> {
            // Captura erros que ocorrem durante a execução e permite implementar lógica de tratamento de falhas
            log("[ERROR] ${event.message}")
        }

        is CafUnifiedEvent.Cancelled -> {
            // Informa que a operação foi cancelada pelo usuário ou devido a uma falha de execução
            log("[CANCELLED]")
        }
    }
```

***

## Configuração do Face Liveness

A integração do **Caf Face Liveness** **(FL)** módulo é feita por meio de sua configuração no `CafSdkConfiguration` objeto. Uma vez definido, o fluxo executa automaticamente o módulo na posição correspondente definida na ordem de apresentação.

A configuração do Face Liveness é feita por meio do `CafFaceLivenessConfig` objeto, no qual são informados os parâmetros que o SDK usará durante sua execução. Confira os principais métodos de configuração disponíveis:

| Método                    | Tipo                    | Descrição                                                                                                                                                |
| ------------------------- | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `setLoading`              | Boolean                 | Ativa ou desativa a tela de carregamento. O padrão é: `false`.                                                                                           |
| `setAuthBaseUrl`          | String                  | Define uma URL de proxy. Define uma URL de proxy reverso para autenticação. Deve usar o protocolo HTTPS. Opcional. Necessário apenas para proxy reverso. |
| `setLivenessBaseUrl`      | String                  | Define uma URL de proxy reverso para verificação de Face Liveness. Deve usar o protocolo WSS. Opcional. Necessário apenas para proxy reverso.            |
| `setCertificates`         | List                    | Define os certificados codificados em Base64 (SHA-256) para o proxy reverso. Opcional. Necessário apenas para WSS via proxy.                             |
| `setScreenCaptureEnabled` | Boolean                 | Ativa ou desativa a captura de tela. O padrão é: `false`.                                                                                                |
| `setDebugModeEnabled`     | Boolean                 | Ativa ou desativa a geração de logs para auxiliar na depuração durante a integração. O padrão é`false`.                                                  |
| `setSdkType`              | CafFaceLivenessPlatform | Informa qual plataforma está executando o SDK. O padrão é `CafFaceLivenessPlatform.NATIVE_ANDROID`.                                                      |
| `setExecuteFaceAuth`      | Boolean                 | Define se a autenticação facial será executada.                                                                                                          |

**Exemplo de configuração para Face Liveness:**

```kotlin
sdkConfiguration.setFaceLivenessConfig(
    CafFaceLivenessConfig(
        loading = true,
        reverseProxyConfig = CafReverseProxyConfig(    
            authBaseUrl = "https://my.proxy.io/v1/faces/",                          // Opcional, usado apenas com proxy reverso
            livenessBaseUrl = "wss://my.proxy.io/ws/",                              // Opcional, usado apenas com proxy reverso
            certificates = listOf("4d69f16113bed7d62ca56feb68d32a0fcb7293d3960=")   // Opcional, usado apenas com proxy reverso
        ),
        screenCaptureEnabled = true,
        debugModeEnabled = true,
        executeFaceAuth = true
    )
)
```

### Resultados

Após a execução bem-sucedida, um `CafUnifiedEvent.Success` evento é acionado, que contém:

* **moduleName**: o nome identificador do módulo (ex.: "faceLiveness").
* **signedResponse**: um token JWT com os dados de verificação.

Em seguida, esses dados são processados pelo callback unificado, permitindo atualizar a interface do usuário ou continuar o fluxo conforme necessário.

***

## Configurações personalizadas - Face Liveness

Use configurações personalizadas para direcionar as solicitações por proxies seguros e garantir que os protocolos corretos (WSS para Face Liveness e HTTPS para autenticação) sejam usados.

### Configuração de proxy reverso (opcional)

Essa configuração avançada permite direcionar as conexões do módulo Face Liveness por um proxy reverso, usando o protocolo WSS (Web Socket Secure). Siga os passos para configurar corretamente:

* **URL do proxy:** defina seu proxy para se comunicar com o endpoint desejado. Por exemplo, você pode usar: `wss://us.rp.secure.iproov.me/ws` ou outra URL compatível.
* **Configuração da URL do Face Liveness:** use o `.setLivenessBaseUrl` método para configurar a URL do Face Liveness. Lembre-se de que o protocolo deve ser WSS.
* **Definição de certificados:** use o `.setCertificates` método para definir os certificados necessários. Esses certificados devem ser os hashes SHA256 dos certificados do proxy codificados em Base64.

**Exemplo de código:**

```kotlin
sdkConfiguration.setFaceLivenessConfig(
    CafFaceLivenessConfig(
        livenessBaseUrl = "wss://my.proxy.io/ws/",
        certificates = listOf(
            "4d69f16113bed7d62ca56feb68d32a0fcb7293d3960=",
            "50f71c5dda30741ee4be1ac378e12539b0d1d511f99=",
            "9f85e26c1ae41f7ac97adc4099be7f2a40759510ab9="
        )
    )
)
```

### **Proxy reverso para autenticação** (opcional)

Para a comunicação de autenticação, é necessário configurar o proxy reverso com uma URL HTTPS. Essa configuração direciona as solicitações de autenticação para o ambiente apropriado.

* **URL do proxy:** defina seu proxy para se comunicar. Por exemplo, você pode usar: `https://api.public.caf.io/`.
* **Configuração da URL de autenticação:** use o `.setAuthBaseUrl` método para especificar a URL de autenticação, garantindo que o protocolo HTTPS seja usado.

**Exemplo de código:**

```kotlin
sdkConfiguration.setFaceLivenessConfig(
    CafFaceLivenessConfig(
        authBaseUrl = "https://my.proxy.io/v1/faces/"
    )
)
```

> Observação: na prática, ambas as configurações (de autenticação e Face Liveness) podem ser combinadas em uma única instância de `CafFaceLivenessConfig`.

## **Estruturas de configuração**

Ao usar o módulo de UI (com o `-ui` sufixo), você estará usando as telas proprietárias do Caf, que têm algumas possibilidades de personalização. Confira os detalhes:

### Tela de instruções do Caf Face Liveness

Essa estrutura permite personalizar a tela de instruções do Face Liveness.

| Propriedade   | Tipo            | Descrição                                                                                                                                              | Valor padrão |
| ------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------ |
| `image`       | `String?`       | Imagem exibida no cabeçalho da tela. O valor pode ser uma URL, o ID do recurso (em formato de string) ou o nome do recurso presente na pasta drawable. | `null`       |
| `title`       | `String?`       | Título da tela (ex.: "Instruções para escanear o rosto").                                                                                              | `null`       |
| `description` | `String?`       | Texto descritivo breve (ex.: "Siga os passos abaixo").                                                                                                 | `null`       |
| `steps`       | `List<String>?` | Lista ordenada de instruções (ex.: listOf("Mantenha o telefone estável", "Boa iluminação")).                                                           | `null`       |
| `buttonText`  | `String?`       | Texto para o botão de confirmação (ex.: "Iniciar a leitura").                                                                                          | `null`       |

### Configuração de cores do Caf

Essa estrutura permite personalizar as cores globais de todas as interfaces. As cores seguem o padrão `RGB` ou `ARGB`.

<table><thead><tr><th>Propriedade</th><th>Tipo</th><th width="166">Descrição</th><th>Formato</th></tr></thead><tbody><tr><td><code>primaryColor</code></td><td><code>String</code></td><td>Cor principal para botões e destaques.</td><td>Código hexadecimal (ex.: <code>#FF0000</code>)</td></tr><tr><td><code>secondaryColor</code></td><td><code>String</code></td><td>Cor secundária para elementos complementares.</td><td>Código hexadecimal</td></tr><tr><td><code>backgroundColor</code></td><td><code>String</code></td><td>Cor de fundo da tela.</td><td>Código hexadecimal</td></tr><tr><td><code>contentColor</code></td><td><code>String</code></td><td>Cor usada para textos e ícones.</td><td>Código hexadecimal</td></tr><tr><td><code>mediumColor</code></td><td><code>String</code></td><td>Cor neutra para elementos como barras de progresso.</td><td>Código hexadecimal</td></tr></tbody></table>

## **Exemplos de código**

Confira o exemplo de como configurar o módulo Face Liveness com instruções, proxy reverso (para autenticação e verificação) e personalização da interface.

```kotlin
val sdkConfiguration = CafSdkConfiguration(
      presentationOrder = listOf(...),
      colorConfig = CafColorConfiguration(
         primaryColor = "#FF0000",
         secondaryColor = "#00FF00",
         backgroundColor = "#FFFFFF",
         contentColor = "#000000",
         mediumColor = "#D1D1D1"
      ),
      enableSecurityModule = true
)
sdkConfiguration.setFaceLivenessConfig(
   CafFaceLivenessConfig(
        loading = true,
        reverseProxyConfig = CafReverseProxyConfig(
            authBaseUrl = "https://my.proxy.io/v1/faces/",
            livenessBaseUrl = "wss://my.proxy.io/ws/",
            certificates = listOf(
                "4d69f16113bed7d62ca56feb68d32a0fcb7293d3960=",
                "50f71c5dda30741ee4be1ac378e12539b0d1d511f99=",
                "9f85e26c1ae41f7ac97adc4099be7f2a40759510ab9="
            )
        ),
        screenCaptureEnabled = true,
        debugModeEnabled = true,
        maxRetryAttempts = 3
   )
)
sdkConfiguration.setCafFaceLivenessInstructionsScreen(
   CafFaceLivenessInstructionsScreen(
        image = R.drawable.scan_icon.toString()
        title = "Custom title",
        description = "Siga os passos abaixo:",
        steps = listOf("Mantenha o telefone estável", "Garanta boa iluminação"),
        buttonText = "Iniciar a leitura",
   )
)
```

***

## Mais informações

**Requisitos dos certificados**

* **Certificados:** eles devem ser os hashes SHA-256 do SPKI (Subject Public Key Info) do certificado, codificados em Base64.

### Aplicação de protocolo

* **Face Liveness:** A URL para Face Liveness **deve** use o `wss://` ao usar um proxy reverso.
* **Autenticação:** A URL para autenticação **deve** use o `https://` ao usar um proxy reverso.

***

## Configuração do Document Detector

O módulo Caf Document Detector (DD) é configurado de forma semelhante ao Face Liveness, mas com foco na captura e no processamento de documentos.

**Configuração e execução**

Em `CafSdkConfiguration`, configure os parâmetros específicos do Document Detector, que determinam o comportamento da captura de documentos.

**Principais parâmetros:**

* `flow`: uma lista de etapas (`DocumentDetectorStep`) que define qual documento e quais ângulos ou partes devem ser capturados.
* `useAdb`, `useDebug`e `useDeveloperMode`: flags que auxiliam no desenvolvimento e na execução em ambientes de teste.
* `manualCaptureEnabled` e `manualCaptureTime`: configure se a captura manual é permitida e qual é o tempo limite para a ação.
* `requestTimeout`: tempo máximo de espera por respostas do servidor ou ações do usuário.
* `showPopup`: determina se uma mensagem de confirmação ou instrução será apresentada ao usuário.
* `maxRetryAttempts`: define o número máximo de tentativas permitidas antes de interromper o processo ou exibir uma mensagem de erro ao usuário

**Exemplo de configuração para o Document Detector:**

```kotlin
sdkConfiguration.setDocumentDetectorConfig(
    CafDocumentDetectorConfig(
        flow = listOf(DocumentDetectorStep(Document.RG_FRONT)),
        useAdb = true,
        useDebug = true,
        useDeveloperMode = true,
        manualCaptureEnabled = true,
        manualCaptureTime = 45,
        requestTimeout = 60,
        showPopup = true
    )
)
```

### Resultados

* Ao concluir a captura e o processamento do documento, o módulo Document Detector aciona um `CafUnifiedEvent.Success` evento.
* Esse evento inclui o `moduleName` (ex.:`"documentDetector"`) e um `resultado` contendo os dados capturados.
* O callback unificado pode então usar essas informações para prosseguir para a próxima etapa ou armazenar os resultados conforme necessário.

***

## Configurações personalizadas - Document Detector

Para configurar o Caf Document Detector, use a `CafDocumentDetectorConfig` estrutura, que inclui:

* Etapas do fluxo de captura do documento.
* Personalização do layout da interface do usuário (UI).
* Mensagens de feedback.
* Comportamento de upload.
* Configurações de proxy.

### Configuração principal

Propriedades de `CafDocumentDetectorConfig`.

| Propriedade                  | Tipo                         | Descrição                                                                                                                                                 |
| ---------------------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `flow`                       | `List<DocumentDetectorStep>` | Define o fluxo de captura do documento. Veja [DocumentDetectorStep](#documentdetectorstep)                                                                |
| `layoutId`                   | `Int?`                       | ID do layout personalizado.                                                                                                                               |
| `uploadSettings`             | `UploadSettings?`            | Configurações para upload de documentos. Veja [UploadSettings](#uploadsettings)                                                                           |
| `manualCaptureEnabled`       | `Boolean?`                   | Ativa ou desativa a captura manual.                                                                                                                       |
| `manualCaptureTime`          | `Int?`                       | Tempo limite para captura manual (em segundos).                                                                                                           |
| `requestTimeout`             | `Int?`                       | Tempo limite para solicitações (em segundos).                                                                                                             |
| `showPopup`                  | `Boolean?`                   | Ativa ou desativa pop-ups antes da captura.                                                                                                               |
| `proxySettings`              | `ProxySettings?`             | Configurações de proxy. Veja [ProxySettings](#proxysettings)                                                                                              |
| `previewShow`                | `Boolean?`                   | Ativa ou desativa a visualização da imagem capturada.                                                                                                     |
| `instructionsEnabled`        | `Bool`                       | Ativa a tela de visualização de instruções.                                                                                                               |
| `ddCustomizations`           | `List<CafDDCustomization>?`  | Lista de personalizações de strings de UI e ativos para telas do Document Detector (ex.: pop-up de upload, tela de visualização).                         |
| `getUrlExpireTime`           | `String?`                    | Define por quanto tempo a URL da imagem permanecerá ativa no servidor até expirar. Aceita intervalos como `30m` (minutos), `24h` (horas) ou `10d` (dias). |
| `allowedPassportCountryList` | `List<CountryCodesList>?`    | Lista de países permitidos para passaportes. Veja [CountryCodesList](#countrycodeslist)                                                                   |
| `useDebug`                   | `Boolean?`                   | Permite que o aplicativo seja executado em modo de depuração quando `true`. **Não recomendado para produção**                                             |
| `useDeveloperMode`           | `Boolean?`                   | Ativa o modo de desenvolvedor quando `true`. **Não recomendado para produção**                                                                            |
| `useAdb`                     | `Boolean?`                   | Ativa o modo de depuração do Android Debug Bridge (ADB) quando `true`. **Não recomendado para produção**                                                  |

### **DocumentDetectorStep**

Para criar um fluxo de captura, você deve criar um array de **`DocumentDetectorStep`**, em que cada elemento representa uma etapa de captura. Para construir cada `DocumentDetectorStep` objeto, você pode usar o seguinte:

#### Construtor

| Propriedade          | Tipo        | Descrição                                                                  | Obrigatório | Padrão                         |
| -------------------- | ----------- | -------------------------------------------------------------------------- | ----------- | ------------------------------ |
| `documento`          | `Documento` | Tipo de documento a ser capturado (por exemplo, `.rgFront`).               | Sim         |                                |
| `stringStepLabel`    | `String?`   | Texto exibido na parte inferior da tela para esta etapa.                   | Não         | Rótulo padrão do documento     |
| `stringIllustration` | `String?`   | Imagem exibida no pop-up de instruções para esta etapa.                    | Não         | Ilustração padrão do documento |
| `stringMessage`      | `String?`   | Texto da mensagem personalizada para o pop-up de instruções desta etapa.   | Não         | Mensagem padrão do documento   |
| `okButtonTitle`      | `String?`   | Texto personalizado para o botão 'OK' no pop-up de instruções desta etapa. | Não         | "OK"                           |

| Propriedade                             | Descrição                                                                            |
| --------------------------------------- | ------------------------------------------------------------------------------------ |
| `document: Document`                    | Especifica o documento a ser capturado na etapa. Confira os tipos suportados abaixo. |
| `setStepLabel(stepLabel: Int)`          | Define o texto exibido na parte inferior do layout.                                  |
| `setIllustration(illustration: Int)`    | Define a ilustração exibida no pop-up antes da captura.                              |
| `showStepLabel(showStepLabel: Boolean)` | Alterna a visibilidade do texto na parte superior do layout.                         |

#### Documentos suportados

| Documento      | Descrição                                                                                                                      |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `RG_FRENTE`    | Lado frontal do documento RG, onde a foto está localizada.                                                                     |
| `RG_VERSO`     | Lado de trás do documento RG.                                                                                                  |
| `RG_COMPLETO`  | Documento RG aberto, exibindo juntos os lados frontal e traseiro.                                                              |
| `CNH_FRENTE`   | Lado frontal do documento CNH, onde a foto está localizada.                                                                    |
| `CNH_VERSO`    | Lado de trás do documento CNH.                                                                                                 |
| `CNH_COMPLETO` | Documento CNH aberto, exibindo juntos os lados frontal e traseiro.                                                             |
| `CRLV`         | Documento CRLV.                                                                                                                |
| `RNE_FRENTE`   | Lado frontal do documento RNE ou RNM.                                                                                          |
| `RNE_VERSO`    | Lado de trás do documento RNE ou RNM.                                                                                          |
| `PASSAPORTE`   | Documento de passaporte, exibindo a foto e os dados pessoais.                                                                  |
| `CTPS_FRENTE`  | Lado frontal do documento CTPS, onde a foto está localizada.                                                                   |
| `CTPS_VERSO`   | Lado de trás do documento CTPS.                                                                                                |
| `QUALQUER`     | Permite o envio de qualquer tipo de documento, incluindo todos os listados acima ou qualquer outro documento não classificado. |

**Exemplo:**

```kotlin
val detectorStep = DocumentDetectorStep(
        Document.RG_FRONT
        "Frente do documento de identidade",
        "https://my.custom/image.jpg",
        "Coloque a frente do seu documento de identidade na moldura.",
        "Entendi!"
    )
```

### **UploadSettings**

Configura as definições relacionadas ao envio de documentos.

| Propriedade                                       | Descrição                                                           |
| ------------------------------------------------- | ------------------------------------------------------------------- |
| `.setEnable(enable: Boolean)`                     | Ativa ou desativa este recurso.                                     |
| `.setCompress(enable: Boolean)`                   | Ativa ou desativa a compactação do arquivo antes do envio.          |
| `.setFileFormats(fileFormats: Array<FileFormat>)` | Especifica os formatos de arquivo aceitos para envio.               |
| `.setMaxFileSize(maxFileSize: Int)`               | Define o limite máximo de tamanho do arquivo em KB.                 |
| `.setActivityLayout(activityLayout: Int)`         | Define o layout de fundo para o envio de documentos.                |
| `.setPopUpLayout(popUpLayout: Int)`               | Define o layout do pop-up para a solicitação de envio do documento. |

Atualmente, os formatos de arquivo suportados são:

| Tipo   | Valor             |
| ------ | ----------------- |
| `PNG`  | `image/png`       |
| `JPG`  | `image/jpg`       |
| `JPEG` | `image/jpeg`      |
| `PDF`  | `application/pdf` |
| `HEIF` | `image/heif`      |

### **ProxySettings**

Para que o SDK use um proxy ao fazer solicitações, você deve configurar uma instância do **`ProxySettings`** .

#### **Método construtor**

| Propriedade | Tipo     | Descrição                                            |
| ----------- | -------- | ---------------------------------------------------- |
| `hostname`  | `String` | Define o domínio ou endereço IP do serviço de proxy. |
| `port`      | `String` | Define a porta a ser usada.                          |

#### **Métodos opcionais**

**`setAuthentication(String user, String password)`**

Define os parâmetros de autenticação para o proxy, se necessário.

| Propriedade | Descrição                                      |
| ----------- | ---------------------------------------------- |
| `user`      | Nome de usuário a ser usado para autenticação. |
| `password`  | Senha a ser usada para autenticação.           |

**`setProxyCertificate(@RawRes Integer proxyCertificate)`**

Se o seu servidor proxy usar um certificado SSL autoassinado ou emitido por uma Autoridade Certificadora (CA) não pública, adicione o certificado da CA em `PEM` ou `DER` formato para o `res/raw/` diretório (por exemplo, `res/raw/proxy_certificate`) e passe o identificador do arquivo como argumento (por exemplo, `R.raw.proxy_certificate`).

| Propriedade        | Descrição                              |
| ------------------ | -------------------------------------- |
| `proxyCertificate` | ID do arquivo do certificado do proxy. |

**`setMTLSConfig(@RawRes Integer clientCertificate, String password)`**

Se o seu servidor proxy oferecer suporte a mTLS, salve o certificado do cliente em `PKCS12` formato (`.p12`) no `res/raw/` diretório (por exemplo, `res/raw/client_certificate`) e passe o identificador do arquivo (por exemplo, `R.raw.client_certificate`) e a chave privada como argumentos.

| Propriedade         | Descrição                                |
| ------------------- | ---------------------------------------- |
| `clientCertificate` | ID do arquivo do certificado do cliente. |
| `password`          | Chave privada a ser usada.               |

### Personalização de strings da UI e de ativos (`CafDDCustomization`)

O `ddCustomizations` propriedade em `CafDocumentDetectorConfig` permite fornecer um array de objetos em conformidade com `CafDDCustomization` para substituir os textos e imagens padrão em telas específicas do Document Detector.

#### `CafPreviewCustomization`

Personaliza a tela de pré-visualização do documento mostrada após a captura de uma imagem de documento (se `previewShow` é `true`).

| Propriedade      | Tipo      | Descrição                                                | Padrão (localizado)                                   |
| ---------------- | --------- | -------------------------------------------------------- | ----------------------------------------------------- |
| `title`          | `String?` | Texto do título na tela de pré-visualização.             | "A foto está boa?"                                    |
| `campo message`  | `String?` | Texto do subtítulo/mensagem na tela de pré-visualização. | "Verifique se todas as informações estão legíveis..." |
| `okButton`       | `String?` | Texto do botão de confirmação ("aceitar").               | "Sim, está boa!"                                      |
| `tryAgainButton` | `String?` | Texto do botão de tentar novamente ("capturar de novo"). | "Capturar de novo"                                    |

**Exemplo:**

```kotlin
val previewCustom = CafDDCustomization.CafPreviewCustomization(
                        title: "Confirmar qualidade da foto",
                        message: "Certifique-se de que todos os detalhes estejam claros e não haja reflexos.",
                        okButton: "Confirmar",
                        tryAgainButton: "Recapturar"
                    )
// Adicione a CafDocumentDetectorConfig:
// ddCustomizations = listOf(previewCustom)
```

#### `CafDDUploadCustomization`

Personaliza o pop-up exibido quando o usuário escolhe enviar um arquivo de documento.

| Propriedade     | Tipo      | Descrição                                    | Padrão (localizado)      |
| --------------- | --------- | -------------------------------------------- | ------------------------ |
| `image`         | `String?` | Imagem exibida no topo do pop-up.            | Ilustração padrão do SDK |
| `campo message` | `String?` | Texto da mensagem dentro do pop-up de envio. | "Selecione o arquivo..." |
| `uploadButton`  | `String?` | Texto do botão "Enviar".                     | "Enviar"                 |
| `cancelButton`  | `String?` | Texto do botão "Cancelar".                   | "Cancelar"               |

**Exemplo:**

```kotlin
val uploadCustom = CafDDCustomization.CafDDUploadCustomization(
                    message: "Por favor, escolha o arquivo de documento que você deseja enviar.",
                    uploadButton: "Escolher arquivo",
                    cancelButton: "Voltar"
                )
// Adicione a CafDocumentDetectorConfig:
// ddCustomizations = listOf(previewCustom, uploadCustom) // Pode haver várias personalizações
```

#### `CafMessageCustomization`

Personaliza várias mensagens em fluxo exibidas durante o processo de captura do documento (por exemplo, mensagens do sensor, feedback da IA).

| Propriedade                    | Descrição                                                                        |
| ------------------------------ | -------------------------------------------------------------------------------- |
| `waitMessage`                  | Mensagem exibida ao iniciar a câmera.                                            |
| `fitTheDocumentMessage`        | Mensagem que solicita ao usuário ajustar o documento dentro da moldura.          |
| `holdItMessage`                | Mensagem exibida durante o processo de captura.                                  |
| `verifyingQualityMessage`      | Mensagem exibida durante a solicitação de verificação de qualidade.              |
| `lowQualityDocumentMessage`    | Mensagem exibida quando a captura do documento falha devido à baixa qualidade.   |
| `uploadingImageMessage`        | Mensagem exibida ao salvar a imagem capturada no servidor.                       |
| `openDocumentWrongMessage`     | Mensagem exibida se um documento aberto for detectado.                           |
| `unsupportedDocumentMessage`   | Mensagem para documentos não suportados.                                         |
| `documentNotFoundMessage`      | Mensagem exibida quando nenhum documento é detectado.                            |
| `sensorLuminosityMessage`      | Mensagem exibida quando o nível de brilho está muito baixo.                      |
| `sensorOrientationMessage`     | Mensagem exibida quando o limite de orientação não é atingido.                   |
| `sensorStabilityMessage`       | Mensagem exibida quando o dispositivo não está estável o suficiente.             |
| `popupDocumentSubtitleMessage` | Mensagem de subtítulo exibida no pop-up que apresenta a ilustração do documento. |
| `positiveButtonMessage`        | Mensagem exibida no botão de confirmação.                                        |
| `aiScanDocumentMessage`        | Mensagem que solicita ao usuário escanear um documento.                          |
| `aiGetCloserMessage`           | Mensagem que solicita ao usuário se aproximar do documento.                      |
| `aiCentralizeMessage`          | Mensagem que solicita ao usuário centralizar o documento na tela.                |
| `aiMoveAwayMessage`            | Mensagem que solicita ao usuário se afastar do documento.                        |
| `aiAlignMessage`               | Mensagem que solicita ao usuário alinhar o documento.                            |
| `aiTurnDocumentMessage`        | Mensagem que solicita ao usuário girar o documento 90 graus.                     |
| `aiCapturedMessage`            | Mensagem que confirma que o documento foi capturado.                             |
| `wrongDocumentMessage`         | Mensagem exibida quando o tipo de documento está incorreto.                      |

**Exemplo:**

```kotlin
val messageCustom = CafMessageCustomization(
    waitMessage: "Por favor, aguarde...",
    fitTheDocumentMessage: "Alinhe seu documento dentro da moldura."
)
// Adicione a CafDocumentDetectorConfig:
// ddCustomizations = listOf(previewCustom, uploadCustom, messageCustom)
```

### **CountryCodesList**

Lista completa dos códigos oficiais atualmente atribuídos de acordo com [ISO 3166-1 alpha-3](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3).

## Personalizando telas

Ao usar o módulo de UI (com o `-ui` sufixo), você estará usando as telas proprietárias da CAF. Essas telas oferecem opções de personalização conforme descrito abaixo.

### CafDocumentDetectorInstructionsScreen

Esta estrutura permite personalizar a tela de instruções.

| Propriedade   | Tipo            | Descrição                                                                                                                             |
| ------------- | --------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `image`       | `String?`       | Imagem exibida no cabeçalho da tela. O valor pode ser uma URL, um ID de recurso (como string) ou o nome do recurso na pasta drawable. |
| `title`       | `String?`       | Título da tela (por exemplo, "Instruções para escanear o rosto").                                                                     |
| `description` | `String?`       | Texto descritivo breve (ex.: "Siga os passos abaixo").                                                                                |
| `steps`       | `List<String>?` | Lista ordenada de instruções (por exemplo, `listOf("Mantenha o celular firme", "Garanta uma boa iluminação")`).                       |
| `buttonText`  | `String?`       | Texto do botão de confirmação (por exemplo, "Iniciar a leitura").                                                                     |

### CafDocumentDetectorDocumentSelectionScreen

Esta estrutura permite personalizar a tela de seleção de documentos.

| Propriedade   | Tipo                      | Descrição                                                                                                                              |
| ------------- | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `documents`   | `List<CafDocument>`       | Lista de documentos a serem exibidos. O valor pode ser uma URL, um ID de recurso (como string) ou o nome do recurso na pasta drawable. |
| `title`       | `String?`                 | Título da tela (por exemplo, "Selecione o documento").                                                                                 |
| `description` | `String?`                 | Texto descritivo breve (por exemplo, "Escolha o documento que você deseja enviar").                                                    |
| `groupLabels` | `CafDocumentGroupLabels?` | Configura os itens da tela de seleção de documentos (título/descrição) com base nos grupos de documentos.                              |

#### CafDocument

| Nome        | Descrição                                                                        |
| ----------- | -------------------------------------------------------------------------------- |
| `RGFront`   | Frente do documento RG, onde fica a foto.                                        |
| `RGBack`    | Verso do documento RG.                                                           |
| `RGFull`    | Documento RG aberto, exibindo juntos a frente e o verso.                         |
| `CnhFront`  | Frente do documento CNH, onde fica a foto.                                       |
| `CnhBack`   | Verso do documento CNH.                                                          |
| `CnhFull`   | Documento CNH aberto, exibindo juntos a frente e o verso.                        |
| `Crlv`      | Documento CRLV.                                                                  |
| `RneFront`  | Frente do documento RNE ou RNM.                                                  |
| `RneBack`   | Verso do documento RNE ou RNM.                                                   |
| `Passport`  | Documento de passaporte, exibindo a foto e os dados pessoais.                    |
| `CtpsFront` | Frente do documento CTPS, onde fica a foto.                                      |
| `CtpsBack`  | Verso do documento CTPS.                                                         |
| `Outro`     | Permite o envio de qualquer outro tipo de documento que não esteja classificado. |

### CafColorConfiguration

Esta estrutura permite personalizar as cores globais de todas as interfaces. As cores seguem o `RGB` ou `ARGB` padrão.

| Propriedade             | Tipo     | Descrição                                           | Formato                                     |
| ----------------------- | -------- | --------------------------------------------------- | ------------------------------------------- |
| `primaryColor`          | `String` | Cor primária para botões e destaques.               | Código hexadecimal (por exemplo, `#FF0000`) |
| `secondaryColor`        | `String` | Cor secundária para elementos complementares.       | Código hexadecimal                          |
| `backgroundColor`       | `String` | Cor de fundo da tela.                               | Código hexadecimal                          |
| `contentColor`          | `String` | Cor usada para texto e ícones.                      | Código hexadecimal                          |
| `mediumColor`           | `String` | Cor neutra para elementos como barras de progresso. | Código hexadecimal                          |
| `dialogBackgroundColor` | `String` | Cor de fundo do diálogo e do pop-up.                | Código hexadecimal                          |
| `dialogBorderColor`     | `String` | Cor da borda do diálogo e do pop-up.                | Código hexadecimal                          |

## Exemplos de código

O exemplo a seguir demonstra como configurar o módulo DocumentDetector com instruções e personalização da interface:

```kotlin
private fun isDarkMode() = 
    (resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) == Configuration.UI_MODE_NIGHT_YES

val colorConfigConfiguration = if (isDarkMode()) {
    CafColorConfiguration(
        primaryColor = "#00FF00",
        secondaryColor = "#FF0000",
        backgroundColor = "#000000",
        contentColor = "#FFFFFF",
        mediumColor = "#D1D1D1",
        dialogBackgroundColor: "#FFFFFF",
        dialogBorderColor: "#E5E5E7"
    )
} else {
    CafColorConfiguration(
        primaryColor = "#FF0000",
        secondaryColor = "#00FF00",
        backgroundColor = "#FFFFFF",
        contentColor = "#000000",
        mediumColor = "#D1D1D1",
        dialogBackgroundColor: "#FFFFFF",
        dialogBorderColor: "#E5E5E7"  
    )
}

val sdkConfiguration = CafSdkConfiguration(
    presentationOrder = listOf(...),
    colorConfig = colorConfigConfiguration,
    enableSecurityModule = true
)

sdkConfiguration.setDocumentDetectorConfig(
    CafDocumentDetectorConfig(
        flow = listOf(),        // Ao usar a UI, isso pode ficar vazio porque a lista será definida em CafDocumentDetectorDocumentSelectionScreen
        uploadSettings = false, // Ao usar a UI, isso será ignorado, pois o usuário pode selecionar na tela
        useDebug = true,
        useDeveloperMode = true,
        useAdb = true
    )
)

sdkConfiguration.setCafDocumentDetectorDocumentSelectionScreen(
    CafDocumentDetectorDocumentSelectionScreen(
        documents = listOf(CafDocument.RGFront(), CafDocument.RGBack(), CafDocument.CnhFront(), CafDocument.CnhBack()),
        title = "Custom title",
        description = "descrição personalizada",
        groupLabels = CafDocumentGroupLabels(
                            rg = CafDocumentLabel("Título personalizado do RG", "Descrição personalizada do RG")
                        )
    )
)

sdkConfiguration.setCafDocumentDetectorInstructionsScreen(
    CafDocumentDetectorInstructionsScreen(
        title = "Custom title",
        steps = listOf("Mantenha o telefone estável", "Garanta boa iluminação"),
        buttonText = "Iniciar"
    )
)
```

## CafUnifiedResponse

```kotlin
public class CafUnifiedResponse(
    public val moduleName: String,
    public val signedResponse: String,
)
```

| Propriedade      | Tipo     | Descrição                                                    |
| ---------------- | -------- | ------------------------------------------------------------ |
| `moduleName`     | `String` | Nome do módulo que emite seu resultado no evento de sucesso. |
| `signedResponse` | `String` | JWT contendo os dados obtidos pela execução do módulo.       |

***

## Recursos adicionais

**Regras do ProGuard/R8**

Confira o bloco de código com as regras do ProGuard/R8 necessárias para que o CafSDK e suas dependências funcionem corretamente mesmo após ofuscação e otimização do código. Essas regras preservam informações essenciais (como assinaturas, anotações e classes internas) e impedem que classes críticas sejam removidas ou alteradas.

```proguard
# O pre-handler do Android para exceções é carregado de forma reflexiva (via ServiceLoader).
-keep class kotlinx.coroutines.experimental.android.AndroidExceptionPreHandler { *; }

### GSON ##################################################################
# O Gson usa informações genéricas de tipo armazenadas em um arquivo de classe ao trabalhar com campos.
# O ProGuard remove essas informações por padrão, então configure-o para manter tudo.
-keepattributes Signature
# Para usar a anotação @Expose do GSON
-keepattributes *Annotation*
### FIM GSON ##################################################################

### Retrofit ##################################################################
# Preserve assinaturas genéricas, classes internas e métodos envolventes para a reflexão do Retrofit.
-keepattributes Signature, InnerClasses, EnclosingMethod
# Reter anotações visíveis em tempo de execução em métodos e parâmetros.
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
# Manter valores padrão das anotações.
-keepattributes AnnotationDefault
# Reter parâmetros de métodos de serviço para interfaces com anotações do Retrofit.
-keepclassmembers,allowshrinking,allowobfuscation interface * {
    @retrofit2.http.* <methods>;
}
# Suprimir avisos para ferramentas de build e certas anotações JSR 305.
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn javax.annotation.**
-dontwarn kotlin.Unit
-dontwarn retrofit2.KotlinExtensions
-dontwarn retrofit2.KotlinExtensions$*
# Manter explicitamente as interfaces do Retrofit para evitar nulificação pelo R8.
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface <1>
-if interface * { @retrofit2.http.* <methods>; }
-keep,allowobfuscation interface * extends <1>
# Preservar as continuações usadas pelas funções suspend do Kotlin.
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation
# Para o modo full do R8: manter tipos genéricos de retorno para métodos do Retrofit.
-if interface * { @retrofit2.http.* public *** *(...); }
-keep,allowoptimization,allowshrinking,allowobfuscation class <3>
# Preservar a classe Response do Retrofit.
-keep,allowobfuscation,allowshrinking class retrofit2.Response
### FIM Retrofit ##############################################################

### OkHttp ####################################################################
# Suprimir avisos para anotações JSR 305.
-dontwarn javax.annotation.**
# Adaptar nomes de arquivos de recursos para o banco de dados interno de sufixos públicos.
-adaptresourcefilenames okhttp3/internal/publicsuffix/PublicSuffixDatabase.gz
# Suprimir avisos para Animal Sniffer e classes específicas da plataforma.
-dontwarn org.codehaus.mojo.animal_sniffer.*
-dontwarn okhttp3.internal.platform.**
-dontwarn org.conscrypt.**
-dontwarn org.bouncycastle.**
-dontwarn org.openjsse.**
# Manter todas as classes do OkHttp e do Okio.
-keep class okhttp3.** { *; }
-dontwarn okhttp3.**
-keep class okio.** { *; }
-dontwarn okio.**
-dontwarn javax.annotation.Nullable
-dontwarn javax.annotation.ParametersAreNonnullByDefault
### FIM OkHttp ################################################################

### Kotlin Serialization ######################################################
# Manter objetos Companion para classes serializáveis.
-if @kotlinx.serialization.Serializable class **
-keepclassmembers class <1> {
    static <1>$Companion Companion;
}
# Manter funções serializer em objetos companion.
-if @kotlinx.serialization.Serializable class ** {
    static **$* *;
}
-keepclassmembers class <2>$<3> {
    kotlinx.serialization.KSerializer serializer(...);
}
# Reter INSTANCE e serializer para objetos serializáveis.
-if @kotlinx.serialization.Serializable class ** {
    public static ** INSTANCE;
}
-keepclassmembers class <1> {
    public static <1> INSTANCE;
    kotlinx.serialization.KSerializer serializer(...);
}
# Preservar objetos Companion em kotlinx.serialization.json.
-keepclassmembers class kotlinx.serialization.json.** {
    *** Companion;
}
-keepclasseswithmembers class kotlinx.serialization.json.** {
    kotlinx.serialization.KSerializer serializer(...);
}
# Preservar a busca de serializer para classes serializáveis (ajuste o nome do pacote conforme necessário).
-keepclassmembers @kotlinx.serialization.Serializable class packeage.** {
    *** Companion;
    *** INSTANCE;
    kotlinx.serialization.KSerializer serializer(...);
}
### FIM Kotlin Serialization #################################################

### AutoValue ################################################################
-dontwarn com.google.auto.**
-dontwarn autovalue.shaded.com.**
-dontwarn sun.misc.Unsafe
-dontwarn javax.lang.model.element.Modifier
### FIM AutoValue ############################################################

### CAF - Combate à Fraude ######################################################
# Manter atributos de exceções.
-keepattributes Exceptions
# Preservar todas as classes, interfaces e membros de classe para os módulos CAF.
-keep class com.caf.facelivenessiproov.** { *; }
-keep class com.combateafraude.documentdetector.** { *; }
-keep class com.combateafraude.** { *; }
-keep interface com.combateafraude.** { *; }
-keep class io.caf.** { *; }
-keep interface io.caf.** { *; }
-keepclassmembers class com.combateafraude.** { *; }
# Suprimir avisos para java.nio.file e certas classes internas do OkHttp.
-dontwarn java.nio.file.*
-dontwarn com.squareup.okhttp.internal.Platform
# Manter campos em classes que estendem GeneratedMessageLite (para uso do Tink).
-keepclassmembers class * extends com.google.crypto.tink.shaded.protobuf.GeneratedMessageLite {
  <fields>;
}
# Preservar classes do TensorFlow.
-keep class org.tensorflow.** { *; }
-keep class org.tensorflow.**$* { *; }
-dontwarn org.tensorflow.**
# Preservar classes do IProov e classes do Protobuf.
-keep public class com.iproov.sdk.IProov { public *; }
-keep class com.iproov.** { *; }
-keep class com.iproov.**$* { *; }
-keep class com.google.protobuf.** { *; }
-keep class com.google.protobuf.**$* { *; }
-dontwarn com.google.protobuf.**
# Suprimir avisos para classes Flow concorrentes.
-dontwarn java.util.concurrent.Flow*
# Preservar classes do Kotlin e kotlinx.
-keep class kotlin.** { *; }
-keep class kotlinx.** { *; }
-dontwarn com.android.tools.lint.**
-dontwarn io.caf.sdk.common.jvmshared.lint.**
### FIM CAF - Combate à Fraude ##################################################
```

***

## Suporte Técnico e Dicas de Uso

**Suporte Técnico** Se você tiver dúvidas ou dificuldades com a integração, entre em contato com o suporte técnico da Caf.

**Dicas de uso**

* **Executar testes:** realize testes em dispositivos reais para validar os requisitos e o desempenho do fluxo.
* **Explore personalizações:** use opções avançadas de personalização para adaptar o fluxo às necessidades do seu projeto.
* **Monitore o desempenho:** integre ferramentas de monitoramento para acompanhar os logs e o desempenho do fluxo em produção.

***


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.caf.io/caf-sdk/caf-sdk-pt-br/android/getting-started-with-the-sdk-1.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
