目錄:
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