6572_Telephony
3.1.8 TelephonyRegistry向ServiceManager注册 23
1 术语和前言:
2 TelePhony:
2.1 Telephony框架
Android手机操作系统是一个基于Linux Kernel的分层智能手机操作系统,其共分为4层,从上到下分别是:
Ø 应用层(Java Application),包括了Android各种应用程序
Ø 应用框架层(Java Frameworks),是Google发布的核心应用所使用的API框架
Ø 系统运行库层(User Libraries),包含了手机系统平台必须的C/C++核心库、Dalvik虚拟机运行环境和HAL子层
Ø 核心层(Linux Kernel),Android 4.0 基于Linux Kernel 3.0.8 提供核心系统服务,例如文件管理、内存管理、进程管理、网络堆栈、驱动模型等操作系统的基本服务能力
Telephony为手机提供通信功能,其通信逻辑关系如下,
Android Telephony采用了分层结构,共跨越了4层:
Ø Telephony应用,包括了Phone、MMS和STK等应用程序
Ø Telephony框架,提供TelephonyManager,包含数据连接、通话、信息和SIM相关的API
Ø 无线通信接口层(RIL),主要位于User Libraries层中的HAL层,提供AP(Application Processor)和BP( Baseband Processor)之间的通信功能
Ø Modem,位于BP,主要负责实际的无线通信能力处理
其中,Telephony框架层是以Phone实例为核心的,Phone接口及其子类管理整个整个手机的Telephony功能。Phone相关信息在后面介绍。
Telephony框架层为应用层和框架层的其它服务提供Telephony服务,如下:
PhoneInterfaceManager服务,是ITelephony接口的实现,PhoneInterfaceManage
通过PhoneApp、CallManager、Phone对象实现相应功能。
IccSmsInterfaceManager短消息服务,是Isms接口的实现;IccPhoneBookInterfaceManager电话本服务,是IIccPhoneBook接口的实现;PhoneSubInfo提供用户信息读取服务,是IPhoneSubInfo接口的实现;
TelephonyRegistry提供应用层的消息登记服务,是ITelephonyRegistry接口的实现。
应用程序通过以下几个客户端对象使用Telephony框架提供的服务。
通过在SmsManager对象实例(通过SmsManager类的getDefault函数返回SmsManager对象)中访问IccSmsInterfaceManager服务,用来收发短信。
通过IccProvider一个内容提供对象提供对IccPhoneBookInterfaceManager服务的访问,读取和管理电话本。
通过TelephonyManager对象提供对PhoneSubInfo、PhoneInterfaceManager、TelephonyRegistry服务的访问,TelephonyManager对象通过getSubscriberInfo函数获得PhoneSubInfo服务的远程访问代理对象。
通过getITelephony函数获得PhoneInterfaceManager的远程访问代理对象。提供一个对象全局sRegistry(指向TelephonyRegistry服务的远程访问代理对象)访问TelephonyRegistry服务。
Android中关于telephony相关的java代码主要在下列目录中:
1. frameworks/base/telephony/java/android/telephony
提供Android telephony的公开接口,任何具有权限的第三方应用都可使用,如接口类TelephonyManager。
2. frameworks/base/telephony/java/com/android/internal/telephony
3. frameworks/base/services/java/com/android/server/TelephonyRegistry.java
提供一系列内部接口,目前第三方应用还不能使用。当前似乎只有packages/apps/Phone能够使用
4. frameworks/opt/telephony
5. packages/apps/Phone
一个特殊应用,或者理解为一个平台内部进程。其他应用通过intent方式调用这个进程的服务。
1.1 Phone介绍
Phone相关类的关系图:
Phone | 接口,定义了一些telephony相关的常量和方法 |
PhoneBase | 类,继承了handler,实现了phone接口, 类里定义了一些常用类的引用,如mCM,SMSDispatcher |
PhoneNotifier | 接口,定义了一些telephony相关的通知方法 |
PhoneFactory | 类,创建phone实例,主要完成socket创建、RIL实例创建、 phoneproxy实例创建。 |
MTKPhoneFactory | MTK对PhoneFactory的封装,当前看不到代码 |
PhoneProxy | 类,继承了handler,实现了phone接口,使用phone实例,完成和ril交互的接口。 |
Phone描述了对电话的所有操作接口。PhoneBase直接从Phone 派生而来, GSMPhone又从PhoneBase派生而来,代表GSM手机的通信功能。PhoneProxy也从Phone直接派生而来,完成和ril交互的接口,手机的Phone实例就是一个PhoneProxy实例。
接口类Phone定义了一套API,这套API用于使用RIL发送AT命令请求,也还有一套register和unregister函数;当调用者对一些内部状态感兴趣时,可以调用对应的register函数,当状态变化时可以得到及时通知。
PhoneBase实现了Phone接口中定义的部分函数,还有一部分由其子类GSMPhone和CDMAPhone实现。PhoneBase通过CommandsInterface接口与RIL daemon层交互,实现短消息提交、数据连接控制、ICC 信息读取等Telephony基类功能。PhoneBase包含SMSDispatcher、DataConnectionTracker、IccFileHandler、IccRecords、IccCard等几个抽象类成员,并通过这些抽象类成员提供某一方面功能的基类实现。
PhoneProxy是GSMPhone和CDMAPhone的代理,让使用者不用关注手机到底是GSM还是CDMA,它遵守Phone定义的API接口,因此继承Phone。PhoneFactory在创建Phone对象时,拥有的是PhoneProxy对象,PhoneProxy根据实际的网络类型创建对应的GSMPhone或CDMAPhone。PhoneProxy代理对象实现了Phone接口,使应用能够使用统一的PhoneProxy对象控制操作具体类型的Phone对象,而不用关心它们之间的差异(代理模式的采用),应用程序通过PhoneFactory的getDefaultPhone函数返回统一的PhoneProxy代理对象来访问不同的Phone对象。 因为Telephony框架层支持不同的网络类型的Telephony实现(CDMA、GSM),因此Telephony框架层普遍使用代理模式来对应用提供统一的服务接口。如PhoneProxy代理对象内部还封装了IccSmsInterfaceManager、IccPhoneBookInterfaceManager、PhoneSubInfo三个服务的代理对象,通过代理对象提供对这三个服务的操作控制。
Phone对象是整个Telephony服务的核心,主要的Telephony服务(IccSmsInterfaceManager、IccPhoneBookInterfaceManager、PhoneSubInfo)及数据连接功能都通过具体的Phone对象提供,具体的Phone对象包括CDMAPhone、CDMALTEPhone、GSMPhone及SipPhone。PhoneBase抽象类是这些具体Phone对象的共同的基类,本身一个Handler类,用来提供Phone接口的基实现。
SMSDispatcher 、DataConnectionTracker 、IccFileHandler、IccRecords、IccCard等抽象类对应GSMPhone对象中的派生类分别为GsmSMSDispatcher(提供GSM模式的短消息发送和接收提交功能)、GsmDataConnectionTracker(提供GSM模式的数据连接管理功能)、SIMFileHandler(提供SIM File处理)、SIMRecords(提供SIM信息记录功能)、SimCard(提供SIM CARD功能); IccSmsInterfaceManager、IccPhoneBookInterfaceManager、PhoneSubInfo服务在GSMPhone对象中实现的具体的服务类为SimSmsInterfaceManager、 SimPhoneBookInterfaceManager及PhoneSubInfo。
另外GSMPhone对象在实例化时还实例化GsmCallTracker(提供GSM模式的CALL管理)、GsmServiceStateTracker(提供GSM模式的服务状态管理)、CatService对象(提供STK服务)。
1.1 Message
Message在telephony主要通过GsmSMSDispatcher提供GSM模式的短消息发送和接收提交功能,通过smsMessage实现短消息的编解码。
1.2 Call
GSMCallTracker是Android的通话管理层,GsmCallTracker派生自Handler的虚拟类CallTracker;
GsmCallTracke对象提供Call状态(共有IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING九种状态)的跟踪和管理,能够提供向RIL层发送请求,接收和处理RIL层发来的命令响应事件及其它主动通知事件,如振铃等CALL相关事件及Service状态事件。
GsmCallTracker对象中还提供有三个GsmCall对象(派生自抽象类Call):ringingCall(用来管理处于INCOMING和WAITING状态的通话)、foregroundCall(用来管理处于DAILING、ALERTING、ACTIVE状态的通话)、backgroundCall(用来管理HOLD的通话)。
1.3 Network States
GsmServiceStateTracker派生自Handler的虚拟类ServiceStateTracker。
GsmServiceStateTracker对象提供ServiceState(共有STATE_IN_SERVICE、STATE_OUT_OF_SERVICE、STATE_EMERGENCY_ONLY、STATE_POWER_OFF四种状态)的跟踪和管理
GsmServiceStateTracker对象中除了包括ServiceState状态信息外,还包括SignalStrength信号强度等信息。
GsmServiceStateTracker对象还维护GSM CELL位置信息,因此包含两个GsmCellLocation对象成员cellLoc(当前位置) , newCellLoc( 新位置 )。
1.4 Data Connection
Telephony框架的数据连接模块负责数据连接通道的建立,使电话能够提供数据服务,如上网等。
DataConnectionTracker是数据连接功能的核心,GsmDataConnectionTracker、CdmaDataConnectionTracker是DataConnectionTracker的两个派生类,实现具体网络的数据连接的建立和管理。
每一个数据连接用一个DataConnection对象表示,DataConnection对应的具体网络的派生类为GsmDataConnection和CdmaDataConnection。DataConnectionTracker中用一个HashMap类型的变量mDataConnections维护每一个数据连接。CDMA同时只能建立一路数据连接,GSM网络则没有限制。
DataConnection对象是一个是一个状态机对象,维护连接的状态,并提供数据连接的LinkProperties和LinkCapabilities等属性。DataConnection对象的状态包括DcDefaultState、DcInactiveState、DcActivatingState、DcActiveState、DcDisconnectingState、DcDisconnectionErrorCreatingConnection六种状态。
对于GsmDataConnectionTracker对象,ApnContext对象提供数据连接的APN上下文,每一个APN类型都对应一个ApnContext对象,ApnContext对象维护对应的APN设置、DataConnectionTracker的状态、对应的DataConnection和DataConnectionAc等。
数据连接通道的建立过程:
1、 数据连接的建立最终都通过GsmDataConnectionTracker和CdmaDataConnectionTracker的trySetupData函数启动数据连接;
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对象。
boolean trySetupData(String reason)
尝试建立数据连接。它只是检查当前手机状态是具备建立数据连接的条件,当符合条件时,就去建立连接。这些条件包括当前是否处在正常的非连接状态、phone是否处在空闲状态、SIM卡是否就绪、是否允许数据连接、数据连接是否受限、以及电源状态也允许的情况下。接着调用buildWaitingApns去构建一个可供使用的APN列表(用户设置的preferred
APN,若没设置则APN的类型匹配亦可,详见buildWaitingApns说明),若列表不为空,若就调用setupData建立数据连接。
boolean setupData(String
reason)使用PdpConnection的connect函数(最终调用到RIL的setupDataCall函数),从备选APN列表waitingApns中,选择第一个APN作为配置去建立数据连接,详见buildWaitingApns函数
APN相关API
createAllApnList:用当前SIM卡对应的运营商查询系统的所有APN,并调用createApnList创建APN列表,并找到用户设置的preferred APN
createApnList:用查询得到的数据集,创建APN列表
onApnChanged:当APN被用户更改时,将调用到此函数,重新建立数据连接
buildWaitingApns:使用用户设置的preferred APN构建一个可用于数据连接的备选APN列表,即waitingApns列表(当有preferred APN,该列表就只有一个)。若用户没有设置preferred APN,则将所有类型匹配的APN添加到waitingApns列表(如default类型)。当trySetupData函数检查有waitingApns列表中有可用的APN时,就会去尝试建立连接。
getNextApn():当PdpConnection需要用到APN建立数据连接时,将调用该函数从waitingApns备选列表中获取第一个APN,直至成功建立数据连接为止。
setPreferredApn:当用户没有设置preferred APN时,将当前数据连接成功的那个APN设置为preferred APN。详见onDataSetupComplete。
getPreferredApn:用户获取用户设置的preferred APN
1.5 Simcard
CatService对象实现STK服务,也是一个Handler对象,并实现AppInterface接口。CatService对象能够与RIL和STK应用交互:可以实现向RIL发送Envelop命令,以及从RIL接收STK事件,解析事件流(包括Proactive Command),从STK应用接收命令执行结果编码后发给RIL。CatService对象采用一个RilMessageDecoder状态机解析RIL发来的STK事件流。
1.6 PhoneNotifier
整个Telephony事件通知框架包括三层: RIL消息层、框架事件处理层、应用层。
整个框架层以PhoneBase为中心,向上通过PhoneNotifier接口向应用层发送框架层产生的的事件,应用层通过TelephonyRegistry接口提供对特定事件的监听,由PhoneNotifier接口的默认实现DefaultPhoneNotifier通过TelephonyRegistry对象向应用层发送事件通知。
1.7 TelephonyManager
TelephonyManager主要提供Phone模块各种信息的查询和监听服务。这些信息既包括设备的状态,也包括SIM卡的状态,还包括网络的状态。
TelephonyManager主要使用两个服务来访问telephony功能:
1. ITelephony,提供与telephony进行操作,交互的接口
在packages/apps/Phone中由PhoneInterfaceManager.java实现。
2. ITelephonyRegistry, 提供登记telephony事件的接口
在frameworks/base/services/java/com/android/server/TelephonyRegistry.java实现。
TelephonyManager并不是一个标准的服务(Service),因为他没有继承自任何其他的Service,,他只是一个普通的类,没有继承任何父类或接口。那么他是如何实现telephony功能的呢,它通过三个接口类ITelephonyRegistry,IPhoneSubInfo,ITelephony,获取系统服务,从而实现通信功能。
1.7.1.1 ITelephonyRegistry服务
这个服务是在TelephonyManager构造函数中得到的,他的主要作用就是对信号、呼叫转移、位置改变、数据连接状态等信息的监听。
是一个系统服务,主要完成两方面的通知任务:
1、监听Phone状态,当有新的状态时,对注册该服务的客户端进行通知。比如:
notifyCallState:通知通话状态的改变。
notifySignalStrength:通知信号的改变。
notifyCallForwardingChanged:通知呼叫转移状态的改变。
notifyDataConnection:通知数据连接的改变。
2、监听Phone状态,当有新的状态时,发送相应的广播到系统中。比如:
broadcastServiceStateChanged:广播服务状态的改变。
broadcastSignalStrengthChanged:广播信号的改变。
broadcastDataConnectionStateChanged:广播数据连接状态的改变。
客户端在得到这个服务后,可以通过统一的listen方法将自己注册为状态的监听器,如果Phone状态发生了改变,系统就会遍历所有的监听器,主动向他们发消息,调用相应的回调函数。
1.7.1.2 IPhoneSubInfo服务
这个服务是在getSubscriberInfo接口中得到的,通过这个服务可以得到软件版本、设备ID、SIM卡串号、语音信箱等信息。
1.7.1.3 ITelephony服务
这个服务很特殊,是在Phone模块中注册给系统的(其他服务都是在framework中注册的),主要功能是Phone模块相关状态的查询和处理,包括位置服务、小区注册信息、当前网络状态、是否有SIM卡插入、以及SIM卡状态等信息。在TelephonyManager中是通过getITelephony接口得到的这个服务。