Version:1.0 StartHTML:0000000194 EndHTML:0000209014 StartFragment:0000024273 EndFragment:0000208974 SourceURL:file:///Y:\Desktop\学习\新建文件夹\%5bAndroid%20O来电call流程.docx
Android O来电call流程
frameworktelephony
- 来电的消息属于主动上报的UnSolicited消息,其对应的事件ID是CALL_STATE_CHANGE,首先会调用RadioIndication.java中的callStateChanged方法来通知上层,这个时候会调用RIL.java中的processIndication方法,来向底层发送确认消息。
public void callStateChanged(int indicationType) {
mRil.processIndication(indicationType);
if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
mRil.mCallStateRegistrants.notifyRegistrants();
}
public void processIndication(int indicationType) {
if (indicationType == RadioIndicationType.UNSOLICITED_ACK_EXP) {
sendAck();
if (RILJ_LOGD) riljLog("Unsol response received; Sending ack to ril.cpp");
} else {
// ack is not expected to be sent back. Nothing is required to be done here.
}
}
- 这里通知完毕会调用notifyRegistrants方法来通知已注册的观察者(观察者模式)。在GsmCdmaCallTracker初始化的时候,就已经注册了,并传入了自身的handler,用来处理EVENT_CALL_STATE_CHANGE消息。
public GsmCdmaCallTracker (GsmCdmaPhone phone) {
…………………………
mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
…………………….
}
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
。。。。。。。。。。。。。。。。。
case EVENT_CALL_STATE_CHANGE:
pollCallsWhenSafe();
break;
。。。。。。。。。。。。。。。。。
}
}
- 接下来就会调用pollCallsWhenSafe方法,这里的mCi,实质上可以看成是RIL.java对象,这里调用了它的getCurrentCalls方法来重新去获取了当前call的状态。
protected void pollCallsWhenSafe() {
mNeedsPoll = true;
if (checkNoOperationsPending()) {
mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
mCi.getCurrentCalls(mLastRelevantPoll);
}
}
- 来到了RIL.java中的getCurrentCalls方法,这里会创建一个请求消息,然后通过Radio代理来向底层发起请求。
public void getCurrentCalls(Message result) {
IRadio radioProxy = getRadioProxy(result);
if (radioProxy != null) {
//创建一个请求消息
RILRequest rr = obtainRequest(RIL_REQUEST_GET_CURRENT_CALLS, result,
mRILDefaultWorkSource);
…….
//向底层发起请求
try {
radioProxy.getCurrentCalls(rr.mSerial);
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "getCurrentCalls", e);
}
}
}
- 等待modem层返回结果给RIL层,调用RadioResponse中的responseCurrentCalls方法。(N上的processSolicited的消息回复被抽取到这个类来了),通过底层返回的消息创建了dcCalls对象,也就是当前的Call状态信息,对dc状态进行判断后如果有需要就notify通知,如果没有异常则通过sendMessageResponse方法发送消息
private void responseCurrentCalls(RadioResponseInfo responseInfo,
ArrayList<android.hardware.radio.V1_0.Call> calls) {
判断电话状态,进行notify通知
…………
//发送返回消息
if (responseInfo.error == RadioError.NONE) {
sendMessageResponse(rr.mResult, dcCalls);
}
mRil.processResponseDone(rr, responseInfo, dcCalls);
}
}
- 之前说过,GsmCdmaCallTracker注册了观察者,这里返回的消息就会发送给他之前注册时候传入的handler来进行处理,这里我们回到GsmCdmaCallTracker中的handleMessage方法中。因为之前我们发送的是EVENT_POLL_CALLS_RESULT消息,所以我们这里只看EVENT_POLL_CALLS_RESULT消息。
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
case EVENT_POLL_CALLS_RESULT:
Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
if (msg == mLastRelevantPoll) {
if (DBG_POLL) log(
"handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
mNeedsPoll = false;
mLastRelevantPoll = null;
handlePollCalls((AsyncResult)msg.obj);
}
break;
……..
}
}
- 继续追踪handlePollCalls方法,在这方法中先对底层反馈的消息进行解析,获取其通话状态,判断如果是来电则发出notifyNewRingingConnection响铃消息通知,然后进行一些通话断开连接的操作及更新phone状态。继续跟进notifyNewRingingConnection响铃消息,该消息调用的是phone的方法。
protected synchronized void handlePollCalls(AsyncResult ar) {
//解析返回的结果
for (int i = 0, curDC = 0, dcS