Android通话过程分析.docx
《Android通话过程分析.docx》由会员分享,可在线阅读,更多相关《Android通话过程分析.docx(11页珍藏版)》请在冰豆网上搜索。
Android通话过程分析
本文档主要对android平台下的call的实现做详细分析。
Call处理的五大核心分别是:
Call,Phone,CallTracker,DriverCall,Connection
1.Call
Call是Call应用中的最基本的单位,其主要是用来管理Connection的。
Call中非常重要的是其状态,Call中共有九种状态:
IDLE,ACTIVE,HOLDING,DIALING,ALERTING,INCOMING,WAITING,DISCONNECTED,DISCONNECTING;
对call的处理实际上是对状态转换上的处理。
对这九中状态所对应的含义和call此时的现状要很熟。
Call的继承关系图:
Call是一个抽象类,从图中可知,实际操作是在其子类GsmCall和CdmaCall。
在GsmCall中,有个成员变量:
connections,这个变量是用来管理Call中的connection的,一个Call最大允许有5个connections:
staticfinalintMAX_CONNECTIONS_PER_CALL=5;//only5connectionsallowedpercall
2.Phone
Phone不仅是call的处理核心,而且是整个Telephony处理的核心。
Phone是一个最基本的概念,用来控制Phone系统相关(即无线相关的)模块的处理:
simcard,call,message,datacall等。
Phone的继承关系如下:
在Phone的继承关系中可知,Phone只是一个接口,它被PhoneBase和PhoneProxy实现,而PhoneBase是抽象类,它被GsmPhone和CdmaPhone继承。
所以有此可知Phone分为两类:
GsmPhone和CdmaPhone。
PhoneBase还有另外一个继承关系:
继承自Handler。
这就说明GsmPhone和CdmaPhone其实都是一个Handler。
所以PhoneBase的子类是可以进行事件处理的。
3.Connection
Connection用来处理一个真正的通话通路,包含通话过程中call的数据,包括号码、通话时间、MT还是MO、是第几路通话、挂断原因等信息。
Connection类关系图:
GsmConnection中有个成员变量:
GsmCallparent,这个成员变量是用来表示该connection是属于哪个Call的。
由变量名(parent)可以看出Call与Connection的关系:
父与子的关系,一个Call可以有多个Connection(3gpp中规定最多5个),但一个Connection只能属于一个Call。
所以一个Connection必定要依附于一个Call。
Connection是怎样依附于一个Call的呢?
从Connection的构造方法中就可以知道:
a.GsmConnection(Contextcontext,DriverCalldc,GsmCallTrackerct,intindex)
这个构造方法是在MT的时候使用的,因为它有一个DriverCall的参数。
它通过parentFromDCState方法来获得对应的parent(Call)且通过parent.attach(this,dc);把connection加入到Call的Connections变量进行管理。
b.GsmConnection(Contextcontext,StringdialString,GsmCallTrackerct,GsmCallparent)
这个构造方法是在MO的时候使用的,它会传入一个指定的parent(Call)且通过parent.attachFake(this,GsmCall.State.DIALING);调用把Connection加入到Call的Connections变量进行管理。
从上面知道Connection调用了Call的2个重要的方法:
Attach和attachFake。
这两个方法都是把一个connection加入到Call的Connections成员变量中进行管理的。
Call中还有一个方法detach(GsmConnectionconn),这个方法是用来把connection从Call中移除的。
其中还有一个方法:
/*package*/booleanupdate(DriverCalldc)。
这个是用来更新connection的。
4.DriverCall
是与ril层通信时的一个中间处理类,主要用来接收到ril的call数据后转到到java层上来。
DriverCall中包含了协议中规定的有关call的相关参数,具体如下:
publicintindex;//ConnectionIndexforusewith,eg,AT+CHLD
publicbooleanisMT;//是incoming还是outgoing
publicStatestate;//connectionstate。
publicbooleanisMpty;//nonzeroifismptycall。
publicStringnumber;//Remotepartynumber
publicintTOA;//typeofaddress,eg145=intl
publicbooleanisVoice;//nonzeroifthisisisavoicecall
publicbooleanisVoicePrivacy;//nonzeroifCDMAvoiceprivacymodeisactive
publicintals;//ALSlineindicatorifavailable(0=line1)
publicintnumberPresentation;//0=Allowed,1=Restricted,2=NotSpecified/Unknown3=Payphone
publicStringname;//Remotepartyname
publicintnamePresentation;//0=Allowed,1=Restricted,2=NotSpecified/Unknown3=Payphone
5.CallTracker
CallTracker的类关系图:
从上图中可以看到,CallTracker在本质上是一个Handler。
CallTracker是一个抽象类,所以其实际的操作对象是其子类:
GSMCallTracker和CdmaCallTracker。
下面以GSMCallTracker为例介绍CallTracker的相关处理,CdmaCallTracker处理基本与之相同。
GSMCallTracker是Android的通话管理层。
GSMCallTracker建立了ConnectionList来管理现行的通话连接,并向上层提供电话调用接口。
1)Connections
Connections是GSMCallTracker用来维护所有的通话的列表,最大可维护7路通话。
staticfinalintMAX_CONNECTIONS=7;//only7connectionsallowedinGSM
2)ringingCall、foregroundCall、backgroundCall
一个手机系统只允许3个Call同时存在,即ringcall、activecall和heldcall,所以GSMCallTracker用ringingCall、foregroundCall、backgroundCall来管理。
ringingCall:
用来管理INCOMING和WAITING的通话
foregroundCall:
用来管理DAILING、ALERTING、ACTIVE的通话
backgroundCall:
用来管理HOLD的通话
那么,ringingCall、foregroundCall、backgroundCall是如何来管理对应的call和connection的呢?
前面已经讲过了Call和Connection及它们之间的关系,其实系统中的Call是已经存在的,就是上面的3个,其实主要的是对于一个connection,它需要依附于那个call,由connection的构造方法知:
1)在从RIL获取的Calls列表的时候,通过parentFromDCState来获取相应的Call:
privateGsmCall
parentFromDCState(DriverCall.Statestate){
switch(state){
caseACTIVE:
caseDIALING:
caseALERTING:
returnowner.foregroundCall;
//break;
caseHOLDING:
returnowner.backgroundCall;
//break;
caseINCOMING:
caseWAITING:
returnowner.ringingCall;
//break;
default:
thrownewRuntimeException("illegalcallstate:
"+state);
}
}
2)在其他情况下,一般根据上面的状态直接传入对应的call。
3)GsmCallTracker中的事件处理机制
Call的事件处理基本上是请求应答模式,具体如下(以dail为例,其他类同):
其中涉及到3个变量的处理:
protectedintpendingOperations;
protectedbooleanneedsPoll;
protectedMessagelastRelevantPoll;
pendingOperations:
顾名思义,这个变量是在发生请求的时候会++,在处理应答的时候会--。
needsPoll:
该变量是用来配合pendingOperations处理是否需要从RIL获取当前calls列表,并更新connections列表。
lastRelevantPoll:
在发送RIL_REQUEST_GET_CURRENT_CALLS的时候记录最近一次请求的message,在response的时候只对最近一次请求的response做出响应,更新connections列表。
上面的3个变量主要是用来判断是否需要发送RIL_REQUEST_GET_CURRENT_CALLS请求来从RIL获取当前的calls列表,并更新connections列表。
GsmCallTracker事件处理的核心是一个异步事件的处理,在发送请求后等待回应的时候,用户有可能会继续