汇聚下,别人对来电的分析:
http://blog.csdn.net/ninedays/article/details/5969215
接电话的基本流程(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页面。
http://www.eoeandroid.com/thread-39731-1-1.html
***************************CallNotifier***************************
本类extends Handler并且implements CallerInfoAsyncQuery.OnQueryCompleteListener
电话状态改变之后本类会接到Message,然后本Handler通过Message的不同,进入不同的case:
然后调用不同的方法处理各种状态改变。
同时实现了OnQueryCompleteListener接口,当来电的时候会帮助执行查询操作,比如查询并调用
Ringer设置响铃方式。
当来电时,本类会接受到一个PHONE_NEW_RINGING_CONNECTION(Message.what),然后调用对应的方法
onNewRingingConnection(),该方法又会调用startIncomingCallQuery()方法,该方法就查询用户
设置的铃声(可能是系统的,也可能是用户自定义的),如果查询完成则直接调用onQueryComplete().
假如执行超时的话,将会发送一个延时Message,延时后将默认调用系统的铃声。
假如在延时发送Message过程中Query已经完成,由于CallNotifier实现了OnQueryCopleteListener,
就会自动调用onQueryComplete()方法,该方法将会首先把可能存在的延时Message给Remove,以防止
再次设置铃声。接着调用onCustomRingQueryComplete()方法。然后该方法里面会调用Ringer的ring()
方法启动响铃。
********************************Ringer***************************
Ringer的ring()方法会启动相应的响铃方式。
响铃之后将会又Message发送,其内容为PHONE_STATE_CHANGED
*******************************InCallScreen**********************
InCallScreen将会接受到发送的PHONE_STATE_CHANGED消息,然后调用onPhoneStateChanged()方法
该方法将更新屏幕,CallNotifier的onCustomRingQueryComplete里也会通过PhoneUtils.showIncomingCallUi()
来启动InCallScreen屏幕。然后由InCallScreen处理,处理方式与前面打电话的大体一致,不过该类第一次调用时执行了
onCreate()方法,但是以后执行都是从onNewIntent()开始.