您的位置:首页 > 移动开发 > Android开发

Android O 拨打电话流程之来电

2017-11-10 23:16 1461 查看
当底层Call状态发生改变时,会上报消息RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED

/hardware/ril/libril/ril_service.cpp



/frameworks/opt/telephony/src/java/com/android/internal/telephony/RadioIndication.java



/frameworks/opt/telephony/src/java/com/android/internal/telephony/RIL.java

/frameworks/opt/telephony/src/java/com/android/internal/telephony/BaseCommands.java

BaseCommands中建立了变量RegistrantList mCallStateRegistrants = new RegistrantList();



RegistrantList消息机制,底层其实也是利用Handler实现,主要利用观察者模式,一个发起通知,所有的观察者都能够接收到.

一般都在注册的类里面接收监听,所以RIL层发起的通知会在GsmCdmaCallTracker里面处置,注意注册事件里面的消息:

EVENT_CALL_STATE_CHANGE

/frameworks/opt/telephony/src/java/com/android/internal/telephony/GsmCdmaCallTracker.java



handleMessage()消息处理:



pollCallsWhenSafe在父类CallTracker中定义



发起CallList查询,调用RIL层的getCurrentCalls

GsmCdmaCallTracker中的handleMessage()消息处理:



protected synchronized void handlePollCalls(AsyncResult ar)中








调用phone发起通知

/frameworks/opt/telephony/src/java/com/android/internal/telephony/Phone.java



查看注册方法:



有两个地方注册来该方法:

/frameworks/opt/telephony/src/java/com/android/internal/telephony/CallManager.java



CallManager中处理,如果当前正在拨号,或有多余一路的来电,直接挂掉当前来电,否则继续发起通知

/packages/services/Telephony/src/com/android/services/telephony/PstnIncomingCallNotifier.java





/**
* Verifies the incoming call and triggers sending the incoming-call intent to Telecom.
*
* @param asyncResult The result object from the new ringing event.
*/
private void handleNewRingingConnection(AsyncResult asyncResult) {
Log.d(this, "handleNewRingingConnection");
Connection connection = (Connection) asyncResult.result;
if (connection != null) {
Call call = connection.getCall();
// Final verification of the ringing state before sending the intent to Telecom.
if (call != null && call.getState().isRinging()) {
sendIncomingCallIntent(connection);
}
}
}




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



/packages/services/Telecomm/src/com/android/server/telecom/components/TelecomService.java





发现最终进入TelecomSystem中去,并调用getTelecomServiceImpl方法,主要获取对象TelecomServiceImpl



/packages/services/Telecomm/src/com/android/server/telecom/TelecomServiceImpl.java



发现在TelecomServiceImpl中的成员变量mBinderImpl 是具体实现类





调用CallIntentProcessor的内部静态类来处理来电,使用Intent来交互,ACTION_INCOMING_CALL

/packages/services/Telecomm/src/com/android/server/telecom/CallIntentProcessor.java



最终还是调用CallIntentProcessor的静态方法:processIncomingCallIntent



/packages/services/Telecomm/src/com/android/server/telecom/CallsManager.java





在CallsManager中创建Call对象,之后调用Call对象的StartCreateConnection去创建连接

/packages/services/Telecomm/src/com/android/server/telecom/Call.java



/packages/services/Telecomm/src/com/android/server/telecom/CreateConnectionProcessor.java



private void attemptNextPhoneAccount()方法中调用



/packages/services/Telecomm/src/com/android/server/telecom/ConnectionServiceWrapper.java



连接创建成功后,调用callback方法中的onSuccess方法,失败调用回调消息的onFailure方法, 在onSuccess方法中调用



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



这里走的是来电,所以创建来电连接,调用onCreateIncomingConnection,但是返回为空.这个方法的实现在ConnectionService的子类TelephonyConnectionService



那么问题来了?为什么子类对象是什么时候建立的呢?

/packages/services/Telecomm/src/com/android/server/telecom/ServiceBinder.java

ConnectionServiceWrapper类的createConnection中调用了的mBinder.bind方法,其实就是调用ServiceBinder的内部类Binder2,该方法中建立来

ServiceConnection connection = new ServiceBinderConnection(call);





该方法中调用了setBinder(binder),这个方法和后面的有关系



ConnectionServiceWrapper.java继承自ServiceBinder,所以调用来该方法来获取TelephonyConnectionService



/packages/services/Telephony/src/com/android/services/telephony/TelephonyConnectionService.java





该类通过判断phone的类型是GSM还是CDMA来创建对应的连接,并返回创建成功的连接,流程又进入 ConnectionService.java中的CreateConnection



继续调用mAdapter中的handleCreateConnectionComplete

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



/packages/services/Telecomm/src/com/android/server/telecom/ConnectionServiceWrapper.java

最终也是调用ConnectionServiceWrapper的内部类Adapter



最终还是调用ConnectionServiceWrapper自己实现的方法



private final Map<String, CreateConnectionResponse> mPendingResponses = new HashMap<>();


mPendingResponses.remove(callId).handleCreateConnectionSuccess(mCallIdMapper, connection);该方法返回的就是CreateConnectionProcessor.java,实现来接口CreateConnectionResponse

/packages/services/Telecomm/src/com/android/server/telecom/CreateConnectionProcessor.java



mCallResponse其实就是Call对象,为什么呢?

这个值是在CreateConnectionProcessor的构造方法中传入



这个方法的调用在创建连接的时候传入进来的,看到没,第三个参数,this



/packages/services/Telecomm/src/com/android/server/telecom/Call.java

public class Call implements CreateConnectionResponse, EventManager.Loggable 看下继承关系,原来Call对象也继承自CreateConnectionResponse

handleCreateConnectionSuccess方法主要逻辑:根据来电还是去电执行对应他的操作



public class CallsManager extends Call.ListenerBase implements VideoProviderProxy.Listener, CallFilterResultCallback, CurrentUserProxy

Listener是call内部的接口,抽象类Call.ListenerBase实现该接口,具体实现在CallsManager中,所以又进入来CallsManager类





setCallState为CallState.RINGING,接着判断是否接通,是否写入通话记录,之后调用addCall添加call



遍历监听者,并调用onCallAdded方法,InCallController是其中一个观察者

/packages/services/Telecomm/src/com/android/server/telecom/InCallController.java



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





接着调用mPhone.internaAddCall

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

final void internalAddCall(ParcelableCall parcelableCall) {
Call call = new Call(this, parcelableCall.getId(), mInCallAdapter,
parcelableCall.getState(), mCallingPackage, mTargetSdkVersion);
mCallByTelecomCallId.put(parcelableCall.getId(), call);
mCalls.add(call);
checkCallTree(parcelableCall);
call.internalUpdate(parcelableCall, mCallByTelecomCallId);
fireCallAdded(call);
}






InCallService.java的内部类mPhoneListener,所以调用onCallAdded,但是发现InCallService没有实现



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

进入Phone应用的Dialer模块



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



将call添加到列表中

/packages/apps/Dialer/java/com/android/incallui/call/CallList.java

在CallList的方法onCallAdded中





public class InCallPresenter implements CallList.Listener

InCallPresenter实现来CallList.Listener,所以又会进入

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



private InCallState startOrFinishUi(InCallState newState)



普通电话走的是 mStatusBarNotifier.updateNotification(mCallList);

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



MT CALL流程图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  telephony