三.InCallService完成framework层每路通话转换
1).数据通过IInCallService进入到framework完成转换处理,上面执行了什么呢?nCallService是什么,看代码,最后发现:
IInCallService inCallService =IInCallService.Stub.asInterface(service);
呵呵,aidl中的IInCallService实例,看上面代码,mInCallServices.put(componentName, inCallService),发现,只要是有继承了这个aidl的类就会被绑定,就保存其实例到列表mInCallServices,最后查明进入到了frameworks/base/telecomm的InCallService.java类中;
2).进入frameworks/base/telecomm的InCallService.java类,恍然大悟,InCallServiceBinder,即被绑定到InCallController中的连接,看看,确实继承了IInCallService.Stub ,并且实现了 addCall方法,进入此方法,调用了mHandler,看mHandler实例:
case MSG_SET_IN_CALL_ADAPTER:
mPhone = new Phone(newInCallAdapter((IInCallAdapter) msg.obj));
onPhoneCreated(mPhone);
break;
case MSG_ADD_CALL:
mPhone.internalAddCall((ParcelableCall)msg.obj);
break;
在此case中,会先调用第一个,看不懂没关系,先看onPhoneCreated(mPhone),这个最终会调用子类中的方法,其实是InCallServiceImpl(packages/apps/InCallUI)中的onPhoneCreated,先看:
@Override
public void onPhoneCreated(Phone phone) {
Log.v(this,"onPhoneCreated");
CallList.getInstance().setPhone(phone);
AudioModeProvider.getInstance().setPhone(phone);
TelecomAdapter.getInstance().setPhone(phone);
InCallPresenter.getInstance().setPhone(phone);
InCallPresenter.getInstance().setUp(
getApplicationContext(),
CallList.getInstance(),
AudioModeProvider.getInstance());
TelecomAdapter.getInstance().setContext(InCallServiceImpl.this);
}
这个方法中会调用CallList.getInstance().setPhone(phone),先不看别的,进入到CallList(packages/apps/InCallUI)中的 setPhone:
public void setPhone(Phone phone) {
mPhone = phone;
mPhone.addListener(mPhoneListener);
}
看 mPhoneListener:
private Phone.Listener mPhoneListener = newPhone.Listener() {
@Override
public void onCallAdded(Phone phone,android.telecom.Call telecommCall) {
Call call = newCall(telecommCall);
Log.d(this, "onCallAdded:telecommCall name is:" + call.getState());
if (call.getState() ==Call.State.INCOMING ||
call.getState() ==Call.State.CALL_WAITING) {
onIncoming(call,call.getCannedSmsResponses());
} else {
onUpdate(call);
}}
@Override
public void onCallRemoved(Phone phone,android.telecom.Call telecommCall) {
if(mCallByTelecommCall.containsKey(telecommCall)) {
Call call =mCallByTelecommCall.get(telecommCall);
call.setState(Call.State.DISCONNECTED);
call.setDisconnectCause(newDisconnectCause(DisconnectCause.UNKNOWN));
if(updateCallInMap(call)) {
Log.w(this,"Removing call not previously disconnected " + call.getId());
}
updateCallTextMap(call,null);}
}
};
主要是onUpdate(call)方法,在此方法追踪下去,这里给 mPhone注册了 mPhoneListener不会马上调用,继续回到上一层InCallService的case中,继续,会调用:
mPhone.internalAddCall((ParcelableCall) msg.obj);
在这里追踪Phone(frameworks\base\telecomm\java\android\telecom)类,可以看到最终会调用到:
private void fireCallAdded(Call call) {
for (Listener listener :mListeners) {
listener.onCallAdded(this, call);
}}
追查即知,调用的就是 mPhoneListener的 onCallAdded方法,在这里最终会在CallList的mCallById列表中将此Call加入进去,以便CallCardFragment调用显示到拨号界面,注意,这里的参数call是类型 android.telecom.Call telecommCall,继而调用new Call(telecommCall)进行了转换,转换成了InCallUI模块中的Call类以便调用。