Android P OS Call 流程简析[telephony]
Call根据拨打网络不同, 分为normall call [通过CS网络拨打] 和 IMS call [也就是volte,通过IMS网络拨打]。
根据操作流程不同,分为主叫[MO]和被叫[MT].
一、MO call [往外拨打电话]
1. 整体状态流转 :
DIALING -----------> ALERTING-----------> ACTIVE ---------->HANGUP
2. 整体结构: [图中文件根据log的主要体现列出,并非全部文件哦]

3. 重点关注telephony 部分
1. TelephonyConnectionService.java .
dial事件从Telecom 传到 Telephony,的入口就在TelephonyConnectionService中onCreateOutgoingConnection()这个函数。
a.这个函数会get真正的telephony的phone对象;
b.会通过CarrierConfigManager获取carrierConfig;
c.会检查radio的状态
d.会创建TelephonyConnection。
2.GsmCdmaPhone.java
这个文件的dial函数 进行逻辑的dial动作,并且返回一个com.android.internal.telephony.Connection这个connection会跟随这个call的整个生命周期。
a.首先会根据刚才的CarrierConfig, 判断emergencycall 是否使用IMSPhone进行dial. 如果是,这一步会调用IMSPhone.dial()。
b.然后判断ServiceState是否可以打电话,airplane mode或者 outofService 等情况都会抛出异常。
c.然后转到dialInternal(),这个函数通过GsmMmiCode对Mmicode进行处理,并且会判断CLIR的状态。
d.对于normalcall ,满足mmi==null,接下来会直接调用GsmCdmaCallTracker.dial();
3.GsmCdmaCallTracker.java
a. 根据carrierConfig对拨出号码进行convert,通过convertNumberIfNecessary()。
b. 必须保证当前dial的这一通电话必须是foregroundCall, 所以如果当前已经有active的通话,需要将当前的通话 hold.
c. 创建了新的GsmCdmaConnection->mPendingMO , 这个Connection会成为telephony与RIL沟通的状态传递媒介。

二、MT Call [接听电话]
1. 整体流程 :

2. 分步具体分析:
1. unsol call Ring
a. mCi.setOnCallRing(this, EVENT_CALL_RING, null);
过程中会检查这个prop"ro.telephony.call_ring.multiple", 在 init.qcom.rc 中默认是false,false时会发送delaymessage -->EVENT_CALL_RING_CONTINUE, 只要call 的状态是PhoneConstants.State.RINGING,就会不断发送ring的notify;如果是true , 会直接调用notify ---> mIncomingRingRegistrants.notifyRegistrants(ar);
b. Phone.java
phone.registerForIncomingRing(handler, EVENT_INCOMING_RING,mRegistrantidentifier);
c. CallManager.java
这里handle EVENT_INCOMING_RING的时候会对ActiveFgCall进行判断。
2.unsol call state change
callstate 变化的消息从modem上报之后会暂存在qcril模块中。unsol的消息会传到GsmCdmaCallTracker.java , 然后下发get_current_call. 去读取暂存在qcril模块中的call 的具体状态信息。
3.get_current_call
a. 首先由GsmCdmaCallTracker.java
下发get_current_call的请求到RIL,并且绑定resonse的event为EVENT_POLL_CALLS_RESULT
b. RadioResponse.java
中getCurrentCallsResponse()会创建一个dc【DriverCall】对象放在dcCalls这个List中。之后会根据msg发送EVENT_POLL_CALLS_RESULT给他的handler,也就是GsmCdmaCallTracker.
c. GsmCdmaCallTracker.java ,
首先会对mPendingMO进行检查,如果当前有dialing call ,则将这个dialing hangup掉 ;
然后根据dc中的数据创建一个新的GsmCdmaConnection;
这里有一个对于dc的检查,如果当前dc的connection属于srvcc过程中的mHandoverConnections ,则进行另一番操作,暂时不表;
之后,正常MT call 会根据phony type 被加入到相对应的 newUnknownConnectionsGsm/newUnknownConnectionsCDMA ConnectionList.
至此,如果这是一通状态正常的NewInComing Call , 会发送mPhone.notifyNewRingingConnection(newRinging) 到PstnIncomingCallNotifier ;如果这通电话上来的状态是不正常 或者 hangup , 那么会下发 mCi.getLastCallFailCause(), 获取通话结束原因。
d.,PstnIncomingCallNotifier.java
根据telephony的GsmCdmaConnection对象 创建Telecom的 PhoneAccountHandle对象,并且通过TelecomManager.java 最终调用到TelecomServiceImpl.java 的addNewIncomingCall() ;

