本文來自http://blog.csdn.net/linyongan ,轉載請務必註明出處。本文主要講解Telephony中Phone相關的知識。
1. Android N中Phone的改變
Android 6.0時,Phone的繼承關係:
在Android N中,Phone的繼承關係:
變化1: GSMPhone和CDMAPhone合併成了GsmCdmaPhone,合併之後,某些方法當然需要對GSM Phone和CDMA Phone進行分別處理,舉個例子:
@Override
public void setCallWaiting(boolean enable, Message onComplete) {
//如果是GSM Phone
if (isPhoneTypeGsm()) {
Phone imsPhone = mImsPhone;
//對IMS的處理
if ((imsPhone != null)
&& ((imsPhone.getServiceState().getState() == ServiceState.STATE_IN_SERVICE)
|| imsPhone.isUtEnabled())) {
//走IMS流程
imsPhone.setCallWaiting(enable, onComplete);
return;
}
mCi.setCallWaiting(enable, CommandsInterface.SERVICE_CLASS_VOICE, onComplete);
} else {
//如果是CDMA Phone
loge("method setCallWaiting is NOT supported in CDMA!");
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
GSMPhone和CDMAPhone合併之後,PhoneProxy的作用就不大了,所以在Android N中PhoneProxy被刪除了。
變化2:Phone.Java取代了以前的PhoneBase.java(內部的方法有小部分修改),Phone.java變成了所有關係的中心樞紐。
變化3:接口變成了PhoneInternalInterface,因爲PhoneProxy已不存在了,實現了PhoneInternalInterface接口的只剩下Phone.java,所以刪掉了PhoneInternalInterface中大量的register/unregister的接口,這些register/unregister的方法留在Phone.java中即可,PhoneInternalInterface接口變得更加精簡;
本文來自
2. 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"
>
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 1
- 2
- 3
- 4
- 5
- 6
- 7
再往下翻翻,你就會看到application的名字是PhoneApp,application是最早被創建的,所以PhoneApp.java就是Phone進程啓動的入口。
<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">
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
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();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
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);
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
由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);
......
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
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());
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
先初始化了DefaultPhoneNotifier和RIL對象,將它們作爲參數,再創建GsmCdmaPhone。
所以在GsmCdmaPhone中可以直接操縱這兩個對象的方法。
DefaultPhoneNotifier實現了PhoneNotifier接口,PhoneNotifier接口中定義了很多notifyXXX的接口,所以DefaultPhoneNotifier主要的作用就是上報消息
public interface PhoneNotifier {
public void notifyPhoneState(Phone sender);
public void notifyServiceState(Phone sender);
...
}
- 1
- 2
- 3
- 4
- 5
- 6
- 1
- 2
- 3
- 4
- 5
- 6
而RIL對象主要作用是跟modem交互。
因此,Phone實例就間接地擁有了跟modem交互的能力和上報消息的能力,再加上Phone實例自身就有監聽事件的能力,所以Phone的作用就是:
1.註冊監聽事件,及時上報消息(Call狀態變化、Service狀態變化、新來電等等)
2.間接地爲其他類提供跟modem交互的服務。