Implementar IMS

O Android 9 apresenta uma nova interface SystemApi chamada ImsService para ajudar a implementar o IP Multimedia Subsystem (IMS). A API ImsService é uma interface bem definida entre a plataforma Android e a implementação de IMS de um 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 atualizável 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 é de alto nível e 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 está parcial ou totalmente descarregada 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 e classes de wrapper mais antigas do AIDL 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.

O framework vai se vincular ao ImsService usando a camada de compatibilidade fornecida no Android 9 para trabalhar 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. Depois, ela precisa definir a quais recursos IMS a implementação oferece suporte (MmTel ou RCS) e, por último, 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 tenha a permissão BIND_IMS_SERVICE concedida possa se vincular ao app. Isso evita que um app não autorizado seja vinculado ao serviço, já que apenas apps do sistema podem receber a permissão pelo 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, além de uma explicação e um exemplo de por que um app IMS poderia implementar um ou todos esses recursos. Depois que cada recurso é definido, esta página descreve como o ImsService declara o conjunto de recursos que ele define para cada slot de SIM.

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 Circuit Switch Fallback por padrão 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 RcsFeature#onFeatureRemoved automaticamente e limpar o ImsService associado ao recurso RCS. Essa funcionalidade pode remover parte da lógica de vinculação ou detecçã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 com suporte do app IMS mudarem, use ImsService#onUpdateSupportedImsFeatures para sinalizar o framework e recalcular 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. ImsService de "override" da operadora: esses ImsServices são pré-carregados no dispositivo, mas estão vinculados a uma ou mais operadoras de celular e só serão vinculados quando um cartão SIM 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 de terceiros definidas aqui. Portanto, todas as implementações do ImsService definidas aqui precisam ser apps do sistema e residir na pasta /system/priv-app/ ou /product/priv-app/ para conceder as permissões adequadas (ou seja, 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ó são vinculados em dispositivos em que são configurados como a ImsService "override" da operadora ou a ImsService "padrão" 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 com suporte, o ImsService será desvinculado até que o smartphone seja reinicializado ou que um novo chip corresponda ao app IMS seja inserido.

Prioridade de vinculação para vários ImsService

O framework não pode oferecer suporte à vinculação a todos os possíveis ImsServices que são pré-carregados no dispositivo e se vincula a até dois ImsServices por slot de SIM (um ImsService para cada recurso) na ordem a seguir por recurso:

  1. O nome do pacote ImsService definido pelo valor config_ims_[mmtel/rcs]_package_override_string de CarrierConfig quando há um chip 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. Esse ImsService PRECISA oferecer suporte ao recurso de chamada de emergência MmTel.

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 atributo. Em um dispositivo (com um ou vários chips) com um único cartão SIM carregado, dois recursos 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 do IMS o framework vai usar com três apps IMS que implementam o 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 IMS que o usuário ativou

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 imprevistas ao tentar acessar as APIs IMS se o ImsService falhar de forma invisível ou for desvinculado devido a uma mudança na assinatura ou na 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 ImsService for disponibilizado novamente, o app vai precisar cancelar o registro ou descartar os callbacks existentes registrados por ImsMmTelManager, ImsRcsManager ou ProvisioningManager, além de 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 uma falha no processo de telefonia, o app recebe ImsStateCallback#onError e deixa de receber atualizações na instância de ImsStateCallback registrada. Para recuperar essa condição, registre novamente a instância ImsStateCallback para a assinatura associada chamando ImsMmTelManager#registerImsStateCallback ou ImsRcsManager#registerImsStateCallback.