IMS 구현

Android 9에는 IP 멀티미디어 하위 시스템(IMS)의 구현을 돕기 위해 ImsService라는 새 SystemApi 인터페이스가 도입되었습니다. ImsService API는 Android 플랫폼과 공급업체 또는 이동통신사가 제공하는 IMS 구현 간의 잘 정의된 인터페이스입니다.

ImsService 개요

그림 1. ImsService 개요

IMS 구현자는 ImsService 인터페이스를 사용하여 중요한 신호 정보(예: IMS 등록 정보, IMS 통합 상의 SMS 및 음성/영상 통화 제공을 위한 MmTel 기능 통합)를 플랫폼에 제공할 수 있습니다. 또한 ImsService API는 Android 시스템 API이기 때문에 소스가 아닌 Android SDK에서 직접 빌드할 수 있습니다. 기기에 사전 설치된 IMS 애플리케이션은 Play 스토어에서 업데이트하도록 구성할 수도 있습니다.

예시 및 소스

Android는 AOSP에서 테스트 및 개발 목적으로 ImsService API의 일부를 구현하는 애플리케이션을 제공합니다. 이 애플리케이션은 /testapps/ImsTestService에서 볼 수 있습니다.

ImsService API 문서는 ImsService와 API의 다른 클래스에서 찾을 수 있습니다.

구현

ImsService API는 사용 가능한 하드웨어에 따라 다양한 방법으로 IMS를 구현할 수 있게 하는 상위 수준의 API입니다. 예를 들어, 구현은 IMS 구현 전체가 애플리케이션 프로세서에 있는지에 따라 또는 모뎀에 부분 또는 전체적으로 오프로드되었는지에 따라 달라집니다. Android는 베이스밴드 프로세서에 오프로드하기 위한 공개 HAL을 제공하지 않으므로 모든 오프로드는 모뎀에 대한 HAL 확장 프로그램을 사용해야 합니다.

이전 IMS 구현과의 호환성

Android 9에 ImsService API가 포함되어 있지만, 이전의 IMS 구현을 사용하는 기기는 API를 지원할 수 없습니다. 이러한 기기를 위해 이전의 AIDL 인터페이스와 래퍼 클래스가 android.telephony.ims.compat 네임스페이스로 이동했습니다. Android 9로 업그레이드할 때 이전 API를 계속 지원하려면 이전 기기에서 다음을 실행해야 합니다.

  • android.telephony.ims.compat 네임스페이스 API에서 확장하기 위해 ImsService 구현의 네임스페이스 변경
  • android.telephony.ims.ImsService 작업 대신 android.telephony.ims.compat.ImsService 인텐트-필터 작업을 사용하도록 AndroidManifest.xml의 ImsService 서비스 정의 수정

그런 다음 프레임워크는 기존 ImsService 구현으로 작업하기 위해 Android 9에서 제공한 호환성 레이어를 사용하여 ImsService에 바인딩합니다.

프레임워크에 ImsService 등록

ImsService API는 IMS 구현과 통신하기 위해 Android 프레임워크가 바인딩하는 서비스로 구현됩니다. ImsService를 구현하는 애플리케이션을 프레임워크에 등록하려면 세 단계를 거쳐야 합니다. 첫째, ImsService 구현은 애플리케이션의 AndroidManifest.xml을 사용하여 플랫폼에 ImsService 구현 자체를 등록해야 합니다. 둘째, ImsService 구현에서 지원하는 IMS 기능(MmTel 또는 RCS)을 정의해야 합니다. 셋째, ImsService 구현은 이동통신사 구성 또는 기기 오버레이에서 신뢰할 수 있는 IMS 구현으로 인증을 받아야 합니다.

서비스 정의

IMS 애플리케이션은 다음 형식을 사용하여 매니페스트에 service 항목을 추가하는 방식으로 프레임워크에 ImsService를 등록합니다.

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

AndroidManifest.xmlservice 정의는 올바른 작업에 필요한 다음 속성을 정의합니다.

  • directBootAware="true": 사용자가 기기를 잠금 해제하기 전에 telephony로 서비스를 검색하고 실행할 수 있습니다. 서비스는 사용자가 기기를 잠금 해제하기 전에 암호화된 기기 저장소에 액세스할 수 없습니다. 자세한 내용은 직접 부팅 지원 모드파일 기반 암호화를 참조하세요.
  • persistent="true": 이 서비스를 지속해서 실행하며 시스템에서 메모리를 회수할 목적으로 서비스를 종료하지 못하게 합니다. 이 속성은 애플리케이션이 시스템 애플리케이션으로 빌드된 경우에만 작동합니다.
  • permission="android.permission.BIND_IMS_SERVICE": BIND_IMS_SERVICE 권한을 가진 프로세스만 애플리케이션에 바인딩할 수 있도록 합니다. 이는 프레임워크에서 시스템 애플리케이션에만 권한을 부여하므로 허가받지 않은 앱이 서비스에 바인딩하는 것을 방지합니다.

또한, 서비스는 android.telephony.ims.ImsService 작업을 사용하여 intent-filter 요소를 지정해야 합니다. 이렇게 하면 프레임워크에서 ImsService를 찾을 수 있습니다.

IMS 기능 사양

ImsService가 AndroidManifest.xml에 Android 서비스로 정의되면 ImsService는 ImsService에서 지원하는 기능을 정의해야 합니다. 현재 Android는 MmTel과 RCS 기능을 지원하지만, MmTel만 프레임워크에 통합되어 있습니다. 프레임워크에 통합된 RCS API는 없지만, RCS를 ImsService의 기능으로 선언하면 이점이 있습니다.

아래는 ImsService가 제공할 수 있는 android.telephony.ims.ImsFeature에 정의된 유효한 기능과 IMS 애플리케이션이 이러한 기능의 하나 또는 모두를 구현하려는 이유에 관한 설명 및 예입니다. 각 기능을 정의하고 난 후 이 페이지는 ImsService에서 각 SIM 슬롯에 정의한 기능 집합을 선언하는 방법에 관한 개요를 제공합니다.

FEATURE_MMTEL

ImsService는 긴급 전화용 IMS PDN으로의 긴급 연결을 제외한 모든 IMS 미디어(IR.92 및 IR.94 사양)를 지원하는 IMS MMTEL 기능을 구현합니다. MMTEL 기능을 지원하려는 모든 ImsService 구현은 android.telephony.ims.MmTelFeature 기본 클래스를 확장하고 ImsService#createMmTelFeature의 맞춤 MmTelFeature 구현을 반환해야 합니다.

FEATURE_EMERGENCY_MMTEL

이 기능을 선언하는 것은 응급 서비스용 IMS PDN으로 긴급 연결이 가능하다고 플랫폼에 신호를 보내는 것에 불과합니다. 이 기능이 ImsService에 선언되지 않으면 플랫폼은 항상 응급 서비스용 회로 스위치 폴백(Circuit Switch Fallback)을 기본값으로 사용합니다. 이 기능을 정의하려면 FEATURE_MMTEL 기능이 정의되어야 합니다.

FEATURE_RCS

ImsService API는 IMS RCS 기능을 구현하지 않지만, android.telephony.ims.RcsFeature 기본 클래스는 유용할 수 있습니다. 프레임워크는 패키지에서 RCS를 제공해야 한다고 감지하면 자동으로 ImsService에 바인딩하고 ImsService#createRcsFeature를 호출합니다. RCS 서비스와 연결된 SIM 카드가 삭제되면 프레임워크는 자동으로 RcsFeature#onFeatureRemoved를 호출한 다음 RCS 기능과 연결된 ImsService를 정리합니다. 이 기능은 RCS 기능에서 제공해야 하는 맞춤 감지/바인딩 로직의 일부를 삭제할 수 있습니다.

지원되는 기능 등록

텔레포니 프레임워크는 먼저 ImsService에 바인딩하여 ImsService가 ImsService#querySupportedImsFeatures API를 사용하여 지원하는 기능을 쿼리합니다. 프레임워크는 ImsService가 지원할 기능을 계산한 후 ImsService에서 담당할 각 기능에 ImsService#create[...]Feature를 호출합니다. IMS 애플리케이션이 지원하는 기능이 변경되면 ImsService#onUpdateSupportedImsFeatures를 사용하여 지원되는 기능을 다시 계산하도록 프레임워크에 신호를 보낼 수 있습니다. ImsService의 초기화 및 바인딩에 관한 자세한 내용은 아래 다이어그램을 참조하세요.

ImsService 초기화 및 바인딩

그림 2: ImsService 초기화 및 바인딩

프레임워크에서 ImsService 구현 감지 및 확인

AndroidManifest.xml에 ImsService가 올바르게 정의되었다면 적절한 시점에 ImsService에 (안전하게) 바인딩되도록 플랫폼을 구성해야 합니다. 프레임워크가 바인딩하는 ImsService에는 다음과 같이 두 가지 유형이 있습니다.

  1. 이동통신사 '재정의' ImsService: 이러한 ImsService는 기기에 미리 로드되지만, 하나 이상의 모바일 이동통신사에 연결되며 일치하는 SIM 카드가 삽입될 때만 바인딩됩니다. 이는 다음을 사용하여 구성됩니다.
  2. 기기 '기본값' ImsService: OEM에서 기기에 로드하는 기본 ImsService로, 이동통신사 ImsService를 사용할 수 없는 모든 상황에서 IMS 서비스를 제공하도록 설계되어야 하며 기기에 삽입된 SIM 카드가 없거나 삽입된 SIM 카드에 이동통신사 ImsService가 설치되어 있지 않은 경우에 유용합니다. 이는 다음 구성을 사용하여 기기 오버레이에 정의됩니다.

Android는 서드 파티의 다운로드 가능한 ImsService 구현이 있는 앱을 지원하지 않으므로 여기 정의된 모든 ImsService 구현은 시스템 애플리케이션이어야 하며 적절한 권한(예: 전화, 마이크, 위치, 카메라, 연락처 권한)을 제공하기 위해 /system/priv-app/ 또는 /product/priv-app/ 폴더에 있어야 합니다. IMS 구현의 패키지 이름이 위에 정의된 CarrierConfig 또는 기기 오버레이 값과 일치하는지 확인한 다음 신뢰할 수 있고 미리 설치된 애플리케이션만 바인딩됩니다.

맞춤설정

ImsService를 구현하는 애플리케이션은 이동통신사 '재정의' ImsService 또는 MMTEL이나 RCS 기능의 기기 '기본' ImsService 구성으로 구성된 기기에만 바인딩됩니다. 또한 ImsService를 사용하면 ImsService가 지원하는 IMS 기능(MMTEL 및 RCS)을 ImsService#onUpdateSupportedImsFeatures 메서드를 사용한 업데이트를 통해 동적으로 사용 설정하거나 중지할 수 있습니다. 그러면 프레임워크는 바인딩되는 ImsService와 이러한 ImsService에서 지원하는 기능을 다시 계산합니다. 지원되는 기능이 없는 프레임워크를 IMS 애플리케이션에서 업데이트하면 ImsService는 스마트폰이 재부팅되거나 IMS 애플리케이션과 일치하는 새 SIM 카드가 삽입될 때까지 바인딩이 해제됩니다.

여러 ImsService 간의 바인딩 우선순위

프레임워크는 기기에 미리 로드된 사용 가능한 모든 ImsService에 대한 바인딩을 지원할 수 없으며, 기능별로 다음 순서에 따라 SIM 슬롯당 최대 2개의 ImsService(기능별로 ImsService 1개)를 바인딩합니다.

  1. CarrierConfig 값 config_ims_[mmtel/rcs]_package_override_string으로 정의된 ImsService 패키지 이름(삽입된 SIM 카드가 있을 때)
  2. config_ims_[mmtel/rcs]_package의 기기 오버레이 값에 정의된 ImsService 패키지 이름(삽입된 SIM 카드가 없는 경우 포함). 이 ImsService는 긴급 MmTel 기능을 지원해야 함

위에 정의한 대로 ImsService가 기본값이 된다면 ImsService의 패키지 이름을 패키지를 사용하는 각 이동통신사의 CarrierConfig 또는 기기 오버레이에 정의해야 합니다.

이에 관해 구체적으로 설명해 보겠습니다. 단일 SIM 카드가 로드된 기기(단일 또는 멀티 SIM)의 경우 MMTel 및 RCS의 두 가지 IMS 기능이 가능합니다. 프레임워크는 각 기능에 관해 위에 정의된 순서대로 바인딩을 시도하고 이동통신사 구성 재정의에서 정의한 ImsService에서 사용할 수 없는 기능인 경우 기본 ImsService로 대체합니다. 예를 들어, 아래 표는 프레임워크에서 사용할 IMS 기능을 설명하며 이러한 기능은 아래 기능을 사용하여 시스템에 설치된 ImsService를 구현하는 세 개의 IMS 애플리케이션을 통해 제공됩니다.

  • 이동통신사 A의 ImsService는 RCS를 지원함
  • 이동통신사 B의 ImsService는 RCS 및 MMTel을 지원함
  • OEM의 ImsService는 RCS 및 MMTel을 지원함
삽입된 SIM 카드 RCS 기능 MMTel 기능
이동통신사 A 이동통신사 A OEM
이동통신사 B 이동통신사 B 이동통신사 B
SIM 없음 OEM OEM

유효성 검사

IMS 사양은 매우 크고 특별한 인증 장비를 사용하므로 IMS 구현 자체를 인증하는 도구는 포함되어 있지 않습니다. 테스트에서는 텔레포니 프레임워크가 ImsService API에 제대로 응답하는지만 확인할 수 있습니다.

IMS 앱 개발

Android 텔레포니 스택과 인터페이스하는 IMS 앱을 개발할 때는 앱이 특정 이동통신사 구독을 위해 연결된 ImsService 인스턴스의 상태를 리슨하거나 수정할 수 있음을 지정하는 것이 좋습니다.

MMTEL 및 RCS 기능에 대해 ImsService 상태를 리슨하거나 수정하려면 ImsManager 클래스를 사용하여 ImsMmTelManager, ImsRcsManager 또는 IMS 관련 ProvisioningManager 클래스의 인스턴스를 가져옵니다. 그러면 앱은 다음과 같은 IMS 관련 서비스 및 프로비저닝 상태를 리슨할 수 있습니다.

  • 사용 설정되고 사용 가능한 MMTEL 또는 RCS 기능
  • IMS 등록 상태의 변경 업데이트
  • IMS 기능의 프로비저닝 상태
  • 사용자가 사용 설정한 IMS 기능

ImsStateCallback 사용

ImsService는 영구적으로 바인드된 서비스이지만, 새로운 SIM 카드 또는 임베디드 구독이 활성화되거나 이동통신사 구성이 변경되면 바인드된 서비스가 변경될 수 있습니다. ImsService는 텔레포니 프로세스의 일부가 아니므로 ImsService가 구독 또는 구성 변경으로 인해 자동 비정상 종료되거나 바인딩 해제되는 경우 앱에서 IMS API에 액세스하려고 할 때 예기치 않은 예외가 발생할 수 있습니다.

Android 13 이상을 실행하는 기기에서는 앱이 ImsStateCallback 클래스를 사용하여 연결된 구독의 ImsService 인스턴스가 사용 가능한지 모니터링할 수 있습니다. ImsMmTelManager 또는ImsRcsManager의 인스턴스를 가져올 때는 앱에서 먼저 ImsMmTelManager#registerImsStateCallback 또는ImsRcsManager#registerImsStateCallback을 사용하여 IMS 상태 콜백을 등록하는 것이 좋습니다. ImsService를 다시 사용할 수 있게 되었을 때 계속해서 특정 구독의 콜백 업데이트를 받으려면 앱은 ImsMmTelManager, ImsRcsManager 또는 ProvisioningManager를 통해 등록된 기존 콜백을 등록 취소하거나 삭제하고 새 콜백을 등록해야 합니다.

IMS를 지원하지 않는 구독이 있는 경우 프레임워크는 REASON_NO_IMS_SERVICE_CONFIGURED라는 이유를 사용하여 ImsStateCallback#onUnavailable을 호출합니다. 이는 이 구독에서 ImsService 및 IMS 관련 API를 사용할 수 없음을 의미합니다.

드물게 텔레포니 프로세스가 비정상 종료되는 경우 앱은 ImsStateCallback#onError를 수신하고 더 이상 등록된 ImsStateCallback 인스턴스에 관한 업데이트를 수신하지 않습니다. 이 조건에서 원복되려면 ImsMmTelManager#registerImsStateCallback 또는 ImsRcsManager#registerImsStateCallback을 호출하여 연결된 구독의 ImsStateCallback 인스턴스를 다시 등록합니다.