Os fabricantes de dispositivos podem expor efeitos especiais como bokeh, modo noturno e HDR para desenvolvedores de terceiros por meio da interface de extensões de câmera fornecida pela biblioteca do fornecedor OEM. Os desenvolvedores podem usar as APIs Camera2 Extensions e CameraX Extensions para habilitar efeitos, que são implementados como extensões na biblioteca do fornecedor OEM no dispositivo.
Para obter uma lista de extensões compatíveis, que é a mesma entre Camera2 e CameraX, consulte API de extensões CameraX . Se você quiser adicionar uma extensão, registre um bug aqui .
Esta página descreve como implementar e habilitar a biblioteca de fornecedores OEM em dispositivos.
Arquitetura
 O diagrama a seguir descreve a arquitetura da interface Camera Extensions ou extensions-interface : 
Figura 1. Diagrama de arquitetura de extensões de câmera
 Conforme mostrado no diagrama, para oferecer suporte a extensões de câmera, você precisa implementar a extensions-interface fornecida pela biblioteca do fornecedor OEM. Sua biblioteca de fornecedor OEM habilita duas APIs: CameraX Extensions API e Camera2 Extensions API , que são usadas pelos aplicativos CameraX e Camera2, respectivamente, para acessar extensões de fornecedor.
Implemente a biblioteca de fornecedores OEM
 Para implementar a biblioteca do fornecedor OEM, copie os arquivos camera-extensions-stub em um projeto de biblioteca do sistema. Esses arquivos definem a interface de Extensões de Câmera.
 Os arquivos camera-extensions-stub são divididos nas seguintes categorias:
Arquivos de interface essenciais (não modifique)
-  PreviewExtenderImpl.java
-  ImageCaptureExtenderImpl.java
-  ExtenderStateListener.java
-  ProcessorImpl.java
-  PreviewImageProcessorImpl.java
-  CaptureProcessorImpl.java
-  CaptureStageImpl.java
-  RequestUpdateProcessorImpl.java
-  ProcessResultImpl.java
-  advanced/AdvancedExtenderImpl.java
-  advanced/Camera2OutputConfigImpl.java
-  advanced/Camera2SessionConfigImpl.java
-  advanced/ImageProcessorImpl.java
-  advanced/ImageReaderOutputConfigImpl.java
-  advanced/ImageReferenceImpl.java
-  advanced/MultiResolutionImageReaderOutputConfigImpl.java
-  advanced/OutputSurfaceImpl.java
-  advanced/RequestProcessorImpl.java
-  advanced/SessionProcessorImpl.java
-  advanced/SurfaceOutputConfigImpl.java
Implementações obrigatórias (adicione sua implementação)
-  ExtensionVersionImpl.java
-  InitializerImpl.java
Classes extensoras de Bokeh (implementá-las se a extensão Bokeh for suportada)
-  BokehImageCaptureExtenderImpl.java
-  BokehPreviewExtenderImpl.java
-  advanced/BokehAdvancedExtenderImpl.java
Aulas de extensão noturna (implementá-lo se a extensão noturna for suportada)
-  NightImageCaptureExtenderImpl.java
-  NightPreviewExtenderImpl.java
-  advanced/NightAdvancedExtenderImpl.java
Classes de extensor automático (implementá-lo se a extensão automática for suportada)
-  AutoImageCaptureExtenderImpl.java
-  AutoPreviewExtenderImpl.java
-  advanced/AutoAdvancedExtenderImpl.java
Classes de extensor HDR (implementá-lo se a extensão HDR for suportada)
-  HdrImageCaptureExtenderImpl.java
-  HdrPreviewExtenderImpl.java
-  advanced/HdrAdvancedExtenderImpl.java
Classes de extensor de retoque de rosto (implementá-lo se a extensão de retoque de rosto for suportada)
-  BeautyImageCaptureExtenderImpl.java
-  BeautyPreviewExtenderImpl.java
-  advanced/BeautyAdvancedExtenderImpl.java
Utilitários (opcional, pode ser excluído)
-  advanced/Camera2OutputConfigImplBuilder.java
-  advanced/Camera2SessionConfigImplBuilder.java
 Você não é obrigado a fornecer uma implementação para cada extensão. Se você não implementar uma extensão, defina isExtensionAvailable() para retornar false ou remova as classes Extender correspondentes. As APIs de extensões Camera2 e CameraX informam ao aplicativo que a extensão não está disponível.
Vamos ver como as APIs Camera2 e CameraX Extensions interagem com a biblioteca do fornecedor para habilitar uma extensão. O diagrama a seguir ilustra o fluxo de ponta a ponta usando a extensão Night como exemplo:

Figura 2. Implementação da extensão noturna
- Verificação da versão: - Camera2/X chama - ExtensionVersionImpl.checkApiVersion()para garantir que a versão- extensions-interfaceimplementada pelo OEM seja compatível com as versões suportadas pelo Camera2/X.
- Inicialização da biblioteca do fornecedor: - InitializerImpltem um método- init()que inicializa a biblioteca do fornecedor. Camera2/X conclui a inicialização antes de acessar as classes Extender.
- Classes de Extensor de Instanciação: - Instancia as classes Extender para a extensão. Existem dois tipos de Extender: Basic Extender e Advanced Extender. Você deve implementar um tipo de Extender para todas as Extensões. Para obter mais informações, consulte Basic Extender versus Advanced Extender . - Camera2/X instancia e interage com as classes Extender para recuperar informações e habilitar a extensão. Para uma determinada extensão, Camera2/X pode instanciar as classes Extender várias vezes. Como resultado, não faça uma inicialização pesada no construtor ou na chamada - init(). Faça o trabalho pesado apenas quando a sessão da câmera estiver prestes a iniciar, como quando- onInit()é chamado no Basic Extender ou- initSession()é chamado no Advanced Extender.- Para a extensão Night, as seguintes classes Extender são instanciadas para o tipo Basic Extender: -  NightImageCaptureExtenderImpl.java
-  NightPreviewExtenderImpl.java
 - E para o tipo Advanced Extender: -  NightAdvancedExtenderImpl.java
 
-  
- Verifique a disponibilidade da extensão: - Antes de habilitar a extensão, - isExtensionAvailable()verifica se a extensão está disponível na ID de câmera especificada por meio da instância do Extender.
- Inicialize o Extender com as informações da câmera: - Camera2/X chama - init()na instância do Extender e passa o ID da câmera e- CameraCharacteristics.
- Informações da consulta: - Chama a classe Extender para recuperar informações como resoluções suportadas, captura ainda a latência estimada e chaves de solicitação de captura do Extender em preparação para ativar a extensão. 
- Habilite a extensão no Extender: - A classe Extender fornece todas as interfaces necessárias para ativar a classe. Ele oferece um mecanismo para conectar a implementação OEM no pipeline Camera2, como injetar parâmetros de solicitação de captura ou habilitar um pós-processador. - Para o tipo Advanced Extender, Camera2/X interage com - SessionProcessorImplpara habilitar a extensão. Camera2/X recupera a instância- SessionProcessorImplchamando- createSessionProcessor()no Extender.
As seções a seguir descrevem o fluxo de extensão com mais detalhes.
Verificação de versão
 Ao carregar a biblioteca do fornecedor OEM do dispositivo em tempo de execução, o Camera2/X verifica se a biblioteca é compatível com a versão extensions-interface . A extensions-interface usa versionamento semântico, ou MAJOR.MINOR.PATCH, por exemplo, 1.1.0 ou 1.2.0. No entanto, apenas as versões principais e secundárias são usadas durante a verificação da versão.
 Para verificar a versão, Camera2/X chama ExtensionVersionImpl.checkApiVersion() com a versão extensions-interface suportada. O Camera2/X então usa a versão relatada pela biblioteca OEM para determinar se a extensão pode ser habilitada e quais recursos ela deve invocar.
Compatibilidade da versão principal
Se as versões principais da interface de extensão forem diferentes entre Camera2/X e a biblioteca do fornecedor, ela será considerada incompatível e a extensão será desativada.
Compatibilidade com versões anteriores
 Desde que a versão principal seja idêntica, o Camera2/X garante compatibilidade com versões anteriores com bibliotecas de fornecedores OEM criadas com versões anteriores extensions-interface . Por exemplo, se Camera2/X oferece suporte extensions-interface 1.3.0, as bibliotecas de fornecedores OEM que implementaram 1.0.0, 1.1.0 e 1.2.0 ainda são compatíveis. Isso também significa que depois de implementar uma versão específica da biblioteca do fornecedor, o Camera2/X garante que a biblioteca seja compatível com versões anteriores extension-interface .
Compatibilidade futura
 A compatibilidade futura com bibliotecas de fornecedores de extensions-interface mais recentes depende de você, o OEM. Se você precisar de alguns recursos para implementar as extensões, convém habilitar as extensões a partir de uma determinada versão. Nesse caso, você pode retornar a versão da extensions-interface suportada quando a versão da biblioteca Camera2/X atender aos requisitos. Se as versões Camera2/X não forem suportadas, você pode retornar uma versão incompatível como 99.0.0 para desabilitar as extensões.
Inicialização da biblioteca do fornecedor
 Após verificar a versão extensions-interface implementada pela biblioteca OEM, Camera2/X inicia o processo de inicialização. O método InitializerImpl.init() sinaliza para a biblioteca OEM que um aplicativo está tentando usar extensões.
 Camera2/X não faz outras chamadas para a biblioteca OEM (além da verificação de versão) até que a biblioteca do fornecedor OEM chame OnExtensionsInitializedCallback.onSuccess() para notificar a conclusão da inicialização.
 Você deve implementar InitializerImpl a partir de extensions-interface 1.1.0. Camera2/X ignora a etapa de inicialização da biblioteca se a biblioteca do fornecedor OEM implementar extensions-interface 1.0.0.
Extensor Básico versus Extensor Avançado
 Existem dois tipos de implementação extensions-interface : Basic Extender e Advanced Extender. O Advanced Extender é suportado desde extensions-interface 1.2.0.
Implemente o Basic Extender para extensões que processam imagens na câmera HAL ou use um pós-processador capaz de processar fluxos YUV.
Implemente o Advanced Extender para extensões que precisam personalizar a configuração do stream Camera2 e enviar solicitações de captura conforme necessário.
Veja a tabela a seguir para a comparação:
| Extensor Básico | Extensor Avançado | |
|---|---|---|
| Configurações de transmissão | Fixo Visualização: PRIVATEouYUV_420_888(se houver processador)Ainda captura: JPEGouYUV_420_888(se houver processador) | Personalizável pelo OEM. | 
| Enviando solicitação de captura | Somente Camera2/X pode enviar solicitações de captura. Você pode definir os parâmetros para essas solicitações. Quando o processador é fornecido para captura de imagem, Camera2/X pode enviar várias solicitações de captura e enviar todas as imagens e resultados de captura para o processador. | Uma instância RequestProcessorImplé fornecida a você para executar a solicitação de captura camera2 e obter resultados e Image. Camera2/X invoca  | 
| Ganchos no pipeline da câmera | 
 | 
 | 
| Adequado para | Extensões implementadas na câmera HAL ou em um processador que processa imagens YUV. | 
 | 
| Versão da API compatível | Extensões Camera2: Android T (AOSP experimental) ou superior Extensões CameraX: extensões camera-extensions1.1.0 ou superior | Extensões Camera2: Android 12L ou superior Extensões CameraX: extensões camera-extensions1.2.0-alpha03 ou superior | 
Fluxos de aplicativos
A tabela a seguir mostra três tipos de fluxos de aplicativos e suas chamadas de API de extensões de câmera correspondentes. Embora a Camera2/X forneça essas APIs, você deve implementar adequadamente a biblioteca do fornecedor para oferecer suporte a esses fluxos, que descreveremos com mais detalhes em uma seção posterior.
| Extensões Camera2 | Extensões CameraX | |
|---|---|---|
| Disponibilidade da extensão de consulta | CameraExtensionCharacteristics . getSupportedExtensions | ExtensionsManager. isExtensionAvailable | 
| Informações de consulta | CameraExtensionCharacteristics. getExtensionSupportedSizesCameraExtensionCharacteristics. getEstimatedCaptureLatencyRangeMillisCameraExtensionCharacteristics. getAvailableCaptureRequestKeysCameraExtensionCharacteristics. getAvailableCaptureResultKeys | ExtensionsManager. getEstimatedCaptureLatencyRangeO CameraX lida com o restante das informações na biblioteca. | 
| Visualização e captura estática com extensão habilitada | CameraDevice. createExtensionSession    | val cameraSelector = ExtensionsManager. getExtensionEnabledCameraSelectorbindToLifecycle(lifecycleOwner, cameraSelector, preview, ...) | 
Extensor Básico
A interface do Basic Extender fornece ganchos em vários locais no pipeline da câmera. Cada tipo de extensão tem classes de Extender correspondentes que os OEMs precisam implementar.
A tabela a seguir lista as classes do Extender que os OEMs precisam implementar para cada extensão:
| Classes extensoras para implementar | |
|---|---|
| Noite | NightPreviewExtenderImpl.java  | 
| HDR | HdrPreviewExtenderImpl.java | 
| Auto | AutoPreviewExtenderImpl.java | 
| Bokeh | BokehPreviewExtenderImpl.java | 
| Retoque de rosto | BeautyPreviewExtenderImpl.java | 
 Usamos PreviewExtenderImpl e ImageCaptureExtenderImpl como espaços reservados no exemplo a seguir. Substitua-os pelos nomes dos arquivos reais que você está implementando.
O Basic Extender tem os seguintes recursos:
-  Injete parâmetros de sessão ao configurar CameraCaptureSession(onPresetSession).
-  Notificá-lo sobre os eventos de início e fechamento da sessão de captura e enviar uma única solicitação para notificar a HAL com os parâmetros retornados ( onEnableSession,onDisableSession).
-  Injete parâmetros de captura para a solicitação ( PreviewExtenderImpl.getCaptureStage,ImageCaptureExtenderImpl.getCaptureStages).
-  Adicione processadores para visualização e captura ainda capaz de processar o fluxo YUV_420_888.
 Vamos ver como Camera2/X invoca a extensions-interface para alcançar os três fluxos de aplicativo mencionados acima.
Fluxo do aplicativo 1: verifique a disponibilidade da extensão

Figura 3. Fluxo de aplicativo 1 no Basic Extender
 Nesse fluxo, Camera2/X chama diretamente o método isExtensionAvailable() de PreviewExtenderImpl e ImageCaptureExtenderImpl sem chamar init() . Ambas as classes Extender devem retornar true para ativar as extensões.
Geralmente, essa é a primeira etapa para os aplicativos verificarem se o tipo de extensão fornecido é compatível com um determinado ID de câmera antes de ativar a extensão. Isso ocorre porque algumas extensões são suportadas apenas em determinadas IDs de câmera.
Fluxo de aplicativo 2: informações de consulta

Figura 4. Fluxo de aplicativo 2 no Basic Extender
Depois de determinar se a extensão está disponível, os aplicativos devem consultar as informações a seguir antes de habilitar a extensão.
- Intervalo de latência de captura ainda: - ImageCaptureExtenderImpl.getEstimatedCaptureLatencyRangeretorna o intervalo de latência de captura para o aplicativo avaliar se é apropriado habilitar a extensão para o cenário atual.
- Tamanhos com suporte para a superfície de visualização e captura: - ImageCaptureExtenderImpl.getSupportedResolutionse- PreviewExtenderImpl.getSupportedResolutionsretornam uma lista de formatos de imagem e os tamanhos com suporte para formato e tamanho de superfície.
- Chaves de solicitação e resultado suportadas: Camera2/X invoca os seguintes métodos para recuperar as chaves de solicitação de captura e as chaves de resultado suportadas de sua implementação: -  ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys
-  ImageCaptureExtenderImpl.getAvailableCapturetResultKeys
 
-  
 Camera2/X sempre chama init() primeiro nessas classes Extender antes de consultar mais informações.
Fluxo de aplicativo 3: visualização/captura estática com extensão habilitada (implementação HAL)

Figura 5. Fluxo de aplicativo 3 no Basic Extender
O diagrama acima ilustra o fluxo principal de habilitar a visualização e ainda capturar com uma extensão sem nenhum processador. Isso significa que a câmera HAL processa a extensão.
 Nesse fluxo, Camera2/X primeiro chama init() e depois onInit , que notifica que uma sessão de câmera está prestes a começar com as extensões especificadas. Você pode fazer uma inicialização pesada em onInit() .
 Ao configurar CameraCaptureSession , Camera2/X invoca onPresetSession para obter os parâmetros da sessão. Depois que a sessão de captura é configurada com sucesso, Camera2/X invoca onEnableSession retornando uma instância CaptureStageImpl que contém os parâmetros de captura. O Camera2/X envia imediatamente uma única solicitação com esses parâmetros de captura para notificar o HAL. Da mesma forma, antes que a sessão de captura seja fechada, Camera2/X invoca onDisableSession e, em seguida, envia uma única solicitação com os parâmetros de captura retornados.
 A solicitação repetida acionada por Camera2/X contém os parâmetros de solicitação retornados por PreviewExtenderImpl.getCaptureStage() . Além disso, a solicitação de captura estática contém os parâmetros retornados por ImageCaptureExtenderImpl.getCaptureStages() .
 Finalmente, Camera2/X invoca onDeInit() após o término da sessão da câmera. Você pode liberar recursos em onDeinit() .
Processador de visualização
Além da câmera HAL, você também pode implementar extensões em um processador.
 Implemente PreviewExtenderImpl.getProcessorType para especificar o tipo de processador conforme explicado abaixo:
- PROCESSOR_TYPE_NONE: Sem processador. As imagens são processadas na câmera HAL.
- PROCESSOR_TYPE_REQUEST_UPDATE_ONLY: O tipo de processador permite atualizar a solicitação repetida com novos parâmetros de solicitação de captura com base no- TotalCaptureResultmais recente.- PreviewExtenderImpl.getProcessordeve retornar uma instância- RequestUpdateProcessorImplque processa a instância- TotalCaptureResulte retorna uma instância- CaptureStageImplpara atualizar a solicitação repetida.- PreviewExtenderImpl.getCaptureStage()também deve refletir o resultado do processamento e retornar o- CaptureStageImplmais recente.
- PROCESSOR_TYPE_IMAGE_PROCESSOR: Este tipo permite implementar um processador para processar imagens- YUV_420_888e gravar a saída em uma superfície- PRIVATE.- Você precisa implementar e retornar uma instância - PreviewImageProcessorImplem- PreviewExtenderImpl.getProcessor. O processador é responsável por processar as imagens de entrada- YUV_420_888. Ele deve gravar a saída no formato- PRIVATEde visualização. Camera2/X usa uma superfície- YUV_420_888em vez de- PRIVATEpara configurar a- CameraCaptureSessionpara visualização.- Veja a ilustração a seguir para o fluxo: 

 Figura 6. Fluxo de visualização com PreviewImageProcessorImpl
 A interface PreviewImageProcessorImpl estende ProcessImpl e tem três métodos importantes:
- onOutputSurface(Surface surface, int imageFormat)define a superfície de saída para o processador. Para- PreviewImageProcessorImpl,- imageFormaté um formato de pixel como- PixelFormat.RGBA_8888.
- onResolutionUpdate(Size size)define o tamanho da imagem de entrada.
- onImageFormatUpdate(int imageFormat)define o formato da imagem de entrada. Atualmente, só pode ser- YUV_420_888.
Processador de captura de imagem
 Para captura estática, você pode implementar um processador retornando uma instância CaptureProcessorImpl usando ImageCaptureExtenderImpl.getCaptureProcessor . O processador é responsável por processar uma lista de imagens YUV_420_888 capturadas e instâncias TotalCaptureResult e gravar a saída em uma superfície YUV_420_888 .
Você pode presumir com segurança que a visualização está habilitada e em execução antes de enviar a solicitação de captura estática.
Veja o fluxo no diagrama abaixo:

 Figura 7. Fluxo de captura estática com CaptureProcessorImpl
- Camera2/X usa uma superfície de formato - YUV_420_888para captura estática para configurar a sessão de captura. Camera2/X prepara- CaptureProcessorImplchamando:-  CaptureProcessorImpl.onImageFormatUpdate()comYUV_420_888.
-  CaptureProcessorImpl.onResolutionUpdate()com o tamanho da imagem de entrada.
-  CaptureProcessorImpl.onOutputSurface()com uma superfície de saídaYUV_420_888.
 
-  
- ImageCaptureExtenderImpl.getCaptureStagesretorna uma lista de- CaptureStageImpl, onde cada elemento mapeia para uma instância- CaptureRequestcom parâmetros de captura que são enviados por Camera2/X. Por exemplo, se ele retornar uma lista de três instâncias de- CaptureStageImpl, Camera2/X enviará três solicitações de captura com parâmetros de captura correspondentes usando a API- captureBurst.
- As imagens recebidas e as instâncias - TotalCaptureResultsão agrupadas e enviadas ao- CaptureProcessorImplpara processamento.
- CaptureProcessorImplgrava a imagem resultante (formato- YUV_420_888) na superfície de saída especificada pela chamada- onOutputSurface(). Camera2/X converte em imagens JPEG, se necessário.
Suporte a chaves e resultados de solicitação de captura
Além da visualização e captura da câmera, os aplicativos podem definir zoom, parâmetros de flash ou acionar um toque para focar. Esses parâmetros podem não ser compatíveis com sua implementação de extensão.
 Os métodos a seguir foram adicionados ao extensions-interface 1.3.0 para permitir que você exponha os parâmetros que sua implementação suporta:
-  ImageCaptureExtenderImpl.getAvailableCaptureRequestKeys()retorna as chaves de solicitação de captura suportadas por sua implementação.
-  ImageCaptureExtenderImpl.getAvailableCaptureResultKeys()retorna as chaves de resultado de captura contidas no resultado de captura.
 Se a câmera HAL processar a extensão, Camera2/X recupera os resultados da captura em CameraCaptureSession.CaptureCallback . No entanto, se o processador for implementado, Camera2/X recupera os resultados da captura em ProcessResultImpl , que é passado para o método process() em PreviewImageProcessorImpl e CaptureProcessorImpl . Você é responsável por relatar o resultado da captura por meio do ProcessResultImpl para Camera2/X.
 Veja a definição da interface CaptureProcessorImpl abaixo como exemplo. Em extensions-interface 1.3.0 ou superior, a segunda chamada process() é invocada:
Interface CaptureProcessorImpl extends ProcessorImpl {
    // invoked when extensions-interface version < 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results);
    // invoked when extensions-interface version >= 1.3.0
    void process(Map<Integer, Pair<Image, TotalCaptureResult>> results,
            ProcessResultImpl resultCallback, Executor executor);
}
Para operações comuns da câmera, como zoom, toque para focar, flash e compensação de exposição, recomendamos oferecer suporte às seguintes teclas para solicitação de captura e resultado de captura:
-  Ampliação:-  CaptureRequest#CONTROL_ZOOM_RATIO
-  CaptureRequest#SCALER_CROP_REGION
 
-  
-  Toque para focar:-  CaptureRequest#CONTROL_AF_MODE
-  CaptureRequest#CONTROL_AF_TRIGGER
-  CaptureRequest#CONTROL_AF_REGIONS
-  CaptureRequest#CONTROL_AE_REGIONS
-  CaptureRequest#CONTROL_AWB_REGIONS
 
-  
-  Instantâneo:-  CaptureRequest#CONTROL_AE_MODE
-  CaptureRequest#CONTROL_AE_PRECAPTURE_TRIGGER
-  CaptureRequest#FLASH_MODE
 
-  
-  Compensação de exposição:-  CaptureRequest#CONTROL_AE_EXPOSURE_COMPENSATION
 
-  
 Para Extensores Básicos que implementam 1.2.0 ou versões anteriores, a API CameraX Extensions suporta explicitamente todas as chaves acima. Para extensions-interface 1.3.0, CameraX e Camera2 honram a lista retornada e suportam apenas as chaves contidas nela. Por exemplo, se você decidir retornar apenas CaptureRequest#CONTROL_ZOOM_RATIO e CaptureRequest#SCALER_CROP_REGION na implementação 1.3.0, isso significa que apenas o zoom é compatível com o aplicativo, enquanto toque para focar, flash e compensação de exposição não são permitidos.
Extensor Avançado
 Advanced Extender é um tipo de implementação de fornecedor baseado na API Camera2. Este tipo de Extender foi adicionado no extensions-interface 1.2.0. Dependendo do fabricante do dispositivo, as extensões podem ser implementadas na camada do aplicativo, o que depende dos seguintes fatores:
- Configuração de fluxo personalizado: configure fluxos personalizados como fluxo RAW ou tenha vários fluxos para diferentes IDs de câmera física. 
- Capacidade de enviar solicitações Camera2: Suporta uma lógica de interação complicada que pode enviar solicitações de captura com parâmetros baseados nos resultados de solicitações anteriores. 
O Advanced Extender fornece um wrapper, ou uma camada intermediária, para que você possa personalizar a configuração do fluxo e enviar solicitações de captura sob demanda.
Arquivos para implementar
 Para alternar para a implementação do Advanced Extender, o método isAdvancedExtenderImplemented() em ExtensionVersionImpl deve retornar true . Para cada tipo de extensão, os OEMs devem implementar as classes Extender correspondentes. Os arquivos de implementação do Advanced Extender estão no pacote avançado .
| Classes extensoras para implementar | |
|---|---|
| Noite | advanced/NightAdvancedExtenderImpl.java | 
| HDR | advanced/HdrAdvancedExtenderImpl.java | 
| Auto | advanced/AutoAdvancedExtenderImpl.java | 
| Bokeh | advanced/BokehAdvancedExtenderImpl.java | 
| Retoque de rosto | advanced/BeautyAdvancedExtenderImpl.java | 
 Usamos AdvancedExtenderImpl como um espaço reservado no exemplo a seguir. Substitua-o pelo nome do arquivo Extender para a extensão que você está implementando.
 Vamos ver como Camera2/X invoca a extensions-interface para alcançar os três fluxos de aplicativo.
Fluxo do aplicativo 1: verifique a disponibilidade das extensões

Figura 8. Fluxo de aplicativo 1 no Advanced Extender
Primeiro, o aplicativo verifica se a extensão especificada é compatível.
Fluxo de aplicativo 2: informações de consulta

Figura 9. Fluxo de aplicativo 2 no Advanced Extender
 Depois de chamar AdvancedExtenderImpl.init() , o aplicativo pode consultar as seguintes informações sobre AdvancedExtenderImpl :
- Latência de captura estática estimada: - AdvancedExtenderImpl.getEstimatedCaptureLatencyRange()retorna o intervalo da latência de captura para o aplicativo avaliar se é apropriado habilitar a extensão para o cenário atual.
- Resoluções suportadas para visualização e captura estática: - AdvancedExtenderImpl.getSupportedPreviewOutputResolutions()retorna um mapa de formato de imagem para a lista de tamanhos com suporte para formato e tamanho de superfície de visualização. Os OEMs devem suportar pelo menos o formato- PRIVATE.
- AdvancedExtenderImpl.getSupportedCaptureOutputResolutions()retorna o formato e os tamanhos suportados para a superfície de captura estática. Os OEMs devem oferecer suporte à saída no formato- JPEGe- YUV_420_888.
- AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions()retorna os tamanhos suportados para um fluxo- YUV_420_888extra para análise de imagem. Se a superfície YUV de análise de imagem não for suportada,- getSupportedYuvAnalysisResolutions()deve retornar- nullou uma lista vazia.
 
- Chaves/resultados de solicitação de captura disponíveis (adicionados na - extensions-interface1.3.0): Camera2/X invoca os seguintes métodos para recuperar as chaves de solicitação de captura suportadas e as chaves de resultado de sua implementação:-  AdvancedExtenderImpl.getAvailableCaptureRequestKeys
-  AdvancedExtenderImpl.getAvailableCaptureResultKeys
 
-  
Para obter mais informações, consulte Chaves e resultados da solicitação de captura de suporte .
Fluxo de aplicativo 3: visualização/captura estática com extensão habilitada

Figura 10. Fluxo de aplicativo 3 no Advanced Extender
O diagrama acima mostra o fluxo principal para iniciar a visualização e ainda capturar para o tipo Advanced Extender. Vamos percorrer cada etapa.
- instância - SessionProcessorImpl- A implementação principal do Advanced Extender está em - SessionProcessorImpl, que é responsável por fornecer configuração de sessão personalizada e enviar solicitações de captura para iniciar a visualização e ainda a solicitação de captura.- AdvancedExtenderImpl.createSessionProcessor()é invocado para retornar a instância- SessionProcessorImpl.
- initSession- SessionProcessorImpl.initSession()inicializa a sessão para a extensão. É aqui que você aloca recursos e retorna uma configuração de sessão para preparar uma- CameraCaptureSession.- Para os parâmetros de entrada, Camera2/X especifica as configurações de superfície de saída para visualização, captura estática e uma análise de imagem YUV opcional. Esta configuração de superfície de saída ( - OutputSurfaceImpl) contém a superfície, tamanho e formato de imagem que são recuperados pelos seguintes métodos em- AdvancedExtenderImpl:-  getSupportedPreviewOutputResolutions()
-  getSupportedCaptureOutputResolutions()
-  getSupportedYuvAnalysisResolutions()
 - Você deve retornar uma instância - Camera2SessionConfigImpl, que consiste em uma lista de instâncias- Camera2OutputConfigImple os parâmetros de sessão usados para configurar- CameraCaptureSession. Você é responsável por enviar as imagens de câmera corretas para as superfícies de saída passadas por Camera2/X. Aqui estão algumas opções para habilitar a saída:-  Processamento na câmera HAL: você pode adicionar diretamente as superfícies de saída a CameraCaptureSessioncom uma implementaçãoSurfaceOutputConfigImpl. Isso configura a superfície de saída fornecida para o pipeline da câmera e permite que a câmera HAL processe a imagem.
- Processando a superfície intermediária do - ImageReader(RAW, YUV, etc): Adicione as superfícies intermediárias do- ImageReaderà- CameraCaptureSessioncom uma instância- ImageReaderOutputConfigImpl.- Você precisa processar as imagens intermediárias e gravar a imagem resultante na superfície de saída. 
 -  Use o compartilhamento de superfície Camera2: use o compartilhamento de superfície com outra superfície adicionando qualquer instância Camera2OutputConfigImplao métodogetSurfaceSharingOutputConfigs()de outra instânciaCamera2OutputConfigImpl. O formato e o tamanho da superfície devem ser idênticos.
 - Todos - Camera2OutputConfigImplincluindo- SurfaceOutputConfigImple- ImageReaderOutputConfigImpldevem ter um ID exclusivo (- getId()), que é usado para especificar a superfície de destino e recuperar a imagem de- ImageReaderOutputConfigImpl.
-  
- onCaptureSessionStarte- RequestProcessorImpl- Quando - CameraCaptureSessioniniciado e a estrutura Camera invoca- onConfigured(), Camera2/X invoca- SessionProcessorImpl.onCaptureSessionStart()com o wrapper de solicitação Camera2- RequestProcessImpl. Camera2/X implementa- RequestProcessImpl, que permite executar as solicitações de captura e recuperar imagens se- ImageReaderOutputConfigImplfor usado.- As APIs - RequestProcessImplsão semelhantes às APIs Camera2- CameraCaptureSessionem termos de execução de solicitações. As diferenças são:-  A superfície de destino é especificada pelo ID da instância Camera2OutputConfigImpl.
-  A capacidade de recuperar a imagem do ImageReader.
 - Você pode chamar - RequestProcessorImpl.setImageProcessor()com uma ID- Camera2OutputConfigImplespecificada para registrar uma instância- ImageProcessorImplpara receber imagens.- A instância - RequestProcessImpltorna-se inválida depois que Camera2/X chama- SessionProcessorImpl.onCaptureSessionEnd().
-  A superfície de destino é especificada pelo ID da instância 
- Inicie a visualização e tire uma foto - Na implementação do Advanced Extender, você pode enviar solicitações de captura por meio da interface - RequestProcessorImpl. Camera2/X notifica você para iniciar a solicitação repetida para visualização ou a sequência de captura estática chamando- SessionProcessorImpl#startRepeatinge- SessionProcessorImpl#startCapturerespectivamente. Você deve enviar solicitações de captura para atender a essas solicitações de visualização e captura estática.- Camera2/X também define os parâmetros de solicitação de captura por meio de - SessionProcessorImpl#setParameters. Você deve definir esses parâmetros de solicitação (se houver suporte para parâmetros) nas solicitações repetidas e únicas.- Você deve suportar pelo menos - CaptureRequest.JPEG_ORIENTATIONe- CaptureRequest.JPEG_QUALITY.- extensions-interface1.3.0 oferece suporte a chaves de solicitação e resultado, que são expostas pelos seguintes métodos:-  AdvancedExtenderImpl.getAvailableCaptureRequestKeys()
-  AdvancedExtenderImpl.getAvailableCaptureResultKeys()
 - Quando os desenvolvedores definem as chaves na lista - getAvailableCaptureRequestKeys, você deve habilitar os parâmetros e garantir que o resultado da captura contenha as chaves na lista- getAvailableCaptureResultKeys.
-  
- startTrigger- SessionProcessorImpl.startTrigger()é chamado para iniciar o acionador, como- CaptureRequest.CONTROL_AF_TRIGGERe- CaptureRequest.CONTROL_AE_PRECAPTURE_TRIGGER. Você pode desconsiderar quaisquer chaves de solicitação de captura que não foram anunciadas em- AdvancedExtenderImpl.getAvailableCaptureRequestKeys().- startTrigger()tem suporte desde- extensions-interface1.3.0. Ele permite que os aplicativos implementem o toque para focar e o flash com extensões.
- Limpar - Ao finalizar uma sessão de captura, - SessionProcessorImpl.onCaptureSessionEnd()é invocado antes de fechar- CameraCaptureSession. Após o fechamento da sessão de captura,- deInitSession()executa a limpeza.
Suporte para visualização, captura estática e análise de imagem
Você deve aplicar a extensão para os casos de uso de visualização e captura ainda. No entanto, se a latência for muito alta para mostrar a visualização sem problemas, você poderá aplicar o efeito apenas para captura estática.
 Para o tipo Basic Extender, independentemente de habilitar o efeito para visualização, você deve implementar ImageCaptureExtenderImpl e PreviewExtenderImpl para uma determinada extensão. Often, an app also uses a YUV stream to analyze the image content such as finding QR codes or text. To better support this use case , you should support the stream combination of preview, still capture, and a YUV_420_888 stream for configuring CameraCaptureSession . This means that if you implement a processor, then you have to support the stream combination of three YUV_420_888 streams.
 For Advanced Extender, Camera2/X passes three output surfaces to the SessionProcessorImpl.initSession() call. These output surfaces are for preview , still capture, and image analysis, respectively. You must ensure that preview and still capture output surfaces show the valid output. However, for the image analysis output surface, ensure it's working only when it's non-null. If your implementation can't support the image analysis stream, you can return an empty list in AdvancedExtenderImpl.getSupportedYuvAnalysisResolutions() . This ensures the image analysis output surface is always null in SessionProcessorImpl.initSession() .
Support video capture
 The current Camera Extension architecture supports only the preview and still capture use cases. We don't support enabling the extension on the MediaCodec or MediaRecorder surfaces for recording the video. However, it's possible for apps to record the preview output.
 Supporting MediaCodec and MediaRecorder surfaces is under investigation.
Extensions interface version history
The following table shows the Camera Extension interface version history. You should always implement the vendor library with the latest version.
| Version | Added features | 
|---|---|
| 1.0.0 | 
 | 
| 1.1.0 | 
 | 
| 1.2.0 | 
 | 
| 1.3.0 | 
 | 
Reference implementation
 For a reference OEM vendor library implementation, see camera-testlib-extensions . Note that this implementation performs passthroughs without actually implementing the effects.
Set up the vendor library on a device
 The OEM vendor library isn't built into an app; it's loaded from the device at runtime by Camera2/X. In CameraX, the <uses-library> tag declares that the androidx.camera.extensions.impl library, which is defined in the AndroidManifest.xml file of the camera-extensions library, is a dependency of CameraX and must be loaded at runtime. In Camera2, the framework loads an extensions service that also declares that the <uses-library> loads the same androidx.camera.extensions.impl library at runtime.
This allows third-party apps using extensions to automatically load the OEM vendor library. The OEM library is marked as optional so apps can run on devices that don't have the library on the device. Camera2/X handles this behavior automatically when an app tries to use a camera extension as long as the device manufacturer places the OEM library on the device so that it can be discovered by the app.
To set up the OEM library on a device, do the following:
-  Add a permission file, which is required by the <uses-library>tag, using the following format:/etc/permissions/ ANY_FILENAME .xml. For example,/etc/permissions/camera_extensions.xml. The files in this directory provide a mapping of the library named in<uses-library>to the actual file path on the device.
- Use the example below to add the required information to the file. -  namemust beandroidx.camera.extensions.implas that's the library that CameraX searches for.
-  fileis the absolute path of the file that contains the extensions implementation (for example,/system/framework/androidx.camera.extensions.impl.jar).
 - <?xml version="1.0" encoding="utf-8"?> <permissions> <library name="androidx.camera.extensions.impl" file="OEM_IMPLEMENTED_JAR" /> </permissions>
-  
 In Android 12 or higher, devices supporting CameraX extensions must have the ro.camerax.extensions.enabled property set to true , which allows for querying whether a device supports extensions. To do this, add the following line in the device make file:
PRODUCT_VENDOR_PROPERTIES += \
    ro.camerax.extensions.enabled=true \
Validation
 To test your implementation of the OEM vendor library during the development stage, use the example app at androidx-main/camera/integration-tests/extensionstestapp/ , which runs through various vendor extensions.
After you complete your implementation, use the Camera Extensions Validation Tool to run automated and manual tests to verify that the vendor library is implemented correctly.
Frequently asked questions (FAQs)
Are there any restrictions on API levels?
 Yes. This depends on the Android API feature set that's required by the OEM vendor library implementation. For example, ExtenderStateListener.onPresetSession() uses the SessionConfiguration.setSessionParameters() call to set a baseline set of tags. This call is available only on API level 28 and higher. For details on specific interface methods, see the API reference documentation .
