Android接电话流程跟踪
流程(java层):
首先,通过ddms拨打模拟器的电话,这样
在RIL.java的RILReceiver线程(run()函数中)当中接收到rild发来的incoming消息,接收线程将消息转给processResponse(p)进行处理,processResponse(p)又将消息转给processUnsolicited (p)处理,然后又转到
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
if (RILJ_LOGD) unsljLog(response);
mCallStateRegistrants
.notifyRegistrants(new AsyncResult(null, null, null));
break;
进行处理。这样消息就转到了mCallStateRegistrants(RegistrantList.java类中)的notifyRegistrants()函数进行处理了,接着转到internalNotifyRegistrants(ar.result, ar.exception);
消息继续上传到
Registrant r = (Registrant) registrants.get(i);
r.internalNotifyRegistrant(result, exception);
internalNotifyRegistrant的函数如下所示:
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);
}
}
注意到消息是由Handler类型的h发出的。好了
我们来看Handler
在Handler中含有如下函数(只是没有什么实现而已)
handleMessage(Message msg)
这就好说了,接着我们看消息怎么上传的吧:
我们以GSM类型的Phone为例
找到CallTracker类,我们发现这个类是由Handler继承而来的,于是我们查看下其handleMessage(Message msg)函数,发现该函数还是没有什么实现(刚看了下原来该这是个抽象类,汗。。。)
不用着急,继续往下找,我们发现GsmCallTracker类是继承自CallTracker类的,看GsmCallTracker的名字,我们应该知道这个类是做什么用的了吧。
找到handleMessage(Message msg)函数,其中有如下语句:
case EVENT_REPOLL_AFTER_DELAY:
case EVENT_CALL_STATE_CHANGE:
pollCallsWhenSafe();
break;
注意第二个case语句,有电话来了,那么call的状态自然是要改变的,呵呵。
于是,转到 pollCallsWhenSafe()进行处理。
在CallTracker类中,pollCallsWhenSafe()函数是的实现如下
protected void pollCallsWhenSafe() {
needsPoll = true;
if (checkNoOperationsPending()) {
lastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
cm.getCurrentCalls(lastRelevantPoll);
}
}
其中 public CommandsInterface cm;
于是,转到RIL.java的
public void
getCurrentCalls (Message result) {
RILRequest rr = RILRequest.obtain(RIL_REQUEST_GET_CURRENT_CALLS, result);
if (RILJ_LOGD) riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
send(rr);
}
执行
这样,消息就往底层下发了,详细过程,我不解释,当消息处理完后,RIL.java的接收线程又会收到相应的消息
进入processSolicited (Parcel p)处理,然后消息进入GsmCallTracker类的
case:EVENT_POLL_CALLS_RESULT进行处理---->handlePollCalls(AsyncResult ar)---->消息经过发送和接收后进入
case EVENT_REPOLL_AFTER_DELAY:
case EVENT_CALL_STATE_CHANGE:
pollCallsWhenSafe();
------>................消息太多,自己去跟踪吧
------>handlePollCalls((AsyncResult)msg.obj);
------>pollCallsWhenSafe();
接通电话,则进入下面的函数执行
------>operationComplete();
进入App层处理,找下CallNotifier.java的handleMessage()函数,在接下来的过程当中,就比较好跟踪了,我也懒得写了。
以下部分为查看日志得到的过程,可能存在错误
CallNotifier.java收到incoming消息后转到handleMessage()进行处理;handleMessage()将incoming消息传给onNewRingingConnection()函数进行处理;在onNewRingingConnection()函数中首先建立ringing连接,获取Call.State状态为INCOMING,然后通过PhoneApp的requestWakeState()函数唤起相应的状态(PARTIAL);然后移除PHONE_AUTO_ANSWER消息;接着执行startIncomingCallQuery(c);在函数startIncomingCallQuery中通过PhoneUtils的startGetCallerInfo()函数获取Caller的相关信息;这样就完成了ringing的连接;同时就完成了incoming状态的一个改变,进一步在CallNotifier的hangdleMessage中调用onPhoneStateChanged()函数处理相关状态的改变(包括通知PhoneApp状态改变,通知InCallScreen状态改变)。InCallScreen受到状态改变的消息后在handleMessage中对之进行处理,即要调用InCallScreen的onPhoneStateChanged()函数进行处理。回到CallNotifier.java中,当handleMessage()处理onCustomRingQueryComplete(),在该函数中会调用Ringer.java的响铃函数进行铃声通知ring(),接着再调用PhoneUtils.showIncomingCallUi();显示UI(通过调用PhoneApp类的displayCallScreen()函数)。下一步,如果接通电话,则走如下流程:
首先更新UI显示(调用CallCard.java的相关函数),然后进入InCallScreen的消息处理,接着进入PhoneUtils的answerCall()函数,在此函数中,会首先通过
PhoneApp.getInstance().getRinger().stopRing();停止响铃,然后更新UI页面。