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详解
- Android Telephony分析(一) ---- Phone详解
- Android Telephony分析(一)--- Phone 详解
- Android Telephony分析(一) ---- Phone详解
- Android Telephony分析(二) ---- RegistrantList详解
- Android Telephony分析(四)--- TelephonyManager 详解
- Android Telephony分析(五)--- TelephonyRegistry 详解
- Android Telephony分析(三) ---- RILJ详解
- Android Telephony分析(三)--- RILJ 详解
- Android源码分析:Telephony部分–phone进程
- Android源码分析:Telephony部分–GSMPhone
- Android 核心分析 之八------Android 启动过程详解
- Android异步消息处理机制详解及源码分析
- Android之SharedPreferences详解与原理分析
- 了解与建设有中国特色的Android M&N(Android6.0和7.0新特性分析)
- Android 7.0 ActivityManagerService(5) 广播(Broadcast)相关流程分析
- Android之TelephonyManager类的方法详解
- Android异步消息处理机制详解及源码分析
- Android触摸屏事件派发机制详解与源码分析
- Android之TelephonyManager类的方法详解