Android 9 introduces a new SystemApi interface called ImsService to help you implement IP Multimedia Subsystem (IMS). The ImsService API is a well-defined interface between the Android platform and a vendor or carrier-provided IMS implementation.
Figure 1. ImsService overview
By using the ImsService interface, the IMS implementer can provide important signaling information to the platform, such as IMS registration information, SMS over IMS integration, and MmTel feature integration to provide voice and video calling. The ImsService API is an Android System API as well, meaning it can be built against the Android SDK directly instead of against the source. An IMS application that has been pre-installed on the device can also be configured to be Play Store updatable.
Examples and source
Android provides an application on AOSP that implements portions of the ImsService API for testing and development purposes. You can find the application at /testapps/ImsTestService.
You can find the documentation for the ImsService API in ImsService and in the other classes in the API.
The ImsService API is a high level API that lets you implement IMS in many ways, depending on the hardware available. For example, the implementation changes depending on whether the IMS implementation is fully on the application processor or if it is partially or fully offloaded to the modem. Android does not provide a public HAL for offloading to the baseband processor, so any offloading must occur using your HAL extension to the modem.
Compatibility with older IMS implementations
Although Android 9 includes the ImsService API,
devices using an older implementation for IMS are not able to support the API.
For these devices, the older AIDL interfaces and wrapper classes have been moved
android.telephony.ims.compat namespace. When upgrading to Android
9, older devices must do the following to continue
the support of the older API.
- Change the namespace of the ImsService implementation to extend from the
- Modify the ImsService service definition in AndroidManifest.xml to use the
android.telephony.ims.compat.ImsServiceintent-filter action, instead of the
The framework will then bind to the ImsService using the compatibility layer
provided in Android 9 to work with the legacy
ImsService registration with the framework
The ImsService API is implemented as a service, which the Android framework
binds to in order to communicate with the IMS implementation. Three steps are
necessary to register an application that implements an ImsService with the
framework. First, the ImsService implementation must register itself with the
platform using the
AndroidManifest.xml of the application; second, it must
define which IMS features the implementation supports (MmTel or RCS); and third,
it must be verified as the trusted IMS implementation either in the carrier
configuration or device overlay.
The IMS application registers an ImsService with the framework by adding a
service entry into the manifest using the following format:
<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>
service definition in
AndroidManifest.xml defines the following
attributes, which are necessary for correct operation:
directBootAware="true": Allows the service to be discovered and run by
telephonybefore the user unlocks the device. The service can't access device encrypted storage before the user unlocks the device. For more information, see Support Direct Boot mode and File-Based Encryption.
persistent="true": Allows this service to be run persistently and not be killed by the system to reclaim memory. This attribute ONLY works if the application is built as a system application.
permission="android.permission.BIND_IMS_SERVICE": Ensures that only a process that has had the
BIND_IMS_SERVICEpermission granted to it can bind to the application. This prevents a rogue app from binding to the service, since only system applications can be granted the permission by the framework.
The service must also specify the
intent-filter element with the action
android.telephony.ims.ImsService. This allows the framework to find the
IMS feature specification
After the ImsService has been defined as an Android service in AndroidManifest.xml, the ImsService must define which IMS features it supports. Android currently supports the MmTel and RCS features, however only MmTel is integrated into the framework. Although there are no RCS APIs integrated into the framework, there are still advantages to declaring it as a feature of the ImsService.
Below are the valid features defined in
an ImsService can provide and an explanation and example as to why an IMS
application would want to implement one or all of these features. After each
feature is defined, this page outlines how the
ImsService declares the set of
features that it defines for each SIM slot.
ImsService implements the IMS MMTEL feature, which contains support for
all IMS media (IR.92 and IR.94 specifications) except emergency attach to the
IMS PDN for emergency calling. Any implementation of
ImsService that wishes to
support the MMTEL features should extend the
android.telephony.ims.MmTelFeature base class and return a custom
MmTelFeature implementation in
Declaring this feature only signals to the platform that emergency attach to the
IMS PDN for emergency services is possible. If this feature is not declared for
ImsService, the platform will always default to Circuit Switch Fallback
for emergency services. The
FEATURE_MMTEL feature must be defined for this
feature to be defined.
The ImsService API does not implement any IMS RCS features, but the
android.telephony.ims.RcsFeature base class can still be useful. The framework
automatically binds to the ImsService and calls
when it detects that the package should provide RCS. If the SIM card associated
with the RCS service is removed, the framework automatically calls
RcsFeature#onFeatureRemoved and then cleans up the
with the RCS feature. This functionality can remove some of the custom
detection/binding logic that an RCS feature would otherwise have to provide.
Registration of supported features
The telephony framework first binds to the ImsService to query the features that
it supports using the
ImsService#querySupportedImsFeatures API. After the
framework calculates which features the ImsService will support, it will call
ImsService#create[...]Feature for each feature that the ImsService will be
responsible for. If the features that the IMS application supports changes, you
ImsService#onUpdateSupportedImsFeatures to signal the framework to
recalculate supported features. See the diagram below for more information on
the initialization and binding of the ImsService.
Figure 2: ImsService initialization and binding
Framework detection and verification of an ImsService implementation
Once the ImsService has been defined correctly in AndroidManifest.xml, the platform must be configured to (securely) bind to the ImsService when appropriate. There are two types of ImsServices that the framework binds to:
- Carrier "override" ImsService: These ImsServices are preloaded onto the device but are attached to one or more cellular carriers and will only be bound when a matching SIM card is inserted. This is configured using the
- Device "default" ImsService: This is the default ImsService that is loaded onto the device by an OEM and should be designed to provide IMS services in all situations when a carrier ImsService is not available and is useful in situations where the device has no SIM card inserted or the SIM card inserted does not have a carrier ImsService installed with it. This is defined in the device overlay using the following configurations:
Android does not support apps with third-party downloadable ImsService implementations, so any ImsService implementations defined here are required to be System applications and must reside in the /system/priv-app/ or /product/priv-app/ folder to grant the appropriate permissions (namely phone, microphone, location, camera, and contacts permissions). By verifying whether the package name of the IMS implementation matches the CarrierConfig or device overlay values defined above, only trusted, pre-installed applications are bound.
Applications implementing an ImsService are only bound on devices where they
are configured as the carrier "override" ImsService or device "default"
ImsService configurations for MMTEL or RCS functionality.
The ImsService also allows the IMS features that it supports (MMTEL and RCS) to
be enabled or disabled dynamically via updates using the
ImsService#onUpdateSupportedImsFeatures method. This triggers the framework to
recalculate which ImsServices are bound and which features they support. If the
IMS application updates the framework with no features supported, the ImsService
will be unbound until the phone is rebooted or a new SIM card is inserted that
matches the IMS application.
Binding priority for multiple ImsService
The framework cannot support binding to all of the possible ImsServices that are preloaded onto the device and will bind to up to two ImsServices per SIM slot (one ImsService for each feature) in the following order on a per-feature basis:
- The ImsService package name defined by the CarrierConfig value
config_ims_[mmtel/rcs]_package_override_stringwhen there is a SIM card inserted.
- The ImsService package name defined in the device overlay value for
config_ims_[mmtel/rcs]_packageincluding the case where there is no SIM card inserted. This ImsService MUST support the Emergency MmTel feature.
You must either have the package name of your ImsService defined in the CarrierConfig for each of the carriers that will use that package or in the device overlay if your ImsService will be the default, as defined above.
Let's break this down for each feature. For a device (single or multi-SIM) with a single SIM card loaded, two IMS features are possible: MMTel and RCS. The framework will try to bind in the order defined above for each feature and if the feature is not available for the ImsService defined in the Carrier Configuration override, the framework will fallback to your default ImsService. So, for example, the table below describes which IMS feature the framework will use given three IMS applications implementing ImsServices installed on a system with the following features:
- Carrier A ImsService supports RCS
- Carrier B ImsService supports RCS and MMTel
- OEM ImsService supports RCS and MMTel
|SIM Card Inserted||RCS Feature||MMTel Feature|
|Carrier A||Carrier A||OEM|
|Carrier B||Carrier B||Carrier B|
Tools for verifying the IMS implementation itself are not included since the IMS specifications are extremely large and use special verification equipment. The tests can only verify that the telephony framework properly responds to the ImsService API.
Develop an IMS app
When developing an IMS app that interfaces with the Android telephony stack, we recommend specifying that the app can listen to or modify the state of the ImsService instance that is attached for a specific carrier subscription.
To listen to or modify the state of ImsService for MMTEL and RCS features, use
class to get an instance of the
class. The app can then listen to IMS-specific service and provisioning states
- MMTEL or RCS features that are enabled and available
- Updates when the IMS registration state changes
- Provisioning status of IMS features
- IMS features the user has enabled
Although ImsService is a persistently bound service, the service that's bound might change when a new SIM card or embedded subscription becomes active or when a carrier configuration changes. Because ImsService isn't part of the telephony process, an app might experience unanticipated exceptions when trying to access IMS APIs if ImsService invisibly crashes or is unbound because of a subscription or configuration change.
On devices running Android 13 or higher, to monitor
whether the ImsService instance for an associated subscription is
available or unavailable, an app can use the
class. When getting an instance of
recommend that the app first register for an IMS state callback using
To continue receiving callback updates for specific subscriptions when
ImsService becomes available again, the app must unregister or discard existing
callbacks registered through
ProvisioningManager; and register new callbacks.
If there's a subscription that doesn't support IMS, the framework calls
with the reason
This means that ImsService and the IMS-related APIs aren't available for the
In the unlikely event that the telephony process crashes, the app receives
and no longer receives updates on the registered
To recover from this condition, reregister the
ImsStateCallback instance for
the associated subscription by calling