




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、 Telephony 框架设计解析 -version:1.2 -author:*目录一、RIL3二、Telephony中多卡及多运营商设计区分61.telephony中的多卡71)AP区分多卡72)modem区分多卡122.telephony中的多运营商设计14三、Telephony中AIDL模式设计15四、Telephony中观察者模式设计16五、TelephonyRegistry监听模式设计201.概述202.以状态栏信号更新为例分析注册和更新过程【YETIM-1107】201).注册过程212).RIL上报监听回调更新过程23六、ServiceStateTracker/DcTracker
2、/CallTracke27七、Telephony分析案例之检测不到SIM卡27八、手机驻网过程modem log29本篇文档将从如下六个方面讲述telephony框架设计:RIL、多卡及多运营商设计区分、不同运营商的extends继承实现、IDEL的设计、观察者模式设计、TelephonyRegistry监听模式设计、ServiceStateTracker/DcTracker/CallTracker。附上Android Telephony框架图PS:AndroidTelephony采用了分层结构,共跨越了4层:1.Telephony应用,包括了Phone、MMS和STK等应用程序2.Telep
3、hony框架,提供TelephonyManager,包含数据连接、通话、信息和SIM相关的API3.无线通信接口层(RIL),主要位于UserLibraries层中的HAL层,提供AP(ApplicationProcessor)和BP(BasebandProcessor)之间的通信功能4.Modem,位于BP,主要负责实际的无线通信能力处理一、 RILRIL有RILJ和RILC,RILJ是我们所熟悉的java侧RIL.java代码,RILC是hardware/ril目录下C代码,此处我们简单介绍下RILC模块的初始化和运行机理。Android的RIL驱动模块, 在hardware/ril目录下
4、,一共分rild,libril.so以及librefrence_ril.so三个部分,另有一radiooptions可供自动或手动调试使用。都依赖于include目录中ril.h头文件。目前cupcake分支上带的是gsm的支持,另有一cdma分支,这里分析的是gsm驱动。GSM模块,由于Modem的历史原因,AP一直是通过基于串口的AT命令与BB交互。包括到了目前的一些edge或3g模块,或像omap这类ap,bp集成的芯片,已经使用了USB或其他等高速总线通信,但大多仍然使用模拟串口机制来使用AT命令。这里的RIL(Radio Interface Layer)层,主要也就是基于AT命令的操
5、作,如发命令,response解析等。首先介绍一下rild与libril.so以及librefrence_ril.so的关系:1. rild:仅实现一main函数作为整个ril层的入口点,负责完成初始化。2. libril.so:与rild结合相当紧密,是其共享库,编译时就已经建立了这一关系。组成部分为ril.cpp,ril_event.cpp。libril.so驻留在rild这一守护进程中,主要完成同上层通信的工作,接受ril请求并传递给librefrence_ril.so, 同时把来自librefrence_ril.so的反馈回传给调用进程。3. librefrence_ril.so:ri
6、ld通过手动的dlopen方式加载,结合稍微松散,这也是因为librefrence.so主要负责跟Modem硬件通信的缘故。这样做更方便替换或修改以适配更多的Modem种类。它转换来自libril.so的请求为AT命令,同时监控Modem的反馈信息,并传递回libril.so。在初始化时, rild通过符号RIL_Init获取一组函数指针并以此与之建立联系。4. radiooptions:radiooptiongs通过获取启动参数, 利用socket与rild通信,可供调试时配置Modem参数。接下来分析初始化流程:主入口是rild.c中的main函数,主要完成三个任务:1. 开启libril
7、.so中的event机制, 在RIL_startEventLoop中,是最核心的由多路I/O驱动的消息循环。2. 初始化librefrence_ril.so,也就是跟硬件或模拟硬件modem通信的部分(后面统一称硬件), 通过RIL_Init函数完成。3. 通过RIL_Init获取一组函数指针RIL_RadioFunctions, 并通过RIL_register完成注册,并打开接受上层命令的socket通道。第一个任务流程图: 图一(RIL_startEventLoop消息循环初始化)第二个任务流程图: 图二(RIL_Init硬件modem通信部分初始化)第三个任务流程图: 图三(RIL_Ra
8、dioFunctions接受上层命令的socket通道初始化)二、Telephony中多卡及多运营商设计区分以双卡为例,上层是如何区分卡1和卡2在telephony模块中运行,AP发送AT命令后?modem如何区分去执行卡1还是卡2的操作?1.telephony中的多卡1)AP区分多卡要区分多卡,就必须要为每张卡都给其属于其自己的变量。com.android.phone是开机自启动进程,有关telephony的很多初始化都是在这个进程中完成的。下面我们来详细解析此进程:packages/services/Telephony/AndroidManifest.xml SOCKET_OPEN_MAX
9、_RETRY) throw new RuntimeException(PhoneFactory probably already running); else try Thread.sleep(SOCKET_OPEN_RETRY_MILLIS); catch (InterruptedException er) /1.初始化DefaultPhoneNotifier,第五章就是会用到此DefaultPhoneNotifier的一个例子 sPhoneNotifier = new DefaultPhoneNotifier(); int cdmaSubscription = CdmaSubscripti
10、onSourceManager.getDefault(context); Rlog.i(LOG_TAG, Cdma Subscription set to + cdmaSubscription); /* In case of multi SIM mode two instances of PhoneProxy, RIL are created, where as in single SIM mode only instance. isMultiSimEnabled() function checks whether it is single SIM or multi SIM mode */ i
11、nt numPhones = TelephonyManager.getDefault().getPhoneCount(); int networkModes = new intnumPhones; sProxyPhones = new PhoneProxynumPhones; sCommandsInterfaces = new RILnumPhones; /2.此循环是开机时给卡槽获取设置网络模式(例如是GSM ONLY还是LTE.),telephony中有关网络模式此处不做详细讲述,后面再单独讲解 for (int i = 0; i numPhones; i+) / reads the sy
12、stem properties and makes commandsinterface / Get preferred network type. networkModesi = RILConstants.PREFERRED_NETWORK_MODE; String value = TelephonyManager.getTelephonyProperty(i, ro.telephony.default_network, null); if (value != null & !value.isEmpty() try networkModesi = Integer.parseInt(value)
13、; catch (NumberFormatException ex) Rlog.i(LOG_TAG, NumberFormatException in parsing networkMode); Rlog.i(LOG_TAG, Network Mode set to + Integer.toString(networkModesi); /2.此sCommandsInterfaces很重要,会一直关联到RIL sCommandsInterfacesi = new RIL(context, networkModesi, cdmaSubscription, i); Rlog.i(LOG_TAG, C
14、reating SubscriptionController); /3.初始化SubscriptionController,一般我们获取telephony.db数据库中siminfo表里的有关sim卡信息都会用此类去获取 SubscriptionController.init(context, sCommandsInterfaces); / Instantiate UiccController so that all other classes can just / call getInstance() /4.初始化UiccController,framework中对sim卡的处理,读写等等操
15、作 mUiccController = UiccController.make(context, sCommandsInterfaces); /5.这个for循环就是区分sim卡的重点,位每个卡槽的sim创建一个phone类型,在整个telephony运行过程中,和卡槽始终对应 /6.ap侧想对某张卡进行操作时都会获取此处的phone类型变量,然后就可以进行相关设置,此处使用了代理模式 for (int i = 0; i numPhones; i+) PhoneBase phone = null; int phoneType = TelephonyManager.getPhoneType(ne
16、tworkModesi); if (phoneType = PhoneConstants.PHONE_TYPE_GSM) phone = (PhoneBase) getGsmPhone(i); else if (phoneType = PhoneConstants.PHONE_TYPE_CDMA) phone = new CDMALTEPhone(context, sCommandsInterfacesi, sPhoneNotifier, i); Rlog.i(LOG_TAG, Creating Phone with type = + phoneType + sub = + i); sProx
17、yPhonesi = new PhoneProxy(phone); mProxyController = ProxyController.getInstance(context, sProxyPhones, mUiccController, sCommandsInterfaces); / Set the default phone in base class. / FIXME: This is a first best guess at what the defaults will be. It / FIXME: needs to be done in a more controlled ma
18、nner in the future. sProxyPhone = sProxyPhones0; sCommandsInterface = sCommandsInterfaces0; / Ensure that we have a default SMS app. Requesting the app with / updateIfNeeded set to true is enough to configure a default SMS app. ComponentName componentName = SmsApplication.getDefaultSmsApplication(co
19、ntext, true /* updateIfNeeded */); String packageName = NONE; if (componentName != null) packageName = componentName.getPackageName(); Rlog.i(LOG_TAG, defaultSmsApplication: + packageName); / Set up monitor to watch for changes to SMS packages /7.初始化一个默认信息应用 SmsApplication.initSmsPackageMonitor(cont
20、ext); sMadeDefaults = true; Rlog.i(LOG_TAG, Creating SubInfoRecordUpdater ); sSubInfoRecordUpdater = new SubscriptionInfoUpdater(context, sProxyPhones, sCommandsInterfaces); SubscriptionController.getInstance().updatePhonesAvailability(sProxyPhones); / Start monitoring after defaults have been made.
21、 / Default phone must be ready before ImsPhone is created / because ImsService might need it when it is being opened. /8.Imsphone,与VoLTE:4G通话,相关 for (int i = 0; i numPhones; i+) sProxyPhonesi.startMonitoringImsService(); 此时的phone类型就出来了,AP侧可以通过PhoneFactory.java中的getPhone方法获取对应卡的phone。2)modem区分多卡 此处创建
22、了phone类型,用构造函数new出了GSMPhone或者CDMAPhone,然后会进入这两个phone类型中进行初始化。GSMPhone.java public GSMPhone(Context context, CommandsInterface ci, PhoneNotifier notifier, boolean unitTestMode, int phoneId) super(GSM, notifier, context, ci, unitTestMode, phoneId);/调用父类的构造函数,见下面的解析 if (ci instanceof SimulatedRadioCont
23、rol) mSimulatedRadioControl = (SimulatedRadioControl) ci; /这个mCi就是就连接RIL的经过RIL往modem发送指令/每张卡对应一个phone对应一个mCi对应modem处理相应的sim卡/下面这四个变量都是对应卡对应变量 mCi.setPhoneType(PhoneConstants.PHONE_TYPE_GSM);/telephony中处理RIL上报的call相关初始化 mCT = new GsmCallTracker(this);/telephony中处理注册状态,信号等相关初始化 mSST = new GsmServiceSt
24、ateTracker(this);/telephony中处理数据业务的初始化 mDcTracker = new DcTracker(this);/以上三个是telephony中非常重要的三个tracker,此处不做详细流程分析 if (!unitTestMode) mSimPhoneBookIntManager = new SimPhoneBookInterfaceManager(this); mSubInfo = new PhoneSubInfo(this); mCi.registerForAvailable(this, EVENT_RADIO_AVAILABLE, null); mCi.r
25、egisterForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null); mCi.registerForOn(this, EVENT_RADIO_ON, null); mCi.setOnUSSD(this, EVENT_USSD, null); mCi.setOnSuppServiceNotification(this, EVENT_SSN, null); mSST.registerForNetworkAttached(this, EVENT_REGISTERED_TO_NETWORK, null); mCi.setO
26、nSs(this, EVENT_SS, null); setProperties(); log(GSMPhone: constructor: sub = + mPhoneId); setProperties(); PhoneBase.java protected PhoneBase(String name, PhoneNotifier notifier, Context context, CommandsInterface ci, boolean unitTestMode, int phoneId) mPhoneId = phoneId; mName = name; mNotifier = n
27、otifier; mContext = context; mLooper = Looper.myLooper();/初始化相关变量 mCi = ci; 2.telephony中的多运营商设计区分运营商的类一般如下1. GSMPhone和CDMAPhone 继承自PhoneBase2. GsmServiceStateTracker和CdmaServiceStateTracker 继承自ServiceStateTracker3. GsmCallTracker和CdmaCallTracker 继承自CallTracker第二种和第三种在第一种的类的内部初始化,所以有第一种决定,只需要关心第一种pho
28、ne类型是如何来确定的,之前在PhoneFactory.java中我们曾提到 /2.此循环是开机时给卡槽获取设置网络模式(例如是GSM ONLY还是LTE.),telephony中有关网络模式此处不做详细讲述,后面再单独讲解 for (int i = 0; i numPhones; i+) / reads the system properties and makes commandsinterface / Get preferred network type. networkModesi = RILConstants.PREFERRED_NETWORK_MODE; String value
29、= TelephonyManager.getTelephonyProperty(i, ro.telephony.default_network, null); if (value != null & !value.isEmpty() try networkModesi = Integer.parseInt(value); catch (NumberFormatException ex) Rlog.i(LOG_TAG, NumberFormatException in parsing networkMode); . /在这里我们可以发现phone类型是由网络模式决定的 /5.这个for循环就是区
30、分sim卡的重点,位每个卡槽的sim创建一个phone类型,在整个telephony运行过程中,和卡槽始终对应 /6.ap侧想对某张卡进行操作时都会获取此处的phone类型变量,然后就可以进行相关设置,此处使用了代理模式 for (int i = 0; i numPhones; i+) PhoneBase phone = null; int phoneType = TelephonyManager.getPhoneType(networkModesi); if (phoneType = PhoneConstants.PHONE_TYPE_GSM) phone = (PhoneBase) get
31、GsmPhone(i); else if (phoneType = PhoneConstants.PHONE_TYPE_CDMA) phone = new CDMALTEPhone(context, sCommandsInterfacesi, sPhoneNotifier, i); Rlog.i(LOG_TAG, Creating Phone with type = + phoneType + sub = + i); sProxyPhonesi = new PhoneProxy(phone); 三、Telephony中AIDL模式设计Telephony中有很多地方在使用跨进程数据调用维持手机的
32、整体运行,所以有些服务died之后可能会导致phone进程crash。下面是常用的一些服务:/第五章是使用此服务的一个例子。在TelephonyRegistry.java实现 private ITelephonyRegistry getTelephonyRegistry() return ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(telephony.registry); /很多手机状态信息是通过此服务调用。在PhoneInterfaceManager.java实现 private ITelephony getIT
33、elephony() return ITelephony.Stub.asInterface(ServiceManager.getService(Context.TELEPHONY_SERVICE); /通话call相关信息科通过此服务获取 private ITelecomService getTelecomService() return ITelecomService.Stub.asInterface(ServiceManager.getService(Context.TELECOM_SERVICE); /sim信息卡相关获取服务 private IPhoneSubInfo getSubsc
34、riberInfo() return IPhoneSubInfo.Stub.asInterface(ServiceManager.getService(iphonesubinfo); /数据库和sim相关服务 private ISub getISub() return ISub.Stub.asInterface(ServiceManager.getService(isub);四、Telephony中观察者模式设计ServiceStateTracker、DcTracker、CallTracker以及其继承类中大都是使用观察者模式进行监听回调执行,下面我们举例来分析观察者模式中重要的参数问题。/我
35、们以RIL中的RIL_UNSOL_RESTRICTED_STATE_CHANGED为例RIL.java case RIL_UNSOL_RESTRICTED_STATE_CHANGED: if (RILJ_LOGD) unsljLogvRet(response, ret); if (mRestrictedStateRegistrant != null) /ret的定义是Object ret;这个参数就是modem返回的数据 /protected Registrant mRestrictedStateRegistrant;定义类型是Registrant,后面分析有用 mRestrictedStat
36、eRegistrant.notifyRegistrant( new AsyncResult (null, ret, null); break; /上面的new个对象new AsyncResult (null, ret, null),进入AsyncResult类中查看此构造函数 /由构造函数可只modem返回的参数ret传给了AsyncResult的result参数 AsyncResult.java public AsyncResult (Object uo, Object r, Throwable ex) userObj = uo; result = r; exception = ex; /然
37、后我们跟进mRestrictedStateRegistrant.notifyRegistrant的notifyRegistrant方法 /此时我们可以发现上面的ret给result参数后,在此处又new了一个AsyncResult,到这里我们就要分析msg.what = what;这里的what是哪里来的,这样或许我们就可以知道此处是如何通知观察者的了Registrant.java public void notifyRegistrant(AsyncResult ar) internalNotifyRegistrant (ar.result, ar.exception); /*package*
38、/ void internalNotifyRegistrant (Object result, Throwable exception) Handler h = getHandler(); if (h = null) clear(); else Message msg = Message.obtain(); msg.what = what; msg.obj = new AsyncResult(userObj, result, exception); h.sendMessage(msg); /接下来我们开始分析注册的地方GsmServiceStateTracker.java /此观察者注册的第一个参数是这个类里的handler,第二个是回调what参数类型,第三个是null,如果我们想传递一些我们自己设计的相关参数也可以利用这个没有使用的参数 mCi.setOnRestrictedStateChanged(this, EVENT_RESTRICTED_STATE_CHANGED, null)
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 三年级语文人教版上册语文能力提升计划
- 物流配送中心成品保护流程措施
- 部编版四年级语文第五单元教学研讨计划
- 江苏高二上学期数学试卷
- 手术后肝管-空肠吻合口狭窄的护理课件
- 慢性病患者双向转诊制度流程研究
- 教科版二年级科学能力培养计划
- 心理健康教育学生成长支持计划
- 航空维修基地6S管理组织机构及工作职责
- 湘少版五年级英语寒假学习指导计划
- 2025年茶艺师高级技能考核试卷:茶艺设备维护与操作试题
- 人教版数学七年级上册单元测试卷-第一单元-有理数(含答案)
- 《能源法》重点内容解读与实务应用
- 2025年云南省康旅控股集团有限公司招聘笔试参考题库含答案解析
- 2025年宁波市交通建设工程试验检测中心有限公司招聘笔试参考题库附带答案详解
- 《数控技术顶岗实习》课程标准
- 【MOOC】《武术基础教与学》(东北大学)中国大学慕课答案
- 神话寓言的解读寓言故事与儿童教育
- 《对血浆输注的认识》课件
- Unit 1 Friendship 讲义-2024年沪教牛津版英语七年级上册
- 《食品安全问题现状》课件
评论
0/150
提交评论