FileDocCategorySizeDatePackage
ImsManager.javaAPI DocAndroid 5.1 API32627Thu Mar 12 22:22:52 GMT 2015com.android.ims

ImsManager

public class ImsManager extends Object
Provides APIs for IMS services, such as initiating IMS calls, and provides access to the operator's IMS network. This class is the starting point for any IMS actions. You can acquire an instance of it with {@link #getInstance getInstance()}.

The APIs in this class allows you to:

hide

Fields Summary
public static final String
PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE
public static final int
PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT
public static final String
PROPERTY_DBG_VT_AVAIL_OVERRIDE
public static final int
PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT
private static final String
IMS_SERVICE
For accessing the IMS related service. Internal use only.
public static final int
INCOMING_CALL_RESULT_CODE
The result code to be sent back with the incoming call {@link PendingIntent}.
public static final String
EXTRA_CALL_ID
Key to retrieve the call ID from an incoming call intent.
public static final String
ACTION_IMS_SERVICE_UP
Action to broadcast when ImsService is up. Internal use only.
public static final String
ACTION_IMS_SERVICE_DOWN
Action to broadcast when ImsService is down. Internal use only.
public static final String
EXTRA_PHONE_ID
Part of the ACTION_IMS_SERVICE_UP or _DOWN intents. A long value; the phone ID corresponding to the IMS service coming up or down. Internal use only.
public static final String
ACTION_IMS_INCOMING_CALL
Action for the incoming call intent for the Phone app. Internal use only.
public static final String
EXTRA_SERVICE_ID
Part of the ACTION_IMS_INCOMING_CALL intents. An integer value; service identifier obtained from {@link ImsManager#open}. Internal use only.
public static final String
EXTRA_USSD
Part of the ACTION_IMS_INCOMING_CALL intents. An boolean value; Flag to indicate that the incoming call is a normal call or call for USSD. The value "true" indicates that the incoming call is for USSD. Internal use only.
private static final String
TAG
private static final boolean
DBG
private static HashMap
sImsManagerInstances
private android.content.Context
mContext
private int
mPhoneId
private com.android.ims.internal.IImsService
mImsService
private ImsServiceDeathRecipient
mDeathRecipient
private ImsUt
mUt
private ImsConfig
mConfig
private ImsEcbm
mEcbm
Constructors Summary
private ImsManager(android.content.Context context, int phoneId)

        mContext = context;
        mPhoneId = phoneId;
        createImsService(true);
    
Methods Summary
private voidcheckAndThrowExceptionIfServiceUnavailable()
Binds the IMS service only if the service is not created.

        if (mImsService == null) {
            createImsService(true);

            if (mImsService == null) {
                throw new ImsException("Service is unavailable",
                        ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
            }
        }
    
public voidclose(int serviceId)
Closes the specified service ({@link ImsServiceClass}) not to make/receive calls. All the resources that were allocated to the service are also released.

param
serviceId a service id to be closed which is obtained from {@link ImsManager#open}
throws
ImsException if calling the IMS service results in an error

        checkAndThrowExceptionIfServiceUnavailable();

        try {
            mImsService.close(serviceId);
        } catch (RemoteException e) {
            throw new ImsException("close()", e,
                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        } finally {
            mUt = null;
            mConfig = null;
            mEcbm = null;
        }
    
public ImsCallProfilecreateCallProfile(int serviceId, int serviceType, int callType)
Creates a {@link ImsCallProfile} from the service capabilities & IMS registration state.

param
serviceId a service id which is obtained from {@link ImsManager#open}
param
serviceType a service type that is specified in {@link ImsCallProfile} {@link ImsCallProfile#SERVICE_TYPE_NONE} {@link ImsCallProfile#SERVICE_TYPE_NORMAL} {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
param
callType a call type that is specified in {@link ImsCallProfile} {@link ImsCallProfile#CALL_TYPE_VOICE} {@link ImsCallProfile#CALL_TYPE_VT} {@link ImsCallProfile#CALL_TYPE_VT_TX} {@link ImsCallProfile#CALL_TYPE_VT_RX} {@link ImsCallProfile#CALL_TYPE_VT_NODIR} {@link ImsCallProfile#CALL_TYPE_VS} {@link ImsCallProfile#CALL_TYPE_VS_TX} {@link ImsCallProfile#CALL_TYPE_VS_RX}
return
a {@link ImsCallProfile} object
throws
ImsException if calling the IMS service results in an error

        checkAndThrowExceptionIfServiceUnavailable();

        try {
            return mImsService.createCallProfile(serviceId, serviceType, callType);
        } catch (RemoteException e) {
            throw new ImsException("createCallProfile()", e,
                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }
    
private com.android.ims.internal.ImsCallSessioncreateCallSession(int serviceId, ImsCallProfile profile)
Creates a {@link ImsCallSession} with the specified call profile. Use other methods, if applicable, instead of interacting with {@link ImsCallSession} directly.

param
serviceId a service id which is obtained from {@link ImsManager#open}
param
profile a call profile to make the call

        try {
            return new ImsCallSession(mImsService.createCallSession(serviceId, profile, null));
        } catch (RemoteException e) {
            return null;
        }
    
private voidcreateImsService(boolean checkService)
Binds the IMS service to make/receive the call.

        if (checkService) {
            IBinder binder = ServiceManager.checkService(getImsServiceName(mPhoneId));

            if (binder == null) {
                return;
            }
        }

        IBinder b = ServiceManager.getService(getImsServiceName(mPhoneId));

        if (b != null) {
            try {
                b.linkToDeath(mDeathRecipient, 0);
            } catch (RemoteException e) {
            }
        }

        mImsService = IImsService.Stub.asInterface(b);
    
private com.android.ims.ImsManager$ImsRegistrationListenerProxycreateRegistrationListenerProxy(int serviceClass, ImsConnectionStateListener listener)

        ImsRegistrationListenerProxy proxy =
                new ImsRegistrationListenerProxy(serviceClass, listener);
        return proxy;
    
private static java.lang.StringgetCallId(android.content.Intent incomingCallIntent)
Gets the call ID from the specified incoming call broadcast intent.

param
incomingCallIntent the incoming call broadcast intent
return
the call ID or null if the intent does not contain it

        if (incomingCallIntent == null) {
            return null;
        }

        return incomingCallIntent.getStringExtra(EXTRA_CALL_ID);
    
public ImsConfiggetConfigInterface()
Gets the config interface to get/set service/capability parameters.

return
the ImsConfig instance.
throws
ImsException if getting the setting interface results in an error.


        if (mConfig == null) {
            checkAndThrowExceptionIfServiceUnavailable();

            try {
                IImsConfig config = mImsService.getConfigInterface(mPhoneId);
                if (config == null) {
                    throw new ImsException("getConfigInterface()",
                            ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE);
                }
                mConfig = new ImsConfig(config, mContext);
            } catch (RemoteException e) {
                throw new ImsException("getConfigInterface()", e,
                        ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
            }
        }
        if (DBG) log("getConfigInterface(), mConfig= " + mConfig);
        return mConfig;
    
public ImsEcbmgetEcbmInterface(int serviceId)
Gets the ECBM interface to request ECBM exit.

param
serviceId a service id which is obtained from {@link ImsManager#open}
return
the ECBM interface instance
throws
ImsException if getting the ECBM interface results in an error

        if (mEcbm == null) {
            checkAndThrowExceptionIfServiceUnavailable();

            try {
                IImsEcbm iEcbm = mImsService.getEcbmInterface(serviceId);

                if (iEcbm == null) {
                    throw new ImsException("getEcbmInterface()",
                            ImsReasonInfo.CODE_ECBM_NOT_SUPPORTED);
                }
                mEcbm = new ImsEcbm(iEcbm);
            } catch (RemoteException e) {
                throw new ImsException("getEcbmInterface()", e,
                        ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
            }
        }
        return mEcbm;
    
private static java.lang.StringgetImsServiceName(int phoneId)

        // TODO: MSIM implementation needs to decide on service name as a function of phoneId
        return IMS_SERVICE;
    
public static com.android.ims.ImsManagergetInstance(android.content.Context context, int phoneId)
Gets a manager instance.

param
context application context for creating the manager object
param
phoneId the phone ID for the IMS Service
return
the manager instance corresponding to the phoneId


                                       
           
        synchronized (sImsManagerInstances) {
            if (sImsManagerInstances.containsKey(phoneId))
                return sImsManagerInstances.get(phoneId);

            ImsManager mgr = new ImsManager(context, phoneId);
            sImsManagerInstances.put(phoneId, mgr);

            return mgr;
        }
    
private static intgetServiceId(android.content.Intent incomingCallIntent)
Gets the service type from the specified incoming call broadcast intent.

param
incomingCallIntent the incoming call broadcast intent
return
the service identifier or -1 if the intent does not contain it

        if (incomingCallIntent == null) {
            return (-1);
        }

        return incomingCallIntent.getIntExtra(EXTRA_SERVICE_ID, -1);
    
public ImsUtInterfacegetSupplementaryServiceConfiguration(int serviceId)
Gets the configuration interface to provision / withdraw the supplementary service settings.

param
serviceId a service id which is obtained from {@link ImsManager#open}
return
the Ut interface instance
throws
ImsException if getting the Ut interface results in an error

        // FIXME: manage the multiple Ut interfaces based on the service id
        if (mUt == null) {
            checkAndThrowExceptionIfServiceUnavailable();

            try {
                IImsUt iUt = mImsService.getUtInterface(serviceId);

                if (iUt == null) {
                    throw new ImsException("getSupplementaryServiceConfiguration()",
                            ImsReasonInfo.CODE_UT_NOT_SUPPORTED);
                }

                mUt = new ImsUt(iUt);
            } catch (RemoteException e) {
                throw new ImsException("getSupplementaryServiceConfiguration()", e,
                        ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
            }
        }

        return mUt;
    
public booleanisConnected(int serviceId, int serviceType, int callType)
Checks if the IMS service has successfully registered to the IMS network with the specified service & call type.

param
serviceId a service id which is obtained from {@link ImsManager#open}
param
serviceType a service type that is specified in {@link ImsCallProfile} {@link ImsCallProfile#SERVICE_TYPE_NORMAL} {@link ImsCallProfile#SERVICE_TYPE_EMERGENCY}
param
callType a call type that is specified in {@link ImsCallProfile} {@link ImsCallProfile#CALL_TYPE_VOICE_N_VIDEO} {@link ImsCallProfile#CALL_TYPE_VOICE} {@link ImsCallProfile#CALL_TYPE_VT} {@link ImsCallProfile#CALL_TYPE_VS}
return
true if the specified service id is connected to the IMS network; false otherwise
throws
ImsException if calling the IMS service results in an error

        checkAndThrowExceptionIfServiceUnavailable();

        try {
            return mImsService.isConnected(serviceId, serviceType, callType);
        } catch (RemoteException e) {
            throw new ImsException("isServiceConnected()", e,
                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }
    
public static booleanisEnhanced4gLteModeSettingEnabledByUser(android.content.Context context)
Returns the user configuration of Enhanced 4G LTE Mode setting

        int enabled = android.provider.Settings.Global.getInt(
                    context.getContentResolver(),
                    android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED, ImsConfig.FeatureValueConstants.ON);
        return (enabled == 1)? true:false;
    
public static booleanisNonTtyOrTtyOnVolteEnabled(android.content.Context context)
Indicates whether the call is non-TTY or if TTY - whether TTY on VoLTE is supported.

        if (context.getResources().getBoolean(
                com.android.internal.R.bool.config_carrier_volte_tty_supported)) {
            return true;
        }

        return Settings.Secure.getInt(context.getContentResolver(),
                Settings.Secure.PREFERRED_TTY_MODE, TelecomManager.TTY_MODE_OFF)
                == TelecomManager.TTY_MODE_OFF;
    
public booleanisOpened(int serviceId)
Checks if the specified IMS service is opend.

param
serviceId a service id which is obtained from {@link ImsManager#open}
return
true if the specified service id is opened; false otherwise
throws
ImsException if calling the IMS service results in an error

        checkAndThrowExceptionIfServiceUnavailable();

        try {
            return mImsService.isOpened(serviceId);
        } catch (RemoteException e) {
            throw new ImsException("isOpened()", e,
                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }
    
public static booleanisVolteEnabledByPlatform(android.content.Context context)
Returns a platform configuration for VoLTE which may override the user setting.

        if (SystemProperties.getInt(PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE,
                PROPERTY_DBG_VOLTE_AVAIL_OVERRIDE_DEFAULT) == 1) {
            return true;
        }

        boolean disabledByGlobalSetting = android.provider.Settings.Global.getInt(
                context.getContentResolver(),
                android.provider.Settings.Global.VOLTE_FEATURE_DISABLED, 0) == 1;

        return context.getResources().getBoolean(
                com.android.internal.R.bool.config_device_volte_available) && context.getResources()
                .getBoolean(com.android.internal.R.bool.config_carrier_volte_available)
                && !disabledByGlobalSetting;
    
public static booleanisVolteProvisionedOnDevice(android.content.Context context)

        boolean isProvisioned = true;
        if (context.getResources().getBoolean(
                        com.android.internal.R.bool.config_carrier_volte_provisioned)) {
            isProvisioned = false; // disable on any error
            ImsManager mgr = ImsManager.getInstance(context,
                    SubscriptionManager.getDefaultVoiceSubId());
            if (mgr != null) {
                try {
                    ImsConfig config = mgr.getConfigInterface();
                    if (config != null) {
                        isProvisioned = config.getVolteProvisioned();
                    }
                } catch (ImsException ie) {
                    // do nothing
                }
            }
        }

        return isProvisioned;
    
public static booleanisVtEnabledByPlatform(android.content.Context context)
Returns a platform configuration for VT which may override the user setting. Note: VT presumes that VoLTE is enabled (these are configuration settings which must be done correctly).

        if (SystemProperties.getInt(PROPERTY_DBG_VT_AVAIL_OVERRIDE,
                PROPERTY_DBG_VT_AVAIL_OVERRIDE_DEFAULT) == 1) {
            return true;
        }

        return
                context.getResources().getBoolean(
                        com.android.internal.R.bool.config_device_vt_available) &&
                context.getResources().getBoolean(
                        com.android.internal.R.bool.config_carrier_vt_available);
    
private voidlog(java.lang.String s)

        Rlog.d(TAG, s);
    
private voidloge(java.lang.String s)

        Rlog.e(TAG, s);
    
private voidloge(java.lang.String s, java.lang.Throwable t)

        Rlog.e(TAG, s, t);
    
public ImsCallmakeCall(int serviceId, ImsCallProfile profile, java.lang.String[] callees, ImsCall.Listener listener)
Creates a {@link ImsCall} to make a call.

param
serviceId a service id which is obtained from {@link ImsManager#open}
param
profile a call profile to make the call (it contains service type, call type, media information, etc.)
param
participants participants to invite the conference call
param
listener listen to the call events from {@link ImsCall}
return
a {@link ImsCall} object
throws
ImsException if calling the IMS service results in an error

        if (DBG) {
            log("makeCall :: serviceId=" + serviceId
                    + ", profile=" + profile + ", callees=" + callees);
        }

        checkAndThrowExceptionIfServiceUnavailable();

        ImsCall call = new ImsCall(mContext, profile);

        call.setListener(listener);
        ImsCallSession session = createCallSession(serviceId, profile);

        if ((callees != null) && (callees.length == 1)) {
            call.start(session, callees[0]);
        } else {
            call.start(session, callees);
        }

        return call;
    
public intopen(int serviceClass, android.app.PendingIntent incomingCallPendingIntent, ImsConnectionStateListener listener)
Opens the IMS service for making calls and/or receiving generic IMS calls. The caller may make subsquent calls through {@link #makeCall}. The IMS service will register the device to the operator's network with the credentials (from ISIM) periodically in order to receive calls from the operator's network. When the IMS service receives a new call, it will send out an intent with the provided action string. The intent contains a call ID extra {@link getCallId} and it can be used to take a call.

param
serviceClass a service class specified in {@link ImsServiceClass} For VoLTE service, it MUST be a {@link ImsServiceClass#MMTEL}.
param
incomingCallPendingIntent When an incoming call is received, the IMS service will call {@link PendingIntent#send(Context, int, Intent)} to send back the intent to the caller with {@link #INCOMING_CALL_RESULT_CODE} as the result code and the intent to fill in the call ID; It cannot be null
param
listener To listen to IMS registration events; It cannot be null
return
identifier (greater than 0) for the specified service
throws
NullPointerException if {@code incomingCallPendingIntent} or {@code listener} is null
throws
ImsException if calling the IMS service results in an error
see
#getCallId
see
#getServiceId

        checkAndThrowExceptionIfServiceUnavailable();

        if (incomingCallPendingIntent == null) {
            throw new NullPointerException("incomingCallPendingIntent can't be null");
        }

        if (listener == null) {
            throw new NullPointerException("listener can't be null");
        }

        int result = 0;

        try {
            result = mImsService.open(mPhoneId, serviceClass, incomingCallPendingIntent,
                    createRegistrationListenerProxy(serviceClass, listener));
        } catch (RemoteException e) {
            throw new ImsException("open()", e,
                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }

        if (result <= 0) {
            // If the return value is a minus value,
            // it means that an error occurred in the service.
            // So, it needs to convert to the reason code specified in ImsReasonInfo.
            throw new ImsException("open()", (result * (-1)));
        }

        return result;
    
private voidsetAdvanced4GMode(boolean turnOn)

        checkAndThrowExceptionIfServiceUnavailable();

        ImsConfig config = getConfigInterface();
        if (config != null) {
            config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE,
                    TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, null);
            if (isVtEnabledByPlatform(mContext)) {
                // TODO: once VT is available on platform replace the '1' with the current
                // user configuration of VT.
                config.setFeatureValue(ImsConfig.FeatureConstants.FEATURE_TYPE_VIDEO_OVER_LTE,
                        TelephonyManager.NETWORK_TYPE_LTE, turnOn ? 1 : 0, null);
            }
        }

        if (turnOn) {
            turnOnIms();
        } else if (mContext.getResources().getBoolean(
                com.android.internal.R.bool.imsServiceAllowTurnOff)) {
            log("setAdvanced4GMode() : imsServiceAllowTurnOff -> turnOffIms");
            turnOffIms();
        }
    
public static voidsetEnhanced4gLteModeSetting(android.content.Context context, boolean enabled)
Change persistent Enhanced 4G LTE Mode setting

        int value = enabled ? 1 : 0;
        android.provider.Settings.Global.putInt(
                context.getContentResolver(),
                android.provider.Settings.Global.ENHANCED_4G_MODE_ENABLED, value);

        if (isNonTtyOrTtyOnVolteEnabled(context)) {
            ImsManager imsManager = ImsManager.getInstance(context,
                    SubscriptionManager.getDefaultVoicePhoneId());
            if (imsManager != null) {
                try {
                    imsManager.setAdvanced4GMode(enabled);
                } catch (ImsException ie) {
                    // do nothing
                }
            }
        }
    
public voidsetUiTTYMode(android.content.Context context, int serviceId, int uiTtyMode, android.os.Message onComplete)


        checkAndThrowExceptionIfServiceUnavailable();

        try {
            mImsService.setUiTTYMode(serviceId, uiTtyMode, onComplete);
        } catch (RemoteException e) {
            throw new ImsException("setTTYMode()", e,
                    ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }

        if (!context.getResources().getBoolean(
                com.android.internal.R.bool.config_carrier_volte_tty_supported)) {
            setAdvanced4GMode((uiTtyMode == TelecomManager.TTY_MODE_OFF) &&
                    isEnhanced4gLteModeSettingEnabledByUser(context));
        }
    
public ImsCalltakeCall(int serviceId, android.content.Intent incomingCallIntent, ImsCall.Listener listener)
Creates a {@link ImsCall} to take an incoming call.

param
serviceId a service id which is obtained from {@link ImsManager#open}
param
incomingCallIntent the incoming call broadcast intent
param
listener to listen to the call events from {@link ImsCall}
return
a {@link ImsCall} object
throws
ImsException if calling the IMS service results in an error

        if (DBG) {
            log("takeCall :: serviceId=" + serviceId
                    + ", incomingCall=" + incomingCallIntent);
        }

        checkAndThrowExceptionIfServiceUnavailable();

        if (incomingCallIntent == null) {
            throw new ImsException("Can't retrieve session with null intent",
                    ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
        }

        int incomingServiceId = getServiceId(incomingCallIntent);

        if (serviceId != incomingServiceId) {
            throw new ImsException("Service id is mismatched in the incoming call intent",
                    ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
        }

        String callId = getCallId(incomingCallIntent);

        if (callId == null) {
            throw new ImsException("Call ID missing in the incoming call intent",
                    ImsReasonInfo.CODE_LOCAL_ILLEGAL_ARGUMENT);
        }

        try {
            IImsCallSession session = mImsService.getPendingCallSession(serviceId, callId);

            if (session == null) {
                throw new ImsException("No pending session for the call",
                        ImsReasonInfo.CODE_LOCAL_NO_PENDING_CALL);
            }

            ImsCall call = new ImsCall(mContext, session.getCallProfile());

            call.attachSession(new ImsCallSession(session));
            call.setListener(listener);

            return call;
        } catch (Throwable t) {
            throw new ImsException("takeCall()", t, ImsReasonInfo.CODE_UNSPECIFIED);
        }
    
private voidturnOffIms()
Used for turning off IMS completely in order to make the device CSFB'ed. Once turned off, all calls will be over CS.

        checkAndThrowExceptionIfServiceUnavailable();

        try {
            mImsService.turnOffIms(mPhoneId);
        } catch (RemoteException e) {
            throw new ImsException("turnOffIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }
    
private voidturnOnIms()
Used for turning on IMS.if its off already

        checkAndThrowExceptionIfServiceUnavailable();

        try {
            mImsService.turnOnIms(mPhoneId);
        } catch (RemoteException e) {
            throw new ImsException("turnOnIms() ", e, ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN);
        }