Android 7.0 IMS框架詳解


本文主要講解IP Multimedia Subsystem (IMS)在Android 7.0上由谷歌Android實現的部分內容。
從APP側一直到Telephony Framework,是不區分CS流程還是PS流程的。到了Telephony Framework模塊,會依據IMS相關的狀態信息(Registration Status,Service Status等)和用戶設置信息(Volte Enable?Wifi Calling Enable?UT Enable?等 )進而判斷出,Call、SMS等是否需要優先走IMS的流程。
整體來看,IMS框架如下圖:

通常都是由Phone對象或者ImsPhoneCallTracker對象直接得到ImsManager對象

mImsManager = ImsManager.getInstance(mPhone.getContext(), mPhone.getPhoneId());

接着再通過ImsManager對象間接地得到ImsConfig、ImsUt、ImsCall等重要對象,然后根據請求不同而走不同的通道與Vendor RIL通信,與Call相關的走ImsCall,與補充業務相關的走ImsUt,與IMS功能的能力、參數相關的走ImsConfig,所以分工是十分明確的。谷歌為了規范高通/MTK等芯片廠商的行為,所以定義了IImsService、IImsConfig、IImsCallSession和IImsUt等接口,再由各芯片廠商來實現這些接口,谷歌只需要處理好上層調用接口的邏輯即可。

接下來分別講一下各個類


ImsPhone


ImsPhone是為了與CS Call區分開,用來處理IMS相關事務的Phone實例,以setCallWaiting為例:

    public void setCallWaiting(boolean enable, Message onComplete) {
        if (isPhoneTypeGsm()) {
            Phone imsPhone = mImsPhone;
            //判斷是否符合IMS的條件
            if ((imsPhone != null)
                    && ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
                    || imsPhone.isUtEnabled())) {
                //走IMS流程
                imsPhone.setCallWaiting(enable, onComplete);
                return;
            }
            //走CS流程
            mCi.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
        } else {
            loge("method setCallWaiting is NOT supported in CDMA!");
        }
    }

然而僅僅有Phone實例是不夠的,還需要有對應地CallTracker、Call以及Connection對象,所以就有了下面這張圖:

 

ImsPhone實例是在IMS Service啟動之后被創建的,接着會初始化ImsPhoneCallTracker對象。

 

ImsPhoneCallTracker

ImsPhoneCallTracker在初始化的時候會注冊監聽IMS InComing call

intentfilter.addAction(ImsManager.ACTION_IMS_INCOMING_CALL);

同時將Action為“ACTION_IMS_INCOMING_CALL”的PendingIntent傳遞給IMS Service,這樣子就可以監聽到IMS MT Call了。

ImsPhoneCallTracker內部會初始化四個ImsPhoneCall對象,

    public ImsPhoneCall mRingingCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_RINGING);
    public ImsPhoneCall mForegroundCall = new ImsPhoneCall(this,ImsPhoneCall.CONTEXT_FOREGROUND);
    public ImsPhoneCall mBackgroundCall = new ImsPhoneCall(this,ImsPhoneCall.CONTEXT_BACKGROUND);
    public ImsPhoneCall mHandoverCall = new ImsPhoneCall(this, ImsPhoneCall.CONTEXT_HANDOVER);

比GsmCdmaCallTracker多了一個Handover Call,比如VoWiFi與VoLTE相互切換就是通過Handover來實現的。

還有一點ImsPhoneCallTracker與GsmCdmaCallTracker不一樣的就是

    protected void handlePollCalls(AsyncResult ar) { }

ImsPhoneCallTracker的handlePollCalls()方法是空的,是因為IMS Call狀態消息的上報和獲取modem當前Call List信息等這些邏輯需要高通/MTK來實現,ImsPhoneCallTracker則通過ImsCall.Listener來監聽Ims Call的狀態變化信息,然后再根據ImsCall的狀態,更新當前ImsPhoneConnection與四種ImsPhoneCall的綁定關系。
比如:
1. A<—>B正在通話,這通電話對應的Connection會與mForegroundCall綁定;
2. 此時A再呼叫C,那么A<—>B這通電話的Connection就會先與mBackgroundCall綁定,這種切換是由mBackgroundCall與mForegroundCall互換Connection集合和狀態實現的;

mForegroundCall.switchWith(mBackgroundCall);

3.然后A<—>C接通之后,A<—>C這通電話對應的Connection會與mForegroundCall綁定。
就是這樣子。每個ImsPhoneCall最多綁定5個ImsPhoneConnection,這個值規定在ImsPhoneCallTracker中:

static final int MAX_CONNECTIONS_PER_CALL = 5;

ImsPhoneCallTracker還負責監聽IMS service的狀態變化

private ImsConnectionStateListener mImsConnectionStateListener =
        new ImsConnectionStateListener() {
        //IMS已注冊上
        public void onImsConnected() {}
        //IMS已斷開,有時候會上報斷開的原因
        public void onImsDisconnected(ImsReasonInfo imsReasonInfo) {}
        //IMS處於正在注冊狀態
        public void onImsProgressing() {}
        //"VoLTE", "ViLTE", "VoWiFi", "ViWiFi", //"UTLTE", "UTWiFi"等功能的能力變化
        public void onFeatureCapabilityChanged() {}
        ......
}

如果遇到IMS注冊不上的問題,應該去看IMS注冊時的SIP信令流程。

 

ImsManager

ImsManager作為IMS框架的核心,是任意IMS action的出發點。ImsManager的職責主要有以下3點:
1. 向上提供ImsConfig、ImsUt、ImsCall等重要對象,得到這些對象就可以跟Vendor RIL通信了。

 public ImsUtInterface getSupplementaryServiceConfiguration(){}
 public ImsConfig getConfigInterface(){}
 public ImsCall makeCall(){}

2 .向APP提供設置IMS相關功能的接口

//設置VoLTE打開或者關閉
public static void setVtSetting(Context context, boolean enabled) {}
//設置WiFi Calling打開或者關閉
public static void setWfcSetting(Context context, boolean enabled) {}
//設置WiFi Calling的模式,如WiFi Only、WiFi優先...
public static void setWfcMode(Context context, int wfcMode) {}
//設置4G LTE增強模式打開或者關閉
public static void setEnhanced4gLteModeSetting(Context context, boolean enabled) {}

3.向上傳遞IMS注冊狀態變化的消息,是由ImsManager來通知ImsPhoneCallTracker的。

 

ImsService

谷歌定義好了ImsServiceBase抽象類和IImsService接口,接着由芯片廠商實現ImsService。
ImsConfig、ImsUt、ImsCall等對象最終是依靠ImsService來創建的,
由此可見,其他三種通信方式都是依賴着ImsService的。

ImsManager—>ImsService—>Vendor RIL
這種通信方式主要用來通知modem turn on/off Ims。
使用場景就是在VoLTE、WFC和Advanced4GMode等功能被用戶手動enable/disable時,就要響應地通知modem turn on/off Ims了。

 

ImsConfig


ImsManager—>ImsConfig—>Vendor RIL
ImsConfig主要就是提供接口給上層動態地去控制IMS功能的能力、參數等。
ImsConfig類中雖然只有7個方法,但是功能強大,特別是下面幾個方法

public int getProvisionedValue();
public int setProvisionedValue();
public String getProvisionedStringValue();
public int setProvisionedStringValue();

 

這些方法為開發者打開了一扇大門!通向底層NV的大門!(不同芯片廠商可能有差異)比如,在UI界面上點擊了打開WFC的按鈕,就可以間接地修改到NV的某一項。
目前Android 7.0中支持的NV只有幾十個,但是這並不能滿足OEM所有的需求,所以有時候還需擴展這個接口。

還有就是,如果要開發IMS接口的話,建議也是加在這里,其他通道都不太合適。


ImsCall

ImsManager—>ImsCall—>ImsCallSession—>Vendor RIL
這個就很明顯了,這條通道是專門處理IMS Call相關事務的,創建ImsCall的方式有兩種:
1. IMS MO Call時,通過ImsManager.makeCall()來創建;
2. IMS MT Call時,通過ImsManager.takeCall()來創建。
在ImsCall中,每個對Call操作的方法(accept/reject/hold/resume/merge等等)都會有對應的回調方法:

    /**
     * @see Listener#onCallResumed, Listener#onCallResumeFailed
     */
    public void resume(){
        ......
    }

如果resume成功則通過onCallResumed()方法通知上層,如果resume失敗則通過onCallResumeFailed()方法通知上層,一般的流程如下:

 

 

ImsUt

ImsManager—>ImsUt—>Vendor RIL
這條通道是專門提供向上提供設置補充業務接口的,如呼叫轉移、呼叫限制、呼叫等待、outgoing Caller Id display等等。

最后,更多關於IMS的內容,請查閱如下協議文檔:
- GSMA IR.92 : features for voice and sms profile
- GSMA IR.94 : video calling feature
- 3GPP TS 24.229 : IMS call control (SIP and SDP)
- 3GPP TS 26.114 : IMS media handling and interaction
- 3GPP TS 26.111 : Codec for CS multimedia telephony service (H.324)
- 3GPP TS 24.623 : XCAP over the Ut interface for manipulating supplementary services

 


————————————————
版權聲明:本文為CSDN博主「linyongan」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/linyongan/article/details/53350493

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM