Android 系统电话管理机制二

[来源] 达内    [编辑] 达内   [时间]2012-09-17

RIL的RILReceiver对象通过相同LocalSocket通道收到AT命令的响应unmarshall后调用processSolicited()函数把应答结果封装进命令携带的应答消息中发送回框架层的事件处理对象

 SipPhone

           如下是SipPhone实现相关类图。

           

          SipPhone对象虽然也派生自PhoneBase,但实现机制及实例化过程与其它Phone 对象大大不同。

          SipPhone对象的实例化通过PhoneFactorymakeSipPhone 的接口调用SipPhoneFactorymakePhone进行实例化。SipPhone对象的实例化调用也不是在PhoneApp 对象中进行,而是在默认电话应用的SipBroadcastReceiver对象的onReceive 回调函数或者 SipCallOptionHandler对象的createSipPhoneIfNeeded函数中被调用,另外不同的是对SipPhone对象的创建个数也没有限制。

       虽然实例化过程和CDMAPhoneGSMPhone对象不同,但实例化的 SipPhone对象和 CDMAPhoneGSMPhone对象一样也被添加到CallManager对象中进行统一管理。

          SipPhone实现机制是通过IP通道实现电话功能,而不是通过无线通讯模块,因此没有采用RIL RIL daemon,因此框架实现层与CDMAPhoneGSMPhone有很大不同,SipPhone 框架实现主要是通过SipService系统服务及调用第三方协议栈来完成。SipService系统服务通过 JNI 来调用本地nist SIP协议堆栈。

          SipPhone对象属于SipService服务的客户端对象, 其通过SipManager 对象的ISipService接口调用SipService

      每个SipPhone对象都对应一个SipProfile对象(包括SIP 帐户, 地址连接信息以及服务信息等信息)用来标识通话一方。SipProfile对象在SipPhoneFactory调用 makePhone 实例化SipPhone对象前根据网络通话的sipUri构建,并作为makePhone 的参数传给SipPhone对象。 

      每个SipPhone对象和其它具体Phone对象相同也包括三个Call 对象(SipCall ):ringingCallforegroundCallbackgroundCall ,每个 SipCall对象也包含一个Connection类型的ArrayList对象,用来维护每个CALL 拥有的通话连接。不过和其它Phone对象不同SipPhone对象对每个Call 对象拥有的connection个数没有限制,SipCall拥有的connection 对象对应具体的 SipConnection对象。

         SipConnection对象包括主动和被动两种类型,主动类型的SipConnection对象在SipCall 对象的dial 函数调用时创建,被动类型的SipConnection对象在SipCall对象接收到输入CALL 时,其initIncomingCall函数调用时创建。创建的SipConnection对象添加到SipCall 对象的Connection类型的ArrayList数组列表中进行管理。

       每个SipConnection对象也包括一个SipProfile对象和一个 SipAudioCall对象。

       被动SipConnection类型的SipProfile对象和SipAudioCall 对象从对方获得。被动类型的 SipAudioCall对象和initIncomingCall函数传进来的SipAudioCall对象相同,SipProfile 对象通过调用SipAudioCallgetPeerProfile函数获得发起通话的对方的SipProfile

       主动SipConnection类型的SipProfile对象在dial 函数中调用SipProfile.Builder 对象的build函数根据发起的通话URL构建,用来标识本地通话方,SipAudioCall 对象在调用dial函数时通过调用SipManager对象的makeAudioCall函数创建。

           SipAudioCall对象中包括一个客户端SipSession对象,管理客户端的每一个会话过程, SipSession 对象中有一个ISipSession接口成员,通过该接口调用服务端对应的会话对象SipSessionImpl 对象(一个实现ISipSession 接口的会话桩对象),共同完成通话一方的会话过程,客户端通过ISipSession接口向服务端的SipSessionImpl 对象发起IPC调用。

       主动类型的SipAudioCall对象对应的SipSession对象在makeAudioCall函数中调用 createSipSession进行实例化,在makeAudioCall函数调用新创建SipAudioCall对象的makeCall 函数时,SipSession对象作为makeCall函数的参数传给SipAudioCall 对象。主动类型的SipSession对象中的ISipSession类型的接口成员在createSipSession 中通过调用SipServicecreateSession函数创建,返回服务端SipSessionImpl 对象的远程调用对象接口。

          SipServicecreateSession函数创建一个Sip会话对象的整个过程:

               1、首先调用createGroup函数实例化一个SipSessionGroupExt 对象, SipSessionGroupExt对象派生自SipSessionAdapter,而SipSessionAdapter是一个实现 ISipSessionListener 接口的桩类;

          2、SipSessionGroupExt对象实例化时又调用createSipSessionGroup函数实例化一个SipSessionGroup对象;

          3、SipSessionGroup对象实例化时由SipFactory工厂对象实例化底层协议栈类对象SipStack,并有 SipStack 对象创建一个SipProvider对象和一个SipHelper对象,SipSessionGroup 对象本身登记为SipProvider对象的监听对象;

               4、然后调用SipSessionGroupExt对象的createSession 函数,内部实际调用 SipSessionGroup对象的createSession函数,实例化SipSessionImpl对象,并返回实例化后的 SipSessionImpl对象引用。

         SipSessionImpl属于SipSessionGroup类的内部类,客户端发起的通话请求都通过服务端的SipSessionImpl 对象封装成EventObject类型的命令发起异步处理请求(调用SipSessionImpl对象的doCommandAsync 函数,doCommandAsync函数的参数是一个EventObject类型的对象),最终通过SipSessionGroup 对象的SipHelper对象调用SIP协议栈的接口与通话对方交互。

      每个SipSessionImpl会话对象被放到SipSessionGroup对象的HashMap 中进行管理。每个实例化的SipSessionGroupExt对象放到SipServiceHashMap中进行管理。

      客户端也可以通过SipManager对象的open函数发起一个被动会话请求,过程为:

        1、 SipManager对象的open函数调用SipServiceopen3函数,同时也实例化一个PendingIntent对象通过SipServiceopen3函数传给服务端的SipSessionGroupExt对象中;

        2、 open3函数中调用createGroup 函数实例化SipSessionGroupExt对象,并进一步实例化SipSessionGroup对象;

        3、 接着调用SipSessionGroup对象的openToReceiveCalls 函数来实例化一个SipSessionCallReceiverImpl对象作为接收会话,SipSessionCallReceiverImpl派生自 SipSessionImplSipSessionGroupExt对象作为函数参数传进openToReceiveCalls函数,并在SipSessionImpl 构造函数时调用内部对象成员mProxySipSessionListenerProxy类,一个实现ISipSessionListener 接口的桩类)的setListener函数,为内部ISipSessionListener类型的成员赋值。

        4、 当接收到底层协议发来的会话请求时,监听底层事件的对象SipSessionGroupprocessRequest函数被调用;

        5、 接着调用接收会话对象SipSessionCallReceiverImplprocess 函数,在process函数中判断接收到的事件请求是Request.INVITE时就调用processNewInviteRequest 函数;

        6、 processNewInviteRequest函数中调用createNewSession 实例化一个SipSessionImpl对象作为新的会话,新的会话状态为INCOMING_CALL。接着调用接收会话 SipSessionCallReceiverImpl对象内部成员mProxyonRinging函数,在onRinging 函数中调用其成员mListenerISipSessionListener类型)的onRinging 函数,实际调用 SipSessionGroupExt对象的onRinging函数;

        7、 SipSessionGroupExt对象的onRinging 函数中通过SipSessionGroupExt对象内部客户端传进来的PendingIntent对象向客户端发送 ACTION_SIP_INCOMING_CALL 类型广播消息;

        8、 客户端在接收到这个广播调用SipManagertakeAudioCall 函数。takeAudioCall函数首先通过SipService接口getPendingSession 获得一个服务端会话对象引用;接着实例化一个SipAudioCall对象(SipAudioCall对象对应的 SipProfile 对象调用服务端会话对象的getLocalProfile函数获得);然后根据服务端会话对象引用实例化一个客户端SipSession 对象;并调用 SipAudioCall对象的attachCall实现SipSession对象与SipAudioCall对象的绑定;

        9、 最后调用现有的SipPhone对象的canTake 函数,在SipPhone对象的canTake函数中调用SipPhone 对象的ringingCall 对象的initIncomingCall函数实例化一个SipConnection对象,完成通话建立过程。

 

四数据连接

          Telephony框架的数据连接模块负责数据连接通道的建立,使电话能够提供数据服务,如上网等,数据连接模块的类图如下图。

         

 

 

          DataConnectionTracker是数据连接功能的核心,GsmDataConnectionTrackerCdmaDataConnectionTracker DataConnectionTracker的两个派生类,实现具体网络的数据连接的建立和管理。

       每一个数据连接用一个DataConnection对象表示,DataConnection 对应的具体网络的派生类为GsmDataConnectionCdmaDataConnectionDataConnectionTracker中用一个HashMap 类型的变量 mDataConnections维护每一个数据连接。CDMA同时只能建立一路数据连接,GSM网络则没有限制。

          DataConnection对象是一个是一个状态机对象,维护连接的状态,并提供数据连接的 LinkPropertiesLinkCapabilities等属性。DataConnection对象的状态包括DcDefaultStateDcInactiveStateDcActivatingStateDcActiveStateDcDisconnectingStateDcDisconnectionErrorCreatingConnection六种状态。

       对于GsmDataConnectionTracker对象,ApnContext对象提供数据连接的 APN 上下文,每一个APN类型都对应一个ApnContext对象,ApnContext 对象维护对应的APN 设置、DataConnectionTracker的状态、对应的DataConnectionDataConnectionAc等。

       数据连接通道的建立过程:

          1、 数据连接的建立最终都通过GsmDataConnectionTracker CdmaDataConnectionTrackertrySetupData函数启动数据连接;

          2、 trySetupData函数调用setupData 函数,设置数据连接参数(如采用的Apn设置参数,连接建立成功响应消息);

          3、 然后调用对应的DataConnection 对象的bringUp 函数发送数据连接消息(EVENT_CONNECT)。

          4、 EVENT_CONNECT消息由DataConnection 对象的状态机的相应状态对象接收处理,对于开始尚未建立数据连接时,DataConnection对象处于DcInactiveState 状态,因此DcInactiveState 状态对象接收处理EVENT_CONNECT事件,调用onConnect函数,并转变为DcActivatingState 状态。

          5、 在具体DataConnection 对象的onConnect 函数中调用RIL接口setupDataCall函数启动数据连接;

          6、 连接建立后RIL 层回应EVENT_SETUP_DATA_CONNECTION_DONE 请求应答事件,由DataConnection对象的DcActivatingState状态对象接收处理 EVENT_SETUP_DATA_CONNECTION_DONE事件,调用onSetupConnectionCompleted函数,并过渡到DcActiveState状态,连接建立成功。

          DataConnectionTracker对象采用DataConnectionAc对象(派生自AsyncChannel )与DataConnection 对象通讯。

          GsmDataConnectionTracker对象在setupData函数调用createDataConnection 函数创建时GsmDataConnection 对象和DataConnectionAc对象,并通过DataConnectionAc对象与GsmDataConnection 对象建立异步通讯连接。GsmDataConnectionTracker对象对于每类ApnContext都可以建立一个 GsmDataConnection 对象和一个DataConnectionAc对象。

         CdmaDataConnectionTracker对象在实例化时调用createAllDataConnectionList 函数创建需要的数据连接对象CdmaDataConnection DataConnectionAc对象。CdmaDataConnectionTracker 对象只支持创建一个 CdmaDataConnection对象和DataConnectionAc对象。

 

五事件通知机制

         整个Telephony事件通知框架包括三层: RIL 消息层、框架事件处理层、应用层。类图如下图,主要是请求应答模式和观察者模式的采用。

           

       整个框架层以PhoneBase为中心,向上通过PhoneNotifier 接口向应用层发送框架层产生的的事件,应用层通过TelephonyRegistry 接口提供对特定事件的监听,由PhoneNotifier接口的默认实现DefaultPhoneNotifier通过 TelephonyRegistry对象向应用层发送事件通知。

       向下框架层通过CommandsInterface接口注册Unsolicited 事件(主动通知事件)及发起AT 命令请求。框架层的事件处理对象包括CDMAPhoneGSMPhone两个对象本身及其包含的 SMSDispatcherIccFileHandlerDataConnectionTrackerIccRecords 类型的对象以及PhoneBase 中的SmsStorageMonitor对象。

       这些对象都是Handler对象,都能够向RIL层注册Unsolicited事件及发起AT 命令请求。也能够接收和处理RIL层产生的Unsolicited事件及AT命令的响应。

          CDMAPhoneGSMPhone对象中的事件处理对象除了CallTrackerServiceStateTracker 对象外,其它都在PhoneBase中由基类实现。

       向RIL层注册的Unsolicited事件都登记添加到BaseCommands 类中的RegistrantList 类型的对象中或者设置为BaseCommands类中的Registrant 类型的对象(根据设置函数的参数实例化具体类型的Registrant类型的对象)。

          RIL层产生的Unsolicited事件通过在BaseCommands 类中登记的RegistrantList 对象或设置的Registrant对象向框架层的事件处理对象发送Unsolicited事件。

         框架层的事件处理对象向RIL层发送的命令直接发送给 RIL 对象的相应函数,向RIL层发送的命令中都带有一个Message类型的应答消息,RIL 对象的相应函数把接收到的命令携带的参数封装进RILRequest请求中发送给RILRILSender 对象并 marshall后通过LocalSocket发送给rild进程。

         RILRILReceiver对象通过相同LocalSocket通道收到AT 命令的响应unmarshall后调用processSolicited()函数把应答结果封装进命令携带的应答消息中发送回框架层的事件处理对象。

       RILSender对象和RILReceiver对象都实现了接口,在独立线程运行。

资源下载