您的位置:首页 > 产品设计 > UI/UE

IMS Modify Call (2) receive request 收到视频升级请求

2016-07-17 13:59 549 查看
主要内容为MT收到视频升级的请求的过程,也是MT消息上传的过程。

流程图

可以看到信息上报跨了4个模块,没有经过service/Telecom看关键log方便跟踪
06-1919:05:41.4373329-4362/com.android.phoneV/ImsSenderRxr:Readpacket:24bytes
06-1919:05:41.4373329-4362/com.android.phoneV/ImsSenderRxr:processResponse[SUB1]
06-1919:05:41.4373329-4362/com.android.phoneD/ImsSenderRxr:Responsedata:[12,13,-1,-1,-1,-1,16,3,24,-49,1,32,0,21,1,0,0,0,26,4,8,3,16,2][SUB1]
06-1919:05:41.4373329-4362/com.android.phoneD/ImsSenderRxr:Tag-132070[SUB1]
06-1919:05:41.4373329-4362/com.android.phoneD/ImsSenderRxr:responseModifyCall132callSubState0videoPauseState2mediaId-1LocalAbilityPeerAbilityCausecode00[SUB1]
06-1919:05:41.4383329-4362/com.android.phoneD/ImsSenderRxr:[UNSL]<UNSOL_MODIFY_CALL132callSubState0videoPauseState2mediaId-1LocalAbilityPeerAbilityCausecode00[SUB1]
06-1919:05:41.4383329-3329/com.android.phoneD/ImsServiceSub:Messagereceived:what=13
06-1919:05:41.4383329-3329/com.android.phoneD/ImsServiceSub:handleCallModifyRequest(132callSubState0videoPauseState2mediaId-1LocalAbilityPeerAbilityCausecode00)
06-1919:05:41.4383329-3329/com.android.phoneD/VideoCall_ImsCallModification:onReceivedCallModify(132callSubState0videoPauseState2mediaId-1LocalAbilityPeerAbilityCausecode00)
06-1919:05:41.4383329-3329/com.android.phoneD/VideoCall_ImsCallModification:validateIncomingModifyConnectionTypenewCallType=3
06-1919:05:41.4383329-3329/com.android.phoneD/VideoCall_ImsCallModification:validateIncomingModifyConnectionTypemodifyToCurrCallType=falseisIndexValid=trueisLowBattery=false
06-1919:05:41.4393329-3329/com.android.phoneD/VideoCall_ImsVideoCallProviderImpl:(1)onCallTypeChangedsession=callid=1mediaId=5
[/code]

代码段

vendor/qcom/proprietary/telephony-apps/ims

高通私有代码,略。

frameworks/opt/net/ims

android/frameworks/opt/net/ims/src/java/com/android/ims/internal/ImsVideoCallProvider.java看到方法名带receiverequest字样,直译就是收到请求,在响应之后方法名中就会换上类似response。
/**@seeConnection.VideoProvider#receiveSessionModifyRequest*/
publicvoidreceiveSessionModifyRequest(VideoProfileVideoProfile){
if(mCallback!=null){
try{
mCallback.receiveSessionModifyRequest(VideoProfile);
}catch(RemoteExceptionignored){
}
}
}
[/code]android/frameworks/opt/net/ims/src/java/com/android/ims/internal/ImsVideoCallProviderWrapper.java
/**
*IImsVideoCallCallbackstubimplementation.
*/
privatefinalclassImsVideoCallCallbackextendsIImsVideoCallCallback.Stub{
@Override
publicvoidreceiveSessionModifyRequest(VideoProfileVideoProfile){
mHandler.obtainMessage(MSG_RECEIVE_SESSION_MODIFY_REQUEST,
VideoProfile).sendToTarget();
}
[/code]
/**Defaulthandlerusedtoconsolidatebindermethodcallsontoasinglethread.*/
privatefinalHandlermHandler=newHandler(Looper.getMainLooper()){
@Override
publicvoidhandleMessage(Messagemsg){
SomeArgsargs;
switch(msg.what){
caseMSG_RECEIVE_SESSION_MODIFY_REQUEST:
receiveSessionModifyRequest((VideoProfile)msg.obj);
break;
[/code]

frameworks/base/telecomm

android/frameworks/base/telecomm/java/android/telecom/Connection.java
/**
*Usedtoinformlistening{@linkInCallService}implementationswhenthe
*{@linkVideoProvider}receivesasessionmodificationrequest.
*<p>
*Receivedbythe{@linkInCallService}via
*{@linkInCallService.VideoCall.Callback#onSessionModifyRequestReceived(VideoProfile)},
*
*@paramvideoProfileTherequestedvideoprofile.
*@see#onSendSessionModifyRequest(VideoProfile,VideoProfile)
*/
publicvoidreceiveSessionModifyRequest(VideoProfilevideoProfile){
if(mVideoCallbacks!=null){
for(IVideoCallbackcallback:mVideoCallbacks.values()){
try{
callback.receiveSessionModifyRequest(videoProfile);//多处调用
}catch(RemoteExceptionignored){
Log.w(this,"receiveSessionModifyRequestcallbackfailed",ignored);
}
}
}
}
[/code]android/frameworks/base/telecomm/java/android/telecom/VideoCallImpl.java
/**
*IVideoCallbackstubimplementation.
*/
privatefinalclassVideoCallListenerBinderextendsIVideoCallback.Stub{
@Override
publicvoidreceiveSessionModifyRequest(VideoProfilevideoProfile){
if(mHandler==null){
return;
}
mHandler.obtainMessage(MessageHandler.MSG_RECEIVE_SESSION_MODIFY_REQUEST,
videoProfile).sendToTarget();
}
[/code]handleMessage
@Override
publicvoidhandleMessage(Messagemsg){
if(mCallback==null){
return;
}
SomeArgsargs;
switch(msg.what){
caseMSG_RECEIVE_SESSION_MODIFY_REQUEST:
mCallback.onSessionModifyRequestReceived((VideoProfile)msg.obj);
break;
[/code]前面几乎都没什么说的,走一条线就是了,然后经InCallService接口回调到InCallUI

packages/apps/InCallUI

一般客户有需求,要修改界面的话也都是该InCallUI,下层的流程是不动的,因此下面一部分比较重要android/packages/apps/InCallUI/src/com/android/incallui/InCallVideoCallCallback.java目前为止传想来的消息都只是MODIFYCALL,并没有携带说是升级还是降级,从下面的方法中可以看到有分开两种情况了。
/**
*Handlesanincomingsessionmodificationrequest.
*
*@paramvideoProfileTherequestedvideocallprofile.
*/
@Override
publicvoidonSessionModifyRequestReceived(VideoProfilevideoProfile){
Log.d(this,"onSessionModifyRequestReceivedvideoProfile="+videoProfile);
intpreviousVideoState=CallUtils.getUnPausedVideoState(mCall.getVideoState());
intnewVideoState=CallUtils.getUnPausedVideoState(videoProfile.getVideoState());
InCallPresenter.getInstance().wakeUpScreen();
booleanwasVideoCall=CallUtils.isVideoCall(previousVideoState);
booleanisVideoCall=CallUtils.isVideoCall(newVideoState);
//Checkforupgradestovideoanddowngradestoaudio.
if(wasVideoCall&&!isVideoCall){
InCallVideoCallCallbackNotifier.getInstance().downgradeToAudio(mCall);
}elseif(previousVideoState!=newVideoState){
InCallVideoCallCallbackNotifier.getInstance().upgradeToVideoRequest(mCall,
newVideoState);
}
}
[/code]downgradeToAudio()方法在后面会调用到VideoCallPresenter.java的onDowngradeToAudio()方法,进而调用exitVideoMode()退出视频模式。upgradeToVideoRequest()升级视频的请求
/**
*Informlistenersofanupgradetovideorequestforacall.
*@paramcallThecall.
*@paramvideoStateThevideostatewewanttoupgradeto.
*/
publicvoidupgradeToVideoRequest(Callcall,intvideoState){
Log.d(this,"upgradeToVideoRequestcall="+call+"newvideostate="+videoState);
for(SessionModificationListenerlistener:mSessionModificationListeners){
listener.onUpgradeToVideoRequest(call,videoState);
}
}
[/code]InCallPresenter
@Override
publicvoidonUpgradeToVideoRequest(Callcall,intvideoState){
Log.d(this,"onUpgradeToVideoRequestcall="+call+"videostate="+videoState);
if(call==null){
return;
}
call.setSessionModificationTo(videoState);
}
[/code]android/packages/apps/InCallUI/src/com/android/incallui/Call.java
/**
*Thismethodiscalledwhenwerequestforavideoupgradeordowngrade.Thishandlesthe
*sessionmodificationstateRECEIVED_UPGRADE_TO_VIDEO_REQUESTandsetsthevideostatewe
*wanttoupgrade/downgradeto.
*/
publicvoidsetSessionModificationTo(intvideoState){
Log.d(this,"setSessionModificationTo-videostate="+videoState);
if(videoState==getVideoState()){
mSessionModificationState=Call.SessionModificationState.NO_REQUEST;
Log.w(this,"setSessionModificationTo-Clearingsessionmodificationstate");
}else{
mSessionModificationState=
Call.SessionModificationState.RECEIVED_UPGRADE_TO_VIDEO_REQUEST;
setModifyToVideoState(videoState);
CallList.getInstance().onUpgradeToVideo(this);
}
Log.d(this,"setSessionModificationTo-mSessionModificationState="
+mSessionModificationState+"videostate="+videoState);
update();
}
[/code]android/packages/apps/InCallUI/src/com/android/incallui/CallList.java
publicvoidonUpgradeToVideo(Callcall){
Log.d(this,"onUpgradeToVideocall="+call);
for(Listenerlistener:mListeners){
listener.onUpgradeToVideo(call);
}
}
[/code]看前面的注释这是modifycall的唯一调用的方法,等下我们看下降级的
*Calledwhenanewmodifycallrequestcomesin
*Thisistheonlymethodthatgetscalledformodifyrequests.
*/
publicvoidonUpgradeToVideo(Callcall);
[/code]android/packages/apps/InCallUI/src/com/android/incallui/AnswerPresenter.java界面显示,(在5.1上我们自己做过升级声音提示,在6.0上高通加了一个类实现这个功能,不知道AOSP上有没有那个提示音的功能)
@Override
publicvoidonUpgradeToVideo(Callcall){
Log.d(this,"onUpgradeToVideo:"+this+"call="+call);
showAnswerUi(true);//一次
booleanisUpgradePending=isVideoUpgradePending(call);
InCallPresenterinCallPresenter=InCallPresenter.getInstance();
if(isUpgradePending
&&inCallPresenter.getInCallState()==InCallPresenter.InCallState.INCOMING){
Log.d(this,"decliningupgraderequest");
//Ifthereisincomingcallrejectupgraderequest
inCallPresenter.declineUpgradeRequest(getUi().getContext());
}elseif(isUpgradePending){
Log.d(this,"processupgraderequestasnoMTcall");
processVideoUpgradeRequestCall(call);
}
}
[/code]
privatevoidprocessVideoUpgradeRequestCall(Callcall){
Log.d(this,"processVideoUpgradeRequestCallcall="+call);
intsubId=call.getSubId();
intphoneId=mCalls.getPhoneId(subId);
mCallId[phoneId]=call.getId();
mCall[phoneId]=call;
//Listenforcallupdatesforthecurrentcall.
CallList.getInstance().addCallUpdateListener(mCallId[phoneId],this);
finalintcurrentVideoState=call.getVideoState();
finalintmodifyToVideoState=call.getModifyToVideoState();
if(currentVideoState==modifyToVideoState){
Log.w(this,"processVideoUpgradeRequestCall:Videostatesaresame.Return.");
return;
}
AnswerUiui=getUi();
if(ui==null){
Log.e(this,"Uiisnull.Can'tprocessupgraderequest");
return;
}
showAnswerUi(true);//2次
ui.showTargets(QtiCallUtils.getSessionModificationOptions(getUi().getContext(),
currentVideoState,modifyToVideoState));
}
[/code]QtiCallUtils.java根据实际情况,在界面AnswerFragment上显示不同选择。
/**
*Returnsthesessionmodificationuseroptionsbasedonsessionmodifyrequestvideostates
*(currentvideostateandmodifyrequestvideostate)
*/
publicstaticintgetSessionModificationOptions(Contextcontext,intcurrentVideoState,
intmodifyToVideoState){
if(!useExt(context)){
returnAnswerFragment.TARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST;
}
if(showVideoUpgradeOptions(currentVideoState,modifyToVideoState)){
returnAnswerFragment.TARGET_SET_FOR_QTI_VIDEO_ACCEPT_REJECT_REQUEST;
}elseif(isEnabled(VideoProfile.STATE_BIDIRECTIONAL,modifyToVideoState)){
returnAnswerFragment.TARGET_SET_FOR_QTI_BIDIRECTIONAL_VIDEO_ACCEPT_REJECT_REQUEST;
}elseif(isEnabled(VideoProfile.STATE_TX_ENABLED,modifyToVideoState)){
returnAnswerFragment.TARGET_SET_FOR_QTI_VIDEO_TRANSMIT_ACCEPT_REJECT_REQUEST;
}elseif(isEnabled(VideoProfile.STATE_RX_ENABLED,modifyToVideoState)){
returnAnswerFragment.TARGET_SET_FOR_QTI_VIDEO_RECEIVE_ACCEPT_REJECT_REQUEST;
}
returnAnswerFragment.TARGET_SET_FOR_QTI_VIDEO_ACCEPT_REJECT_REQUEST;
}
[/code]在我们的代码中,这个返回值后面被修改了,会根据运营商返回不同的值,
/**
*ChecksthebooleanflaginconfigfiletofigureoutifwearegoingtouseQtiextensionor
*not
*/
publicstaticbooleanuseExt(Contextcontext){
if(context==null){
Log.w(context,"Contextisnull...");
}
returnisConfigEnabled(context,R.bool.video_call_use_ext);//这个布尔值默认为true,但是针对mnc为405的都重写成了false
}
[/code]AnswerFragment.java显示到界面上
/**
*Setstargetsontheglowpadaccordingtotargetsetidentifiedbytheparameter.
*@paramtargetSetIntegeridentifyingthesetoftargetstouse.
*/
publicvoidshowTargets(inttargetSet){
showTargets(targetSet,VideoProfile.STATE_BIDIRECTIONAL);
}
/**
*Setstargetsontheglowpadaccordingtotargetsetidentifiedbytheparameter.
*@paramtargetSetIntegeridentifyingthesetoftargetstouse.
*/
@Override
publicvoidshowTargets(inttargetSet,intvideoState){
finalinttargetResourceId;
finalinttargetDescriptionsResourceId;
finalintdirectionDescriptionsResourceId;
finalinthandleDrawableResourceId;
mGlowpad.setVideoState(videoState);
finalbooleanisEnhanceUIEnabled=getContext().getResources().getBoolean(
R.bool.config_enable_enhance_video_call_ui);
switch(targetSet){
...
caseTARGET_SET_FOR_VIDEO_ACCEPT_REJECT_REQUEST:
targetResourceId=
R.array.incoming_call_widget_video_request_targets;
targetDescriptionsResourceId=
R.array.incoming_call_widget_video_request_target_descriptions;
directionDescriptionsResourceId=R.array
.incoming_call_widget_video_request_target_direction_descriptions;
handleDrawableResourceId=R.drawable.ic_incall_video_handle;
break;
[/code]log
06-1919:05:41.62214182-14182/com.android.dialerI/InCall:StatusBarNotifier-Willshow"dismissupgrade"actionintheincomingcallNotification
06-1919:05:41.62414182-14182/com.android.dialerI/InCall:StatusBarNotifier-Willshow"acceptupgrade"actionintheincomingcallNotification
[/code]

关键log

MTreceive

收到视频升级请求
//receive
06-1919:05:41.4373329-4362/com.android.phoneV/ImsSenderRxr:Readpacket:24bytes
06-1919:05:41.4373329-4362/com.android.phoneV/ImsSenderRxr:processResponse[SUB1]
06-1919:05:41.4373329-4362/com.android.phoneD/ImsSenderRxr:Responsedata:[12,13,-1,-1,-1,-1,16,3,24,-49,1,32,0,21,1,0,0,0,26,4,8,3,16,2][SUB1]
06-1919:05:41.4373329-4362/com.android.phoneD/ImsSenderRxr:Tag-132070[SUB1]
06-1919:05:41.4373329-4362/com.android.phoneD/ImsSenderRxr:responseModifyCall132callSubState0videoPauseState2mediaId-1LocalAbilityPeerAbilityCausecode00[SUB1]
06-1919:05:41.4383329-4362/com.android.phoneD/ImsSenderRxr:[UNSL]<UNSOL_MODIFY_CALL132callSubState0videoPauseState2mediaId-1LocalAbilityPeerAbilityCausecode00[SUB1]
[/code]

MOsendrequest,accepted,rejected,timeout

MT接受升级请求后MO的log
//acceptedresponse
06-2521:37:21.7933289-4294/com.android.phoneV/ImsSenderRxr:Readpacket:12bytes
06-2521:37:21.7933289-4294/com.android.phoneV/ImsSenderRxr:processResponse[SUB1]
06-2521:37:21.7933289-4294/com.android.phoneD/ImsSenderRxr:Responsedata:[11,13,110,0,0,0,16,2,24,17,32,0][SUB1]
06-2521:37:21.7933289-4294/com.android.phoneD/ImsSenderRxr:Tag1102170[SUB1]
06-2521:37:21.7933289-4294/com.android.phoneD/ImsSenderRxr:[0110]<MODIFY_CALL_INITIATE[SUB1]
06-2521:37:21.7933289-3289/com.android.phoneD/VideoCall_ImsCallModification:EVENT_MODIFY_CALL_INITIATE_DONEreceived
[/code]升级请求被拒绝和超时,可以看到两者的log是一样的
//sendrequest
06-2116:00:12.16713623-13623/com.android.phoneD/ImsSenderRxr:[0021]>MODIFY_CALL_INITIATE[SUB0]
//reject
06-2116:00:19.12913623-14690/com.android.phoneD/ImsSenderRxr:[0021]<MODIFY_CALL_INITIATEerror:28
06-2116:00:19.12913623-13623/com.android.phoneD/VideoCall_ImsCallModification:EVENT_MODIFY_CALL_INITIATE_DONEreceived
/
/sendrequest07-1710:00:11.6552915-2915/com.android.phoneD/ImsSenderRxr:[0028]>MODIFY_CALL_INITIATE[SUB1]
//timeout
07-1710:00:27.7332915-4049/com.android.phoneD/ImsSenderRxr:[0028]<MODIFY_CALL_INITIATEerror:2807-1710:00:27.7332915-2915/com.android.phoneD/VideoCall_ImsCallModification:EVENT_MODIFY_CALL_INITIATE_DONEreceived
07-1710:00:27.74813872-13872/com.android.dialerD/InCall:InCallVideoCallCallback-onSessionModifyResponseReceivedstatus=5requestedProfile=[VideoProfilevideoState=AudioTxRx
[/code]MT不做任何处理的话15秒后(运营商决定)MO收到运营商发来的响应消息,其中包括InCallVideoCallCallback-onSessionModifyResponseReceivedstatus=5,这个5的定义为VideoProvider.SESSION_MODIFY_REQUEST_REJECTED_BY_REMOTE(5)意为被远端拒绝了可见对于MO来说超时和reject是一样的,而在MT收到的则是VideoProvider.SESSION_MODIFY_REQUEST_TIMED_OUT(4),所以在MT方reject和timeout是区分的。然后这个error:28的定义在imsIF.proto中查到,也证明了timeout和reject的。
E_REJECTED_BY_REMOTE=28;/*Remoteendrejectedachangestartedby
REQUEST_MODIFY_CALL_INITIATE*/
[/code]

小结

整个流程中的log不多,主要是底层ImsSenderRxr.java中的log多些,UNSOL_MODIFY_CALL(未处理的新消息),MODIFY_CALL_CONFIRM(MT界面应答),MODIFY_CALL_INITIATE(MO发起),然后InCall中在一些场景中有些log,AnswerPresenter和CallCardPresenter的log。如果出问题的话也基本上在从底层和上层判断,中间应该不会有什么问题,底层看消息首发,上层看信息显示。ModifyCall已经包括upgrade和downgrade,流程整体也是一样,在需要区分的时候会通过callType(CallMofidy)来区分。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: