MT 流程同时也向RIL.java上报UNSOL_RESPONSE_CALL_STATE_CHANGED消息,RIL.java收到将才标志转换为RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED,这告诉我们真正处理代码在哪个分支里,看下面代码:
processUnsolicited (Parcel p) {//主动上报的命令
…省略代码……
case RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED:
mCallStateRegistrants .notifyRegistrants(new AsyncResult(null, null, null));
break; }
上面这个通知发给谁呢,这就要先回头先看下GsmCallTracker.java的构造函数了,相信看了下面两段代码,也就知道了我们后面要找的东西(EVENT_CALL_STATE_CHANGE)了,类似的用法在phone里面很常见。
GsmCallTracker (GSMPhone phone) {
this.phone = phone;
cm = phone.mCM;
cm.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
………. }
public void registerForCallStateChanged(Handler h, int what, Object obj) {
Registrant r = new Registrant (h, what, obj);
mCallStateRegistrants.add(r);
当然EVENT_CALL_STATE_CHANGE这个消息的上会有很多原因,除了来电消息RING,还有挂断消息NOCARRIER、电话状态改变消息CLCC等,RIL都会作为EVENT_CALL_STATE_CHANGE报给GsmCallTracker.java,GsmCalTracker.java收到之后会,在handleMessage()对应分支中进行处理,代码如下:
case EVENT_CALL_STATE_CHANGE:
pollCallsWhenSafe();
break;
在phoneBase.java里发出通知
protected void notifyNewRingingConnectionP(Connection cn) {
if (!mIsVoiceCapable)
return;
AsyncResult ar = new AsyncResult(null, cn, null);
mNewRingingConnectionRegistrants.notifyRegistrants(ar);
}
再后面的代码就离开Framework层了,这里把来电消息通知给上层应用,还记得前面EVENT_CALL_STATE_CHANGE这个消息的注册和接收过程吗?,这里又用到了同样的方法,在CallNotifer.java里
private void registerForNotifications() {
mCM.registerForNewRingingConnection(this,PHONE_NEW_RINGING_CONNECTION, null);
….后面的代码省略
}
public void registerForNewRingingConnection(
Handler h, int what, Object obj) {
checkCorrectThread(h);
mNewRingingConnectionRegistrants.addUnique(h, what, obj);
}
***************************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()开始.