Android通话过程分析_第1页
Android通话过程分析_第2页
Android通话过程分析_第3页
Android通话过程分析_第4页
Android通话过程分析_第5页
已阅读5页,还剩63页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Android通话过程分析 本文档主要对android平台下的call的实现做详细分析。Call处理的五大核心分别是:Call,Phone, CallTracker,DriverCall,Connection 1. CallCall是Call应用中的最基本的单位,其主要是用来管理Connection的。Call中非常重要的是其状态,Call中共有九种状态:IDLE, ACTIVE, HOLDING, DIALING, ALERTING, INCOMING, WAITING, DISCONNECTED, DISCONNECTING;对call的处理实际上是对状态转换上的处理。对这九中状态所对应的

2、含义和call此时的现状要很熟。Call的继承关系图:Call是一个抽象类,从图中可知,实际操作是在其子类GsmCall和CdmaCall。在GsmCall中,有个成员变量:connections,这个变量是用来管理Call中的connection的,一个Call最大允许有5个connections:static final int MAX_CONNECTIONS_PER_CALL = 5; / only 5 connections allowed per call2. PhonePhone不仅是call的处理核心,而且是整个Telephony处理的核心。Phone是一个最基本的概念,用来控制

3、Phone系统相关(即无线相关的)模块的处理:simcard,call,message,datacall等。Phone的继承关系如下:在Phone的继承关系中可知,Phone只是一个接口,它被PhoneBase和PhoneProxy实现,而PhoneBase是抽象类,它被GsmPhone和CdmaPhone继承。所以有此可知Phone分为两类:GsmPhone和CdmaPhone。PhoneBase还有另外一个继承关系:继承自Handler。这就说明GsmPhone和CdmaPhone其实都是一个Handler。所以PhoneBase的子类是可以进行事件处理的。3. ConnectionCon

4、nection用来处理一个真正的通话通路,包含通话过程中call的数据,包括号码、通话时间、MT还是MO、是第几路通话、挂断原因等信息。Connection类关系图:GsmConnection中有个成员变量:GsmCall parent,这个成员变量是用来表示该connection是属于哪个Call的。由变量名(parent)可以看出Call与Connection的关系:父与子的关系,一个Call可以有多个Connection(3gpp中规定最多5个),但一个Connection只能属于一个Call。所以一个Connection必定要依附于一个Call。Connection是怎样依附于一个Ca

5、ll的呢?从Connection的构造方法中就可以知道:a. GsmConnection (Context context, DriverCall dc, GsmCallTracker ct, int index)这个构造方法是在MT的时候使用的,因为它有一个DriverCall的参数。它通过parentFromDCState方法来获得对应的parent(Call)且通过parent.attach(this, dc);把connection加入到Call的Connections变量进行管理。b. GsmConnection (Context context, String dialString

6、, GsmCallTracker ct, GsmCall parent)这个构造方法是在MO的时候使用的,它会传入一个指定的parent(Call)且通过parent.attachFake(this, GsmCall.State.DIALING);调用把Connection加入到Call的Connections变量进行管理。从上面知道Connection调用了Call的2个重要的方法:Attach和attachFake。这两个方法都是把一个connection加入到Call的Connections成员变量中进行管理的。Call中还有一个方法detach(GsmConnection conn),

7、这个方法是用来把connection从Call中移除的。其中还有一个方法:/*package*/ boolean update (DriverCall dc)。这个是用来更新connection的。4. DriverCall是与ril层通信时的一个中间处理类,主要用来接收到ril的call数据后转到到java层上来。DriverCall中包含了协议中规定的有关call的相关参数,具体如下:public int index; /Connection Index for use with, eg, AT+CHLDpublic boolean isMT; /是incoming还是outgoingpu

8、blic State state; /connection state。public boolean isMpty;/ nonzero if is mpty call。public String number;/ Remote party numberpublic int TOA; /type of address, eg 145 = intlpublic boolean isVoice;/ nonzero if this is is a voice callpublic boolean isVoicePrivacy;/ nonzero if CDMA voice privacy mode i

9、s activepublic int als;/ ALS line indicator if available (0 = line 1)public int numberPresentation;/ 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphonepublic String name;/ Remote party namepublic int namePresentation;/ 0=Allowed, 1=Restricted, 2=Not Specified/Unknown 3=Payphone5. CallTracke

10、rCallTracker的类关系图:从上图中可以看到,CallTracker 在本质上是一个Handler。CallTracker是一个抽象类,所以其实际的操作对象是其子类:GSMCallTracker和CdmaCallTracker。下面以GSMCallTracker为例介绍CallTracker的相关处理,CdmaCallTracker处理基本与之相同。GSMCallTracker是Android 的通话管理层。GSMCallTracker建立了ConnectionList 来管理现行的通话连接,并向上层提供电话调用接口。1) ConnectionsConnections是GSMCallT

11、racker 用来维护所有的通话的列表,最大可维护7路通话。static final int MAX_CONNECTIONS = 7; / only 7 connections allowed in GSM2) ringingCall、foregroundCall、backgroundCall一个手机系统只允许3个Call同时存在,即ring call、active call和held call,所以GSMCallTracker用ringingCall、foregroundCall、backgroundCall来管理。ringingCall:用来管理INCOMING和WAITING的通话for

12、egroundCall:用来管理DAILING、ALERTING、ACTIVE的通话backgroundCall:用来管理HOLD的通话那么,ringingCall、foregroundCall、backgroundCall是如何来管理对应的call和connection的呢?前面已经讲过了Call和Connection及它们之间的关系,其实系统中的Call是已经存在的,就是上面的3个,其实主要的是对于一个connection,它需要依附于那个call,由connection的构造方法知:1) 在 从RIL获取的Calls列表的时候,通过parentFromDCState来获取相应的Call:

13、 private GsmCall parentFromDCState (DriverCall.State state) switch (state) case ACTIVE: case DIALING: case ALERTING: return owner.foregroundCall; /break; case HOLDING: return owner.backgroundCall; /break; case INCOMING: case WAITING: return owner.ringingCall; /break; default: throw new RuntimeExcept

14、ion(illegal call state: + state); 2) 在其他情况下,一般根据上面的状态直接传入对应的call。3) GsmCallTracker中的事件处理机制Call的事件处理基本上是请求应答模式,具体如下(以dail为例,其他类同):其中涉及到3个变量的处理: protected int pendingOperations;protected boolean needsPoll;protected Message lastRelevantPoll;pendingOperations:顾名思义,这个变量是在发生请求的时候会+,在处理应答的时候会-。needsPoll:该变

15、量是用来配合pendingOperations处理是否需要从RIL获取当前calls列表,并更新connections列表。lastRelevantPoll:在发送RIL_REQUEST_GET_CURRENT_CALLS的时候记录最近一次请求的message,在response的时候只对最近一次请求的response做出响应,更新connections列表。上面的3个变量主要是用来判断是否需要发送RIL_REQUEST_GET_CURRENT_CALLS请求来从RIL获取当前的calls列表,并更新connections列表。 GsmCallTracker事件处理的核心是一个异步事件的处理,

16、在发送请求后等待回应的时候,用户有可能会继续的发送对应的请求,然后会有多个response同时上报过来,上面的3个变量主要是为了更好的处理这种情况,不管用户发送了多少次请求,pendingOperations都会记录下来;而且只要用户发送了一次请求,needsPoll就为true,即就需要从RIL获取最新的call列表。所以只有当pendingOperations=0 并且 needsPoll = true的时候才发送RIL_REQUEST_GET_CURRENT_CALLS请求去获取Calls列表。 if (pendingOperations = 0 & needsPoll) lastRel

17、evantPoll= obtainMessage(EVENT_POLL_CALLS_RESULT); cm.getCurrentCalls(lastRelevantPoll); 由于中间可能发送了多次RIL_REQUEST_GET_CURRENT_CALLS请求,在多次发送此请求的过程中却没有一次response回来,最后的结果是到最后肯定会有多个response上来,而此时我们只需要更新一次就够了,lastRelevantPoll就是用来处理这个事情的:lastRelevantPoll记录了最近一次发送RIL_REQUEST_GET_CURRENT_CALLS请求时的response mes

18、sage,当返回的response message是最后一个时就更新Connections列表。4) GsmCallTracker的核心处理方法-更新connections列表处理方法protected void handlePollCalls(AsyncResult ar)的处理分析handlePollCalls(AsyncResult ar) List polledCalls;if(DBG_POLL) log(handlePollCalls);if (ar.exception = null) /没有异常,取得calllists列表 polledCalls = (List)ar.result

19、; else if (isCommandExceptionRadioNotAvailable(ar.exception) /如果radio是RADIO_NOT_AVAILABLE,则挂断所有的calls,这里的意思是所有的DriverCall是null。 polledCalls = new ArrayList(); else /其他的异常的话,推迟POLL_DELAY_MSEC = 250后再发送/RIL_REQUEST_GET_CURRENT_CALLS去获取DriverCall列表。 pollCallsAfterDelay(); return; Connection newRinging

20、= null; /or waiting boolean hasNonHangupStateChanged = false; / Any change besides / a dropped connection boolean needsPollDelay = false; boolean unknownConnectionAppeared = false; /遍历DriverCall和Connections,根据不同情况做相应处理。 for (int i = 0, curDC = 0, dcSize = polledCalls.size() ; i connections.length; i

21、+) GsmConnection conn = connectionsi; DriverCall dc = null; / polledCall list is sparse if (curDC = 0 ; i-) GsmConnection conn = droppedDuringPoll.get(i); if (conn.isIncoming() & conn.getConnectTime() = 0) / Missed or rejected call Connection.DisconnectCause cause; if (conn.cause = Connection.Discon

22、nectCause.LOCAL) cause = Connection.DisconnectCause.INCOMING_REJECTED; else cause = Connection.DisconnectCause.INCOMING_MISSED; droppedDuringPoll.remove(i); conn.onDisconnect(cause); else if (conn.cause = Connection.DisconnectCause.LOCAL) / Local hangup droppedDuringPoll.remove(i); conn.onDisconnect

23、(Connection.DisconnectCause.LOCAL); else if (conn.cause = Connection.DisconnectCause.INVALID_NUMBER) droppedDuringPoll.remove(i); conn.onDisconnect(Connection.DisconnectCause.INVALID_NUMBER); / Any non-local disconnects: determine causeif (droppedDuringPoll.size() 0) /本地挂断都是DisconnectCause.LOCAL,此处表

24、明是对方或网络端的挂断,具体/挂断原因需要从RIL处获得。 cm.getLastCallFailCause( obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE); if (needsPollDelay) pollCallsAfterDelay(); / Cases when we can no longer keep disconnected Connections / with their previous calls / 1) the phone has started to ring / 2) A Call/Connec

25、tion object has changed state. / we may have switched or held or answered (but not hung up) if (newRinging != null | hasNonHangupStateChanged) internalClearDisconnected(); 更新Phone的状态。 updatePhoneState(); if (unknownConnectionAppeared) phone.notifyUnknownConnection(); if (hasNonHangupStateChanged | newRinging != null) /通知用户callstatechange。 phone.notifyPreciseCallStateChanged(); if(DBG_POLL) log(handlePollCalls); /dumpState();Call处理中的内部接口就是PhoneUtils,它提供的主要接口如下:setAudioControlState(int)answerCall(Phone)hangup(Phone)hangupRingingCall(Phone)hangup

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论