Android5.1 Telecomm层通话去电流程两路进程分析之三创建去电通话连接

三.创建去电通话连接

1.在调用到CallsManager.java中startOutgoingCall去做每路通话管理和通话界面显示的过程中,同时发出了 NewOutgoingCallIntentBroadcaster,我们看在这里做了什么,进入NewOutgoingCallIntentBroadcaster.java,主要方法是processIntent():

if (Intent.ACTION_CALL.equals(action)|| Intent.ACTION_CALL_PRIVILEGED.equals(action)) {
// Voicemail calls will be handled directly by the telephony connection manager
Log.i(this, "Placing call immediately instead of waiting for + " OutgoingCallBroadcastReceiver: %s", intent);
boolean speakerphoneOn = mIntent.getBooleanExtra(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, false);
mCallsManager.placeOutgoingCall(mCall, handle, null, speakerphoneOn,VideoProfile.VideoState.AUDIO_ONLY);
return DisconnectCause.NOT_DISCONNECTED;
} else {
  Log.i(this, "Unhandled intent %s. Ignoring and not placing call.", intent);
  return DisconnectCause.OUTGOING_CANCELED;
}

看关键的一行:
mCallsManager.placeOutgoingCall(mCall, handle, null, speakerphoneOn,VideoProfile.VideoState.AUDIO_ONLY);

2.这里做了什么呢?其实跟进去既可以看到,在CallsManager中的 placeOutgoingCall()方法中:
call.setHandle(uriHandle);
        call.setGatewayInfo(gatewayInfo);
        call.setStartWithSpeakerphoneOn(speakerphoneOn);
        call.setVideoState(videoState);

boolean isEmergencyCall = TelephonyUtil.shouldProcessAsEmergency(mContext,call.getHandle());
if (isEmergencyCall) {
// Emergency -- CreateConnectionProcessor will choose accounts automatically
  call.setTargetPhoneAccount(null);
}
if (call.getTargetPhoneAccount() != null || isEmergencyCall) {
// If the account has been set, proceed to place the outgoing call.
// Otherwise the connection will be initiated when the account is set by the user.
   call.startCreateConnection(mPhoneAccountRegistrar);
}

这里先拿到call的实例,然后对这个实例做一些配置工作,比如设置状态,对方号码,即将进入拨号,不过,这里出现了非常重要的一行代码:

call.startCreateConnection(mPhoneAccountRegistrar);

我们知道拨打电话,这一路通话必须要建立一个连接Connection,这个连接就好比一个通道,只有将连接建立好我们的电话才有可能到达对方端,才能够拨打电话成功,我们继续跟踪,看看这个连接是如何建立起来的,进入Call.java(packages/services/Telecomm)中查看方法startCreateConnection():

Preconditions.checkState(mCreateConnectionProcessor == null);
        mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this,phoneAccountRegistrar, mContext);
        mCreateConnectionProcessor.process();

直接查看CreateConnectionProcessor.java(packages/services/Telecomm)中的方法process():

clearTimeout();
mAttemptRecords = new ArrayList<>();
if (mCall.getTargetPhoneAccount() != null) {
   mAttemptRecords.add(new CallAttemptRecord(
   mCall.getTargetPhoneAccount(), mCall.getTargetPhoneAccount()));
}
adjustAttemptsForConnectionManager();
adjustAttemptsForEmergency();
mAttemptRecordIterator = mAttemptRecords.iterator();
attemptNextPhoneAccount();

这个CreateConnectionProcessor就是建立通话连接的类,看它的 attemptNextPhoneAccount()方法:

ConnectionServiceWrapper service =mRepository.getService(phoneAccount.getComponentName(),phoneAccount.getUserHandle());
if (service == null) {
Log.i(this, "Found no connection service for attempt %s", attempt);
attemptNextPhoneAccount();
} else {
mCall.setConnectionManagerPhoneAccount(attempt.connectionManagerPhoneAccount);
mCall.setTargetPhoneAccount(attempt.targetPhoneAccount);
mCall.setConnectionService(service);
setTimeoutIfNeeded(service, attempt);
Log.i(this, "Attempting to call from %s", service.getComponentName());
service.createConnection(mCall, new Response(service));
  }


看代码看关键地方,我们看到这里先拿到了ConnectionServiceWrapper的一个实例service,然后:

mCall.setConnectionService(service);
service.createConnection(mCall, new Response(service));

这里调用了Call.java(packages/services/Telecomm)中的 setConnectionService方法保存service实例,然后调用service实例也就是ConnectionServiceWrapper类的createConnection方法,在这个方法中才最终创建了connection,创建成功后会调用当前类的handleCreateConnectionSuccess方法:

for (Listener l : mListeners) {
l.onSuccessfulOutgoingCall(this,getStateFromConnectionState(connection.getState()));
}

在这里,最终是调用了CallsManager.java中的onSuccessfulOutgoingCall方法去做显示通话界面的动作了,至于为什么是调用了CallsManager.java类中的方法,我们在后面的具体如何创建通话连接中会有详细的剖析。那么到这里,我们介绍了通话的两路进程的大概流程,那么,这两路进程又有什么联系呢,创建通话连接成功后是怎么具体通知前台显示通话界面呢,我们接下来继续分析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值