远程来电流程分析---之一

来源:互联网 发布:淘宝站外推广怎么做 编辑:程序博客网 时间:2024/05/19 12:18

2,远程来电流程分析

2.1 opt telephony

handlePollCalls中有关notifyNewRingingConnection调用流程图如下,


最后会调用GSMPhone的notifyNewRingingConnection方法,

if (newRinging != null) {     mPhone.notifyNewRingingConnection(newRinging);}

GSMPhone的notifyNewRingingConnection方法直接调用父类PhoneBase的notifyNewRingingConnectionP方法,如下,

public void notifyNewRingingConnectionP(Connection cn) {     if (!mIsVoiceCapable)         return;     AsyncResult ar = new AsyncResult(null, cn, null);     mNewRingingConnectionRegistrants.notifyRegistrants(ar);}

在PhoneBase的registerForNewRingingConnection进行注册,

public void registerForNewRingingConnection(Handler h, int what, Object obj) {      checkCorrectThread(h);      mNewRingingConnectionRegistrants.addUnique(h, what, obj);}

在PstnIncomingCallNotifier的构造方法中,会调用registerForNotifications方法,该方法如下,

mPhoneBase.registerForNewRingingConnection(  mHandler, EVENT_NEW_RINGING_CONNECTION, null);

因此,当PhoneBase的notifyNewRingingConnectionP方法中调用mNewRingingConnectionRegistrants的notifyRegistrants方法时,

 PstnIncomingCallNotifier的内部Handler就会收到EVENT_NEW_RINGING_CONNECTION消息, handleMessage方法对该消息

处理如下,

case EVENT_NEW_RINGING_CONNECTION:    handleNewRingingConnection((AsyncResult) msg.obj);

2.2 services Telephony

PstnIncomingCallNotifier.java位于packages\services\Telephony路径下,来电消息在opt telephony中兜兜转转终于来到services Telephony中了。

PstnIncomingCallNotifier的handleNewRingingConnection方法调用流程图如下,


handleNewRingingConnection方法如下,

Connection connection = (Connection) asyncResult.result;//获取发送消息if (connection != null) {    Call call = connection.getCall();//获取call对象// Final verification of the ringing state before sending the intent to Telecom.    if (call != null && call.getState().isRinging()) {        if (tryBlockingIncommingCall(connection, call)) {             Log.i(this, "call was blocked by firewall");             return;        }        sendIncomingCallIntent(connection);     }}

sendIncomingCallIntent主要逻辑如下,

1,解析call信息,

Bundle extras = null;if (connection.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED &&                !TextUtils.isEmpty(connection.getAddress())) {   extras = new Bundle();   Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, connection.getAddress(), null);   extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, uri);}

2, 通过aidl接口调用telecomservice的的addNewIncomingCall方法

PhoneAccountHandle handle = findCorrectPhoneAccountHandle();if (handle == null) {   try {       connection.hangup();//直接挂断电话   } catch (CallStateException e) {       // connection already disconnected. Do nothing   }} else {  TelecomManager.from(mPhoneProxy.getContext()).addNewIncomingCall(handle, extras);}

TelecomManager的目录如下,

frameworks\base\telecomm  是services telecom对外提供的API, TelecomManager的from方法如下,

public static TelecomManager from(Context context) {    return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);}

该服务对象是TelecomServiceImpl的匿名内部类ITelecomService.Stub。

居然一步就走到了services telecom中。

2.3 services telecom

TelecomServiceImpl的addNewIncomingCall方法调用流程图如下,


TelecomServiceImpl的匿名内部类ITelecomService.Stub的addNewIncomingCall方法部分代码如下,

long token = Binder.clearCallingIdentity();try {    Intent intent = new Intent(TelecomManager.ACTION_INCOMING_CALL);   intent.putExtra(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE,                            phoneAccountHandle);   intent.putExtra(CallIntentProcessor.KEY_IS_INCOMING_CALL, true);   if (extras != null) {     intent.putExtra(TelecomManager.EXTRA_INCOMING_CALL_EXTRAS, extras);   }  CallIntentProcessor.processIncomingCallIntent(mCallsManager, intent);

CallIntentProcessor中的建立连接的流程在去电部分已经详细论述了。流程图如下,



这样,建立连接后,又走到了services Telephony中。