1. 程式人生 > >ims Registered and Volte enable on Android N

ims Registered and Volte enable on Android N

文前

程式碼基於mkm-mr1 android 7.1.2 本篇記錄了調查ims Registered狀態和VoLTE enable狀態的一些取值和更新的關鍵方法。 初衷是調查ims registered狀態和 VoLTE Available有沒有對外提供介面,以及這兩者有什麼邏輯上的關係。 PS:本文采取“雙線敘事”,同時調查ims Registered和Volte enable的關鍵方法,如果讀者感覺有點亂,可以一次只看ims或者volte(這意味著你要看兩遍,其實是我懶不想分開寫)。

正文

TelephonyManager.java向系統其他應用(Settings,SystemUI)提供介面,為什麼說是“系統其他應用
”呢? 因為以下幾個方法都是@hide方法,不對第三方應用公開。 fw/base/telephony TelephonyManager.java 以下兩個方法都是獲得ims registered的方法,區別在於第二個方法需傳入subId作為引數。
  1. /**
  2. * Returns the IMS Registration Status
  3. * @hide
  4. */
  5. publicboolean isImsRegistered(){
  6. try{
  7. ITelephony telephony = getITelephony();
  8. if(telephony ==null)
  9. return
    false;
  10. return telephony.isImsRegistered();
  11. }catch(RemoteException ex){
  12. returnfalse;
  13. }catch(NullPointerException ex){
  14. returnfalse;
  15. }
  16. }
  1. /**
  2. * Returns the IMS Registration Status
  3. * using subId
  4. * @hide
  5. */
  6. publicboolean isImsRegisteredForSubscriber(int subId){
  7. try{
  8. ITelephony telephony = getITelephony
    ();
  9. if(telephony ==null)
  10. returnfalse;
  11. return telephony.isImsRegisteredForSubscriber(subId);
  12. }catch(RemoteException ex){
  13. returnfalse;
  14. }catch(NullPointerException ex){
  15. returnfalse;
  16. }
  17. }
下面這個方法返回的是VoLTE status
  1. /**
  2. * Returns the Status of Volte
  3. * @hide
  4. */
  5. publicboolean isVolteAvailable(){
  6. try{
  7. return getITelephony().isVolteAvailable();
  8. }catch(RemoteException ex){
  9. returnfalse;
  10. }catch(NullPointerException ex){
  11. returnfalse;
  12. }
  13. }
到現在為止我們知道TelephonyManager.java中有三個hide方法返回ims registered和VoLTE Status,但都是hide方法,不對第三方應用公開。 packages/services/Telephony PhoneInterfacemanager.java 到了這可以看到,兩個方法呼叫的都是Phone.java 裡的registered()方法(當然,實際呼叫的是ImsPhone.java裡的同名方法)。
  1. @Override
  2. publicboolean isImsRegistered(){
  3. return mPhone.registered();
  4. }
  5. /*
  6. * {@hide}
  7. * Returns the IMS Registration Status based on subId
  8. */
  9. publicboolean isImsRegisteredForSubscriber(int subId){
  10. finalPhone phone = getPhone(subId);
  11. if(phone !=null){
  12. return phone.isImsRegistered();
  13. }
  14. returnfalse;
  15. }
然後下面這個是VoLTE的,isVolteAvailable和isVolteEnabled居然是等價的,意味著開啟即可用?
  1. /*
  2. * {@hide}
  3. * Returns the IMS Registration Status
  4. */
  5. publicboolean isVolteAvailable(){
  6. return mPhone.isVolteEnabled();
  7. }
然後觀察到這個類裡面還有個方法來設定ims registration status的,但是吧其實這個方法沒有使用到。
  1. publicvoid setImsRegistrationState(boolean registered){
  2. enforceModifyPermission();
  3. mPhone.setImsRegistrationState(registered);
  4. }
Phone.java 這個方法只在GsmCdmaPhone.java裡面重寫了,但是GsmCdmaPhone會有ims服務?
  1. /**
  2. * Set IMS registration state
  3. */
  4. publicvoid setImsRegistrationState(boolean registered){
  5. }

ImsRegistered的最終取值

fw/opt/telephony ImsPhone.java 下面便是Ims registered取值的終點,接下來看的賦值(更新)的地方。 setImsRegistered()正是給mImsRegistered 賦值的地方
  1. @Override
  2. publicboolean isImsRegistered(){
  3. return mImsRegistered;
  4. }
  5. publicvoid setImsRegistered(boolean value){
  6. mImsRegistered = value;
  7. }
而Volte的取值還需再跟進一步
  1. @Override
  2. publicboolean isVolteEnabled(){
  3. return mCT.isVolteEnabled();
  4. }

VolteEnabled的最終取值

fw/opt/telephony ImsPhoneCallTracker.java 來自一個布林值,其實是一個布林數組裡面的其中一個值。
  1. publicboolean isVolteEnabled(){
  2. return mImsFeatureEnabled[ImsConfig.FeatureConstants.FEATURE_TYPE_VOICE_OVER_LTE];
  3. }

Ims Registered 的更新

巧合的是ims registered的更新也是在這個類裡面
  1. /**
  2. * Listen to the IMS service state change
  3. *
  4. */
  5. privateImsConnectionStateListener mImsConnectionStateListener =
  6. newImsConnectionStateListener(){
  7. @Override
  8. publicvoid onImsConnected(){
  9. if(DBG) log("onImsConnected");
  10. mPhone.setServiceState(ServiceState.STATE_IN_SERVICE);
  11. mPhone.setImsRegistered(true);
  12. mMetrics.writeOnImsConnectionState(mPhone.getPhoneId(),
  13. ImsConnectionState.State.CONNECTED,null);
  14. }
  15. @Override
  16. publicvoid onImsDisconnected(ImsReasonInfo imsReasonInfo){
  17. if(DBG) log("onImsDisconnected imsReasonInfo="+ imsReasonInfo);