Android Telephony分析(一) ---- Phone詳解


目錄:

  Phone的繼承關系與PhoneFactory(GsmCdmaPhone、ImsPhone、SipPhone)

  Phone進程的啟動

  Phone對象的初始化(DefaultPhoneNotifier和RIL對象,將作為創建GsmCdmaPhone參數

  為Phone實例注冊監聽事件(CM,注冊與注銷)

  Phone有什么作用(監聽、上報消息、modem交互)

1、在Android N中,Phone的繼承關系:

Android中有三種PhoneFactory:
PhoneFactory.java ——–>用於創建GsmCdmaPhone對象;
ImsPhoneFactory.java ——–>用於創建ImsPhone對象;
SipPhoneFactory.java ——–>用於創建SipPhone對象。
其中,GsmCdmaPhone對象是在Phone進程啟動之后創建的(步驟1~6);之后,等到ImsService啟動之后,就會創建ImsPhone(步驟7~11)。

 2.1 Phone進程的啟動


在Android中進程名一般對應的是該APP的包名,所以我們可以在源碼中找package=”com.android.phone”。
接着你就會在/packages/services/Telephony/AndroidManifest.xml文件中看到:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
xmlns:androidprv
="http://schemas.android.com/apk/prv/res/android"
package
="com.android.phone"
coreApp
="true"
android:sharedUserId
="android.uid.phone"
android:sharedUserLabel
="@string/phoneAppLabel" >

 

<application android:name="PhoneApp" 
//在系統啟動之時,ActivityManagerService的systemReady() 會加載所有persistent為true的應用
android:persistent
="true"
android:label
="@string/phoneAppLabel"
android:icon
="@mipmap/ic_launcher_phone"
android:allowBackup
="false"
android:supportsRtl
="true"
android:usesCleartextTraffic
="true">

2.2 Phone對象的初始化

在PhoneFactory.java的makeDefaultPhone方法中(時序圖中的步驟3)

 

    public static void makeDefaultPhone(Context context) {
        ......
        //創建DefaultPhoneNotifier對象 sPhoneNotifier = new DefaultPhoneNotifier();

       //根據待機模式計算出要創建Phone對象的數量
        int numPhones = TelephonyManager.getDefault().getPhoneCount();
        //創建networkMode、PhoneProxy、RIL的數組,用於存儲對應的對象
        int[] networkModes = new int[numPhones];
        //Android 6.0
        //sProxyPhones = new PhoneProxy[numPhones];
      //Android N中沒有了PhoneProxy,所以通過getDefaultPhone()得到的就是Phone實例
     sPhones = new Phone[numPhones]; sCommandsInterfaces = new RIL[numPhones];  for (int i = 0; i < numPhones; i++) {
            // reads the system properties and makes commandsinterface // Get preferred network type.
           networkModes[i] = RILConstants.PREFERRED_NETWORK_MODE;
            Rlog.i(LOG_TAG, "Network Mode set to " + Integer.toString(networkModes[i]));
            //創建RIL,此時的i對應的是PhoneID。
          sCommandsInterfaces[i] = new RIL(context, networkModes[i], cdmaSubscription, i);
        }
        ......
        for (int i = 0; i < numPhones; i++) {
              Phone phone = null;
              //根據不用的類型,創建不同的Phone對象
              int phoneType = TelephonyManager.getPhoneType(networkModes[i]);
              if (phoneType == PhoneConstants.PHONE_TYPE_GSM) {
                  phone = new GsmCdmaPhone(context,
                          sCommandsInterfaces[i], sPhoneNotifier, i,
                          PhoneConstants.PHONE_TYPE_GSM,
                     //Android N中新增TelephonyComponentFactory類,主要用來 //初始化CallTracker、ServiceStateTracker、DcTracker等對象
                          TelephonyComponentFactory.getInstance());
             } else if (phoneType == PhoneConstants.PHONE_TYPE_CDMA) {
                 phone = new GsmCdmaPhone(context,
                          sCommandsInterfaces[i], sPhoneNotifier, i,
                          PhoneConstants.PHONE_TYPE_CDMA_LTE,
                          TelephonyComponentFactory.getInstance());
             }
             Rlog.i(LOG_TAG, "Creating Phone with type = " + phoneType + " sub = " + i);

            sPhones[i] = phone;
        } 
        .....
        // Start monitoring after defaults have been made. // Default phone must be ready before ImsPhone is created // because ImsService might need it when it is being opened.
        for (int i = 0; i < numPhones; i++) {
         //開始監聽ImsService,如果ImsService已啟動,進而執行創建ImsPhone對象
            sPhones[i].startMonitoringImsService();
        }
    }

2.3 為Phone實例注冊監聽事件

PhoneGlobals.java的onCreate()方法中

 

    public void onCreate() {
        if (mCM == null) {
            // Initialize the telephony framework //先創建Phone實例
            PhoneFactory.makeDefaultPhones(this);
            mCM = CallManager.getInstance();
            for (Phone phone : PhoneFactory.getPhones()) {
              //把新創建的Phone實例傳遞進來
                mCM.registerPhone(phone);
            }
        }
    }

由CallManager來管理這些Phone實例並且為它們注冊監聽事件。

 

 // list of registered phones, which are PhoneBase objs
    private final ArrayList<Phone> mPhones;

    public boolean registerPhone(Phone phone) {
        Phone basePhone = getPhoneBase(phone);

        if (basePhone != null && !mPhones.contains(basePhone)) {

            if (DBG) {
                Rlog.d(LOG_TAG, "registerPhone(" +
                        phone.getPhoneName() + " " + phone + ")");
            }
            if (mPhones.isEmpty()) {
                mDefaultPhone = basePhone;
            }
            //管理Phone實例
            mPhones.add(basePhone);
            mRingingCalls.add(basePhone.getRingingCall());
            mBackgroundCalls.add(basePhone.getBackgroundCall());
            mForegroundCalls.add(basePhone.getForegroundCall());
         //為Phone實例注冊監聽事件
            registerForPhoneStates(basePhone);
            return true;
        }
        return false;
    }
    private void registerForPhoneStates(Phone phone) {
        ......
        phone.registerForDisconnect(handler, EVENT_DISCONNECT,mRegistrantidentifier);
        phone.registerForIncomingRing(handler, EVENT_INCOMING_RING,mRegistrantidentifier);
        ......
    }

 

3. Phone有什么作用


回憶第2小節創建GsmCdmaPhone對象時

      sPhoneNotifier = new DefaultPhoneNotifier();
      sCommandsInterfaces[i] = new RIL(context, networkModes[i],
                            cdmaSubscription, i);

      phone = new GsmCdmaPhone(context,
              sCommandsInterfaces[i], sPhoneNotifier, i,
              PhoneConstants.PHONE_TYPE_GSM,
              TelephonyComponentFactory.getInstance());

初始化了DefaultPhoneNotifier和RIL對象,將它們作為參數,再創建GsmCdmaPhone。
所以在GsmCdmaPhone中可以直接操縱這兩個對象的方法。
DefaultPhoneNotifier實現了PhoneNotifier接口,PhoneNotifier接口中定義了很多notifyXXX的接口,所以DefaultPhoneNotifier主要的作用就是上報消息

 

public interface PhoneNotifier {

    public void notifyPhoneState(Phone sender);
    public void notifyServiceState(Phone sender);
    ...
}

而RIL對象主要作用是跟modem交互。
因此,Phone實例就間接地擁有了跟modem交互的能力和上報消息的能力,再加上Phone實例自身就有監聽事件的能力,所以Phone的作用就是:
1.注冊監聽事件,及時上報消息(Call狀態變化、Service狀態變化、新來電等等)
2.間接地為其他類提供跟modem交互的服務。

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

 


免責聲明!

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



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