通话类型转换流程之AudioCall到VideoCall

目录

  1. 概述
  2. 时序图
  3. 关键代码
  4. 关键log
  5. 总结

一、概述

  这里的通话类型指的是语音通话和视频通话,转换包括upgrade/ downgrade升降级,就是语音通话升级为视频通话、视频通话降级为语音通话。升级为视频通话一般就是包括如下图示的4步,MO发起请求,MT接收请求,MT响应请求,MO接收响应。本文主要学习第一步,MO发起请求的流程(upgradeToVideo为例)。

二、时序图

如上为MO发起请求upgradeToVideo的时序图,主要包含从App(Dialer)到最终通过imsRadio发起请求的过程。

下面跟着关键代码进一步理解这一过程。

三、关键代码

代码主要包含如下几个路径,时序图最上面也有标识出。

packages\apps\Dialer

frameworks\base\telecomm

frameworks\opt\net\ims

vendor\qcom\proprietary\commonsys\telephony-apps\ims

  1. App界面点击

packages/apps/Dialer/java/com/android/incallui/incall/impl/ButtonController.java

 class UpgradeToVideoButtonController extends SimpleNonCheckableButtonController {
    public UpgradeToVideoButtonController(@NonNull InCallButtonUiDelegate delegate) {
      super(
          delegate,
          InCallButtonIds.BUTTON_UPGRADE_TO_VIDEO,
          0,
          R.string.incall_label_videocall,
          R.drawable.quantum_ic_videocam_white_36);
      Assert.isNotNull(delegate);
    }
    @Override
    public void onClick(View view) {
      delegate.changeToVideoClicked();
    }
  }

 

packages/apps/Dialer/java/com/android/incallui/CallButtonPresenter.java

  @Override
  public void changeToVideoClicked() {
    LogUtil.enterBlock("CallButtonPresenter.changeToVideoClicked");
    Logger.get(context)
        .logCallImpression(
            DialerImpression.Type.VIDEO_CALL_UPGRADE_REQUESTED,
            call.getUniqueCallId(),
            call.getTimeAddedMs());
    call.getVideoTech().upgradeToVideo(context);
  }

packages/apps/Dialer/java/com/android/incallui/videotech/ims/ImsVideoTech.java

  @Override
  public void upgradeToVideo(@NonNull Context context) {
    LogUtil.enterBlock("ImsVideoTech.upgradeToVideo");
    int unpausedVideoState = getUnpausedVideoState(call.getDetails().getVideoState());
    call.getVideoCall()
        .sendSessionModifyRequest(
            new VideoProfile(unpausedVideoState | VideoProfile.STATE_BIDIRECTIONAL));
setSessionModificationState(SessionModificationState.WAITING_FOR_UPGRADE_TO_VIDEO_RESPONSE);
    logger.logImpression(DialerImpression.Type.IMS_VIDEO_UPGRADE_REQUESTED);
  }

 

sendSessionModifyRequest,Dialer中的点击事件完成,下一步是frameworks中的流程。

  1. frameworks中的流程

video provider发送callType修改请求。
frameworks/base/telecom/java/android/telecom/VideoCallImpl.java

 

    public void sendSessionModifyRequest(VideoProfile requestProfile) {
        try {
            VideoProfile originalProfile = new VideoProfile(mVideoState, mVideoQuality);
            mVideoProvider.sendSessionModifyRequest(originalProfile, requestProfile);
        } catch (RemoteException e) {
        }
    }

frameworks/base/telecomm/java/android/telecom/Connection.java

VideoProviderBinder

/**
* IVideoProvider stub implementation.
*/
private final class VideoProviderBinder extends IVideoProvider.Stub {
    public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
       SomeArgs args = SomeArgs.obtain();
       args.arg1 = fromProfile;
       args.arg2 = toProfile;
       mMessageHandler.obtainMessage(MSG_SEND_SESSION_MODIFY_REQUEST, args).sendToTarget();
    }
}

 

VideoProviderHandler

case MSG_SEND_SESSION_MODIFY_REQUEST: {
   SomeArgs args = (SomeArgs) msg.obj;
   try {
      onSendSessionModifyRequest((VideoProfile) args.arg1, (VideoProfile) args.arg2);
   } finally {
      args.recycle();
   }
   break;
}
public abstract void onSendSessionModifyRequest(VideoProfile fromProfile,
    VideoProfile toProfile);

 

frameworks/opt/net/ims/src/java/com/android/ims/internal/ImsVideoCallProviderWrapper.java

重写 Connection.java中的onSendSessionModifyRequest方法。

/** @inheritDoc */
public void onSendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
   try {
……
       mVideoCallProvider.sendSessionModifyRequest(fromProfile, toProfile);
   } catch (RemoteException e) {
   }
}

 

frameworks/opt/net/ims/src/java/com/android/ims/internal/ImsVideoCallProvider.java

public void sendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
    SomeArgs args = SomeArgs.obtain();
    args.arg1 = fromProfile;
    args.arg2 = toProfile;
    mProviderHandler.obtainMessage(MSG_SEND_SESSION_MODIFY_REQUEST, args).sendToTarget();
}

 

mProviderHandler

case MSG_SEND_SESSION_MODIFY_REQUEST: {
    SomeArgs args = (SomeArgs) msg.obj;
    try {
        VideoProfile fromProfile = (VideoProfile) args.arg1;
        VideoProfile toProfile = (VideoProfile) args.arg2;
        onSendSessionModifyRequest(fromProfile, toProfile);
    } finally {
        args.recycle();
    }
    break;
}
/** @see Connection.VideoProvider#onSendSessionModifyRequest */
public abstract void onSendSessionModifyRequest(VideoProfile fromProfile,
            VideoProfile toProfile);

frameworks中的处理完成,下一步到高通私有类中接着处理

3、高通私有类中的流程

vendor/qcom/proprietary/commonsys/telephony-apps/ims/src/com/qualcomm/ims/

vt/ImsVideoCallProviderImpl.java

重写 onSendSessionModifyRequest方法

@Override
public void onSendSessionModifyRequest(VideoProfile fromProfile, VideoProfile toProfile) {
......
        // Neither pause or resume, so this is upgrade/downgrade request
        Message newMsg = mHandler.obtainMessage(EVENT_SEND_SESSION_MODIFY_REQUEST_DONE);
        int callType = ImsCallUtils.convertVideoStateToCallType(toProfile.getVideoState());
        mImsCallModification.changeConnectionType(newMsg, callType, null);
}

到这可以看到,从传过来的VideoProfile中获取了需要转换的callType。

Vendor/qcom/proprietary/commonsys/telephony-apps/ims/src/org/codeaurora/ims/ ImsCallModification.java

// MODIFY_CALL_INITIATE

public void changeConnectionType(Message msg, int newCallType, Map<String, String> newExtras){
......
    modifyCallInitiate(newMsg, newCallType, newExtras);
......
}
private void modifyCallInitiate(Message newMsg, int newCallType, Map<String, String> newExtras){
......
   CallDetails callDetails = new CallDetails(newCallType, mImsCallSessionImpl.getCallDomain(),
                CallDetails.getExtrasFromMap(newExtras));
   ImsCallProfile callProfile = mImsCallSessionImpl.getCallProfile();
   if (callProfile != null) {
      callDetails.setRttMode(callProfile.mMediaProfile.mRttMode);
   }
   CallModify callModify = new CallModify(callDetails, mIndex);
   mCi.modifyCallInitiate(newMsg, callModify);
}

将newCallType转换为callModify传入。

Vendor/qcom/proprietary/commonsys/telephony-apps/ims/src/org/codeaurora/

ims/ImsSenderRxr.java

 

public void modifyCallInitiate(Message result, CallModify callModify) {
    ......
    try {
        logSolicitedRequest(rr);
        imsRadioV10().modifyCallInitiate(rr.mSerial,
                ImsRadioUtils.buildCallModifyInfo(callModify));
    } catch (Exception ex) {
        removeFromQueueAndSendResponse(rr.mSerial);
        Log.e(this, msgIdString + "request to IImsRadio: Exception: " + ex);
    }
}

最后通过imsRadio将callModify发送出去

关键log

//upgrade
03-01 00:12:58.120  4918  4918 D VideoCall_ImsVideoCallProviderImpl: (1) onSendSessionModifyRequest, videoState=3 quality= 4
03-01 00:12:58.120  4918  4918 D VideoCall_ImsCallModification: validateOutgoingModifyConnectionType newCallType=3//CalllType 和videoState对应
03-01 00:12:58.120  4918  4918 D VideoCall_ImsCallModification: validateOutgoingModifyConnectionType modifyToCurrCallType = false isIndexValid = true isLowBattery = false
03-01 00:12:58.120  4918  4918 V ImsSenderRxr: modifyCallInitiate callModify=  1  3 2 callSubState 0 videoPauseState2 mediaId-1 Local Ability  Peer Ability  Cause code 0 0[SUB1]
03-01 00:12:58.120  4918  4918 V ImsSenderRxr: setCallModify callModify=  1  3 2 callSubState 0 videoPauseState2 mediaId-1 Local Ability  Peer Ability  Cause code 0 0[SUB1]
03-01 00:12:58.120  4918  4918 D ImsSenderRxr: [0044]> MODIFY_CALL_INITIATE[SUB1]
03-01 00:13:02.989  4918  5512 D ImsSenderRxr: [0044]< MODIFY_CALL_INITIATE [SUB1]
03-01 00:13:02.989  4918  4918 D VideoCall_ImsCallModification: EVENT_MODIFY_CALL_INITIATE_DONE received
03-01 00:13:02.989  4918  4918 D VideoCall_ImsCallModification: clearPendingModify imsconn=org.codeaurora.ims.ImsCallModification@1ea212
03-01 00:13:02.990  4918  4918 D VideoCall_ImsVideoCallProviderImpl: (1) handleSessionModifyDone msg.what=0
03-01 00:13:02.990  4918  4918 D VideoCall_ImsVideoCallProviderImpl: (1) Session modify success

五、总结

在实际开发中,无论是需求还是解bug,重点需要关注的是Dialer App中和framework中的流程,Vendor中的高通私有类的流程了解即可,一般不会修改到,对关键log信息要熟悉,便于对此类问题的分析。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值