Implementar IMS

O Android 9 apresenta uma interface SystemApi chamada ImsService para ajudar a implementar o IMS (IP Multimedia Subsystem). A API ImsService é uma interface bem definida entre a plataforma Android e uma implementação IMS fornecida pelo fornecedor ou operadora.

Visão geral do ImsService

Figura 1. Visão geral do ImsService

Ao usar a interface ImsService, o implementador de IMS pode fornecer informações de sinalização importantes para a plataforma, como informações de registro IMS, integração de SMS via IMS e integração de recursos MmTel para fornecer chamadas de voz e vídeo. A API ImsService também é uma API do sistema Android, o que significa que ela pode ser criada diretamente no SDK do Android, em vez de na fonte. Um app IMS pré-instalado no dispositivo também pode ser configurado para ser atualizado pela Play Store.

Exemplos e origem

O Android oferece um app no AOSP que implementa partes da API ImsService para fins de teste e desenvolvimento. O app pode ser encontrado em /testapps/ImsTestService.

Encontre a documentação da API ImsService em ImsService e nas outras classes da API.

Implementação

A API ImsService é uma API de alto nível que permite implementar o IMS de várias maneiras, dependendo do hardware disponível. Por exemplo, a implementação muda dependendo se a implementação do IMS está totalmente no processador do app ou se ela é parcialmente ou totalmente transferida para o modem. O Android não oferece uma HAL pública para transferência para o processador de baseband. Portanto, qualquer transferência precisa ocorrer usando a extensão HAL para o modem.

Compatibilidade com implementações mais antigas do IMS

Embora o Android 9 inclua a API ImsService, os dispositivos que usam uma implementação mais antiga para IMS não podem oferecer suporte à API. Para esses dispositivos, as interfaces AIDL e classes de wrapper mais antigas foram movidas para o namespace android.telephony.ims.compat. Ao fazer upgrade para o Android 9, dispositivos mais antigos precisam fazer o seguinte para manter o suporte à API mais antiga.

  • Mude o namespace da implementação do ImsService para estender a API do namespace android.telephony.ims.compat.
  • Modifique a definição do serviço ImsService no AndroidManifest.xml para usar a ação de filtro de intent android.telephony.ims.compat.ImsService em vez da ação android.telephony.ims.ImsService.

Em seguida, o framework será vinculado ao ImsService usando a camada de compatibilidade fornecida no Android 9 para funcionar com a implementação ImsService legada.

Registro do ImsService com a estrutura

A API ImsService é implementada como um serviço, ao qual o framework do Android se vincula para se comunicar com a implementação do IMS. Três etapas são necessárias para registrar um app que implementa um ImsService com o framework. Primeiro, a implementação do ImsService precisa se registrar na plataforma usando o AndroidManifest.xml do app. Em segundo lugar, ela precisa definir quais recursos do IMS são compatíveis com a implementação (MmTel ou RCS). Em terceiro lugar, ela precisa ser verificada como a implementação confiável do IMS na configuração da operadora ou na sobreposição do dispositivo.

Definição do serviço

O app IMS registra um ImsService com o framework adicionando uma entrada service ao manifesto usando o seguinte formato:

<service
    android:name="com.egcorp.ims.EgImsService"
    android:directBootAware="true"
    Android:persistent="true"
    ...
    android:permission="android.permission.BIND_IMS_SERVICE" >
    ...
    <intent-filter>
        <action android:name="android.telephony.ims.ImsService" />
    </intent-filter>
</service>

A definição de service em AndroidManifest.xml define os seguintes atributos, que são necessários para a operação correta:

  • directBootAware="true": permite que o serviço seja descoberto e executado por telephony antes que o usuário desbloqueie o dispositivo. O serviço não pode acessar o armazenamento criptografado pelo dispositivo antes que o usuário desbloqueie o dispositivo. Para mais informações, consulte Suporte ao modo de inicialização direta e Criptografia baseada em arquivos.
  • persistent="true": permite que esse serviço seja executado de forma persistente e não seja interrompido pelo sistema para recuperar a memória. Esse atributo só funciona se o app for criado como um app do sistema.
  • permission="android.permission.BIND_IMS_SERVICE": garante que apenas um processo que recebeu a permissão BIND_IMS_SERVICE possa se vincular ao app. Isso impede que um app malicioso se vincule ao serviço, já que apenas apps do sistema podem receber a permissão do framework.

O serviço também precisa especificar o elemento intent-filter com a ação android.telephony.ims.ImsService. Isso permite que o framework encontre o ImsService.

Especificação do recurso IMS

Depois que o ImsService for definido como um serviço do Android no AndroidManifest.xml, ele precisará definir quais recursos do IMS são compatíveis. Atualmente, o Android oferece suporte aos recursos MmTel e RCS, mas apenas o MmTel é integrado ao framework. Embora não haja APIs RCS integradas ao framework, ainda há vantagens em declará-lo como um recurso do ImsService.

Confira abaixo os recursos válidos definidos em android.telephony.ims.ImsFeature que um ImsService pode fornecer e uma explicação e um exemplo de por que um app IMS implementaria um ou todos esses recursos. Após a definição de cada recurso, esta página descreve como a ImsService declara o conjunto de recursos definidos para cada slot de chip.

FEATURE_MMTEL

O ImsService implementa o recurso IMS MMTEL, que contém suporte a todos os meios de IMS (especificações IR.92 e IR.94), exceto a conexão de emergência ao PDN do IMS para chamadas de emergência. Qualquer implementação de ImsService que queira oferecer suporte aos recursos MMTEL precisa estender a classe base android.telephony.ims.MmTelFeature e retornar uma implementação MmTelFeature personalizada em ImsService#createMmTelFeature.

FEATURE_EMERGENCY_MMTEL

A declaração desse recurso apenas sinaliza para a plataforma que a conexão de emergência com o IMS PDN para serviços de emergência é possível. Se esse recurso não for declarado para o ImsService, a plataforma sempre vai usar o fallback de comutação de circuito para serviços de emergência. O recurso FEATURE_MMTEL precisa ser definido para que esse recurso seja definido.

FEATURE_RCS

A API ImsService não implementa nenhum recurso do IMS RCS, mas a classe de base android.telephony.ims.RcsFeature ainda pode ser útil. O framework se vincula automaticamente ao ImsService e chama ImsService#createRcsFeature quando detecta que o pacote precisa fornecer RCS. Se o chip associado ao serviço RCS for removido, o framework vai chamar automaticamente RcsFeature#onFeatureRemoved e limpar o ImsService associado ao recurso RCS. Essa funcionalidade pode remover parte da lógica de detecção ou vinculação personalizada que um recurso RCS teria que fornecer.

Registro de recursos compatíveis

O framework de telefonia se vincula primeiro ao ImsService para consultar os recursos com suporte usando a API ImsService#querySupportedImsFeatures. Depois que o framework calcula quais recursos o ImsService vai oferecer suporte, ele chama ImsService#create[...]Feature para cada recurso pelo qual o ImsService será responsável. Se os recursos compatíveis com o app IMS mudarem, você poderá usar ImsService#onUpdateSupportedImsFeatures para indicar ao framework que recalcule os recursos com suporte. Consulte o diagrama a seguir para mais informações sobre a inicialização e a vinculação do ImsService.

Inicialização e vinculação do ImsService

Figura 2:inicialização e vinculação do ImsService

Detecção e verificação de framework de uma implementação do ImsService

Depois que o ImsService for definido corretamente no AndroidManifest.xml, a plataforma precisará ser configurada para se vincular (com segurança) ao ImsService quando apropriado. Há dois tipos de ImsServices aos quais o framework se vincula:

  1. O ImsService da operadora "substitui": esses ImsServices são pré-carregados no dispositivo, mas estão anexados a uma ou mais operadoras de celular e só serão vinculados quando um chip correspondente for inserido. Isso é configurado usando o
  2. ImsService "padrão" do dispositivo: é o ImsService padrão que é carregado no dispositivo por um OEM e precisa ser projetado para fornecer serviços IMS em todas as situações em que um ImsService da operadora não está disponível e é útil em situações em que o dispositivo não tem um chip inserido ou o chip inserido não tem um ImsService da operadora instalado. Isso é definido na sobreposição do dispositivo usando as seguintes configurações:

O Android não oferece suporte a apps com implementações ImsService para download de terceiros. Portanto, todas as implementações ImsService definidas aqui precisam ser apps do sistema e precisam residir na pasta /system/priv-app/ ou /product/priv-app/ para conceder as permissões adequadas, como permissões de telefone, microfone, localização, câmera e contatos. Ao verificar se o nome do pacote da implementação do IMS corresponde aos valores de sobreposição do CarrierConfig ou do dispositivo definidos acima, apenas os apps confiáveis pré-instalados são vinculados.

Personalização

Os apps que implementam um ImsService são vinculados apenas em dispositivos em que são configurados como a "substituição" do ImsService da operadora ou as configurações "padrão" do ImsService do dispositivo para a funcionalidade MMTEL ou RCS. O ImsService também permite que os recursos IMS compatíveis (MMTEL e RCS) sejam ativados ou desativados dinamicamente usando atualizações com o método ImsService#onUpdateSupportedImsFeatures. Isso aciona o framework para recalcular quais ImsServices estão vinculados e quais recursos são compatíveis. Se o app IMS atualizar o framework sem recursos compatíveis, o ImsService será desvinculado até que o telefone seja reinicializado ou um novo chip SIM seja inserido que corresponda ao app IMS.

Prioridade de vinculação para vários ImsService

O framework não oferece suporte à vinculação a todos os ImsServices possíveis que estão pré-carregados no dispositivo e vão vincular até dois ImsServices por slot do chip (um ImsService para cada recurso) na seguinte ordem em cada recurso:

  1. O nome do pacote ImsService definido pelo valor CarrierConfig config_ims_[mmtel/rcs]_package_override_string quando há um cartão SIM inserido.
  2. O nome do pacote ImsService definido no valor de sobreposição do dispositivo para config_ims_[mmtel/rcs]_package, incluindo o caso em que não há um cartão SIM inserido. Este ImsService PRECISA ser compatível com o recurso de comunicação de emergência.

O nome do pacote do ImsService precisa estar definido na CarrierConfig para cada uma das operadoras que vão usar esse pacote ou na sobreposição do dispositivo, se o ImsService for o padrão, conforme definido acima.

Vamos detalhar isso para cada recurso. Para um dispositivo (um ou vários chips) com um único chip carregado, dois recursos de IMS são possíveis: MMTel e RCS. O framework vai tentar se vincular na ordem definida acima para cada recurso. Se o recurso não estiver disponível para o ImsService definido na substituição de configuração do operador, o framework vai usar o ImsService padrão. Por exemplo, a tabela abaixo descreve qual recurso IMS o framework vai usar, considerando três apps IMS que implementam ImsServices instalados em um sistema com os seguintes recursos:

  • O Carrier A ImsService oferece suporte a RCS
  • O Carrier B ImsService oferece suporte a RCS e MMTel
  • O OEM ImsService oferece suporte a RCS e MMTel
Chip inserido Recurso RCS Recurso MMTel
Operadora A Operadora A Driver OEM
Operadora B Operadora B Operadora B
Sem chip Driver OEM Driver OEM

Validação

As ferramentas para verificar a implementação do IMS não são incluídas, porque as especificações do IMS são extremamente grandes e usam equipamentos de verificação especiais. Os testes só podem verificar se o framework de telefonia responde corretamente à API ImsService.

Desenvolver um app IMS

Ao desenvolver um app IMS que interage com a pilha de telefonia do Android, recomendamos especificar que o app pode detectar ou modificar o estado da instância do ImsService anexada a uma assinatura específica da operadora.

Para detectar ou modificar o estado do ImsService para recursos de MMTEL e RCS, use a classe ImsManager para receber uma instância da classe ImsMmTelManager, ImsRcsManager ou ProvisioningManager específica do IMS. O app pode detectar estados de serviço e provisionamento específicos do IMS, como:

  • Recursos MMTEL ou RCS ativados e disponíveis
  • Atualiza quando o estado do registro do IMS muda
  • Status do provisionamento dos recursos do IMS
  • Recursos do IMS ativados pelo usuário

Usar ImsStateCallback

Embora o ImsService seja um serviço vinculado de forma persistente, o serviço vinculado pode mudar quando um novo cartão SIM ou uma assinatura integrada é ativada ou quando a configuração de uma operadora muda. Como o ImsService não faz parte do processo de telefonia, um app pode apresentar exceções inesperadas ao tentar acessar APIs IMS se o ImsService falhar de forma invisível ou for desvinculado devido a uma assinatura ou mudança de configuração.

Em dispositivos com o Android 13 ou mais recente, para monitorar se a instância do ImsService para uma assinatura associada está disponível ou não, um app pode usar a classe ImsStateCallback. Ao receber uma instância de ImsMmTelManager ou ImsRcsManager, recomendamos que o app primeiro se registre para um callback de estado do IMS usando ImsMmTelManager#registerImsStateCallback ou ImsRcsManager#registerImsStateCallback. Para continuar recebendo atualizações de callback para assinaturas específicas quando o ImsService estiver disponível novamente, o app precisa cancelar o registro ou descartar os callbacks registrados com ImsMmTelManager, ImsRcsManager ou ProvisioningManager e registrar novos callbacks.

Se houver uma assinatura que não ofereça suporte ao IMS, o framework vai chamar ImsStateCallback#onUnavailable com o motivo REASON_NO_IMS_SERVICE_CONFIGURED. Isso significa que o ImsService e as APIs relacionadas ao IMS não estão disponíveis para a assinatura.

No caso improvável de o processo de telefonia falhar, o app vai receber ImsStateCallback#onError e não vai mais receber atualizações na instância ImsStateCallback registrada. Para se recuperar dessa condição, registre novamente a instância ImsStateCallback da assinatura associada chamando ImsMmTelManager#registerImsStateCallback ou ImsRcsManager#registerImsStateCallback.