您的位置:首页 > 移动开发 > Android开发

Android Telephony分析(一) ---- Phone详解(Android 7.0)

2017-09-14 16:32 1066 查看


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

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

再往下翻翻,你就会看到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


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


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

由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


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

先初始化了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

而RIL对象主要作用是跟modem交互。 

因此,Phone实例就间接地拥有了跟modem交互的能力和上报消息的能力,再加上Phone实例自身就有监听事件的能力,所以Phone的作用就是: 

1.注册监听事件,及时上报消息(Call状态变化、Service状态变化、新来电等等) 

2.间接地为其他类提供跟modem交互的服务。

原文地址:http://blog.csdn.net/linyongan/article/details/51994817
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Android Telephony Phone