Implementar IMS

O Android 9 apresenta uma interface SystemApi chamada ImsService para ajudar você a implementar o subsistema multimídia IP (IMS). A API ImsService é uma interface bem definida entre a plataforma Android e uma implementação de IMS fornecida por um fornecedor ou operadora.

Visão geral do ImsService

Figura 1. Visão geral do ImsService

Ao usar a interface ImsService, o implementador do IMS pode fornecer informações de sinalização importantes à plataforma, como informações de registro do IMS, integração de SMS pelo IMS e integração de recursos MmTel para oferecer 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 origem. 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.

A documentação da API ImsService está disponível 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á parcialmente ou totalmente descarregada para o modem. O Android não fornece uma HAL pública para descarregar no processador de banda de base. Portanto, qualquer descarregamento precisa ocorrer usando sua extensão HAL para o modem.

Compatibilidade com implementações de IMS mais antigas

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

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

Em seguida, o framework vai se vincular ao ImsService usando a camada de compatibilidade fornecida no Android 9 para trabalhar com a implementação legada do ImsService.

Registro do ImsService com o framework

A API ImsService é implementada como um serviço que o framework Android 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. Segundo, ela precisa definir quais recursos do IMS são compatíveis com a implementação (MmTel ou RCS). Terceiro, 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 de 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 pelo telephony antes de o usuário desbloquear 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 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 pode 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 da estrutura.

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 do IMS

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

A seguir, estão os recursos válidos definidos em android.telephony.ims.ImsFeature que um ImsService pode oferecer, além de uma explicação e um exemplo de por que um app IMS implementaria 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 MMTEL do IMS, que oferece suporte a todas as mídias do IMS (especificações IR.92 e IR.94), exceto a conexão de emergência ao IMS PDN para chamadas de emergência. Qualquer implementação de ImsService que queira oferecer suporte aos recursos do MMTEL precisa estender a classe base android.telephony.ims.MmTelFeature e retornar uma implementação personalizada de MmTelFeature em ImsService#createMmTelFeature.

FEATURE_EMERGENCY_MMTEL

Declarar esse recurso apenas sinaliza para a plataforma que é possível fazer uma conexão de emergência com a PDN do IMS para serviços de emergência. Se esse recurso não for declarado para seu ImsService, a plataforma sempre usará o fallback de comutação de circuito para serviços de emergência. O recurso FEATURE_MMTEL precisa ser definido para que este recurso seja definido.

FEATURE_RCS

A API ImsService não implementa nenhum recurso do IMS RCS, mas a classe 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, a estrutura 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 do RCS precisaria fornecer.

Registro de recursos compatíveis

Primeiro, a estrutura de telefonia se vincula ao ImsService para consultar os recursos que ele oferece 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 de que o ImsService será responsável. Se os recursos compatíveis com o app IMS mudarem, você poderá usar ImsService#onUpdateSupportedImsFeatures para sinalizar ao framework que recalcule os recursos compatíveis. 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 vincular (com segurança) ao ImsService quando apropriado. Há dois tipos de ImsServices aos quais o framework se vincula:

  1. Substituição da operadora ImsService: 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 carregado no dispositivo por um OEM e projetado para fornecer serviços de IMS em todas as situações em que um ImsService da operadora não está disponível. Ele é ú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 é compatível com apps que têm implementações de ImsService para download de terceiros. Portanto, todas as implementações de ImsService definidas aqui precisam ser apps do sistema e estar na pasta /system/priv-app/ ou /product/priv-app/ para conceder as permissões adequadas (ou seja, 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 CarrierConfig ou de sobreposição do dispositivo definidos acima, apenas apps confiáveis e pré-instalados são vinculados.

Personalização

Os apps que implementam um ImsService só são vinculados em dispositivos em que estão configurados como as configurações de ImsService "substituir" da operadora ou "padrão" do dispositivo para funcionalidade MMTEL ou RCS. O ImsService também permite que os recursos do 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 eles oferecem suporte. Se o app IMS atualizar o framework sem recursos compatíveis, o ImsService será desvinculado até que o smartphone seja reiniciado ou um novo chip seja inserido e corresponda ao app IMS.

Prioridade de vinculação para vários ImsService

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

  1. O nome do pacote ImsService definido pelo valor CarrierConfig config_ims_[mmtel/rcs]_package_override_string 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 chip inserido. Esse ImsService PRECISA ser compatível com o recurso de MmTel de emergência.

Você precisa ter o nome do pacote do seu ImsService definido no 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 cada recurso. Em um dispositivo (com um ou vários chips) com um único chip inserido, dois recursos IMS são possíveis: MMTel e RCS. O framework tentará fazer a vinculação na ordem definida acima para cada recurso e, se o recurso não estiver disponível para o ImsService definido na substituição da configuração da operadora, o framework vai usar o ImsService padrão. Por exemplo, a tabela abaixo descreve qual recurso do IMS a estrutura vai usar considerando três apps do IMS que implementam ImsServices instalados em um sistema com os seguintes recursos:

  • O ImsService da operadora A é compatível com RCS
  • O ImsService da operadora B é compatível com RCS e MMTel
  • O ImsService do OEM é compatível com RCS e MMTel.
Chip inserido Recurso do 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 estão incluídas porque as especificações do IMS são muito grandes e usam equipamentos especiais de verificação. Os testes só podem verificar se a estrutura de telefonia responde corretamente à API ImsService.

Desenvolver um app do IMS

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

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

  • Recursos de MMTEL ou RCS ativados e disponíveis
  • Atualiza quando o estado do registro de IMS muda
  • Status do provisionamento dos recursos do IMS
  • Recursos do 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 chip ou assinatura incorporada é ativado ou quando uma configuração da operadora muda. Como o ImsService não faz parte do processo de telefonia, um app pode ter exceções inesperadas ao tentar acessar APIs IMS se o ImsService falhar ou for desvinculado de forma invisível devido a uma mudança de assinatura ou configuração.

Em dispositivos com Android 13 ou mais recente, para monitorar se a instância do ImsService de 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 de assinaturas específicas quando o ImsService estiver disponível novamente, o app precisa cancelar o registro ou descartar os callbacks registrados por ImsMmTelManager, ImsRcsManager ou ProvisioningManager e registrar novos callbacks.

Se houver uma assinatura que não seja compatível com o 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 falha no processo de telefonia, o app recebe ImsStateCallback#onError e não recebe mais atualizações na instância ImsStateCallback registrada. Para se recuperar dessa condição, registre novamente a instância ImsStateCallback na assinatura associada chamando ImsMmTelManager#registerImsStateCallback ou ImsRcsManager#registerImsStateCallback.