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

来源:互联网 发布:linux中查看文件内容 编辑:程序博客网 时间:2024/05/16 08:35

本文主要讲解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接口变得更加精简;


http://blog.csdn.net/linyongan 


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交互的服务。

原文地址: http://blog.csdn.net/linyongan/article/details/51994817

0 0