Platform:Android-7.1.1_r22
CS Call来电上报流程 当有来电时,modem会上报CALL_STATE_CHANGED,RIL收到此消息后,会通知GsmCdmaCallTracker进行处理。 由于GsmCdmaCallTracker的构造函数中注册监听call状态改变的事件为EVENT_CALL_STATE_CHANGE,因此RIL上报的call状态改变将会触发EVENT_CALL_STATE_CHANGE事件的处理流程。 GsmCdmaCallTracker.java public void handleMessage(Message msg) { ...... case EVENT_CALL_STATE_CHANGE:pollCallsWhenSafe(); ...... } 调用父类的方法处理。 通过RIL发起获取当前call的请求。 CallTracker.java protected void pollCallsWhenSafe() { mNeedsPoll = true; if (checkNoOperationsPending()) { mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT); mCi.getCurrentCalls(mLastRelevantPoll); } } 取得当前call后,继续在GsmCdmaCallTracker中处理。 public void handleMessage(Message msg) { ...... case EVENT_POLL_CALLS_RESULT: ...... handlePollCalls((AsyncResult)msg.obj); ...... } protected synchronized void handlePollCalls(AsyncResult ar) { ...... for (int i = 0, curDC = 0, dcSize = polledCalls.size() ; i < mConnections.length; i++) { // 将取得的当前call转换为DriverCall对象 if (curDC < dcSize) { dc = (DriverCall) polledCalls.get(curDC); ...... } ...... if (conn == null && dc != null) { // 获取到了新的链接 // Connection appeared in CLCC response that we don't know about if (mPendingMO != null && mPendingMO.compareTo(dc)) { ...... } else { ......// 新建Connection mConnections[i] = new GsmCdmaConnection(mPhone, dc, this, i); ...... if (hoConnection != null) { ...... } else { // find if the MT call is a new ring or unknown connection newRinging = checkMtFindNewRinging(dc,i); // 判断是来电还是未知链接 if (newRinging == null) { ...... } } } hasNonHangupStateChanged = true; } else if (conn != null && dc == null) { ...... } ...... if (newRinging != null) { // 通知有新的来电 mPhone.notifyNewRingingConnection(newRinging); } ......// 清空所有断开的call if (newRinging != null || hasNonHangupStateChanged || hasAnyCallDisconnected) { internalClearDisconnected(); } ......updatePhoneState(); // 更新Phone状态 ...... if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected) { mPhone.notifyPreciseCallStateChanged(); // 通知Phone状态变化 } ...... } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 先看mPhone.notifyNewRingingConnection(newRinging)的流程 其会通过GsmCdmaPhone → Phone最终通知PstnIncomingCallNotifier处理EVENT_NEW_RINGING_CONNECTION事件。 PstnIncomingCallNotifier.java private final Handler mHandler = new Handler() { public void handleMessage(Message msg) { switch(msg.what) { case EVENT_NEW_RINGING_CONNECTION:handleNewRingingConnection((AsyncResult) msg.obj); break; ...... } }; 对来电进行一些判断,然后就要准备交给telecom处理。 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); } } } private void sendIncomingCallIntent(Connection connection) { // 处理来电显示 Bundle extras = new Bundle(); if (connection.getNumberPresentation() == TelecomManager.PRESENTATION_ALLOWED && !TextUtils.isEmpty(connection.getAddress())) { Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, connection.getAddress(), null); extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, uri); } ...... PhoneAccountHandle handle = findCorrectPhoneAccountHandle(); if (handle == null) { ...... } else { TelecomManager.from(mPhone.getContext()).addNewIncomingCall(handle, extras); } } 接下来就通过TelecomManager进入了telecom中,注册新的来电。 TelecomServiceImpl.java private final ITelecomService.Stub mBinderImpl = new ITelecomService.Stub() { public void addNewIncomingCall(PhoneAccountHandle phoneAccountHandle, Bundle extras) { ...... mCallIntentProcessorAdapter.processIncomingCallIntent( mCallsManager, intent); ...... } } CallIntentProcessor.java public static class AdapterImpl implements Adapter { public void processIncomingCallIntent(CallsManager callsManager, Intent intent) { CallIntentProcessor.processIncomingCallIntent(callsManager, intent); } } 将intent解包,然后再转到CallsManager处理。 static void processIncomingCallIntent(CallsManager callsManager, Intent intent) { ...... callsManager.processIncomingCallIntent(phoneAccountHandle, clientExtras); } CallsManager.java void processIncomingCallIntent(PhoneAccountHandle phoneAccountHandle, Bundle extras) { ......// 新建Call对象 Call call = new Call( getNextCallId(), mContext, this, mLock, mConnectionServiceRepository, mContactsAsyncHelper, mCallerInfoAsyncQueryFactory, mPhoneNumberUtilsAdapter, handle, null /* gatewayInfo */, null /* connectionManagerPhoneAccount */, phoneAccountHandle, Call.CALL_DIRECTION_INCOMING /* callDirection */, false /* forceAttachToExistingConnection */, false /* isConference */ );// 初始化CallInfoImpl对象 call.initAnalytics(); ......// 准备建立Connection call.startCreateConnection(mPhoneAccountRegistrar); } 开始建立Connection的流程。 com.android.server.telecom.Call.java void startCreateConnection(PhoneAccountRegistrar phoneAccountRegistrar) { ...... mCreateConnectionProcessor = new CreateConnectionProcessor(this, mRepository, this, phoneAccountRegistrar, mContext); mCreateConnectionProcessor.process(); } 从这里开始,建立Connection的准备阶段跟拨号的流程基本相同,因此不再赘述。 从下面开始建立来电Connection的流程就跟去电不一样了。 ConnectionService.java private void createConnection( ...... boolean isUnknown) { ...... Connection connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request) : isIncoming ? onCreateIncomingConnection(callManagerAccount, request) : onCreateOutgoingConnection(callManagerAccount, request); ...... mAdapter.handleCreateConnectionComplete( callId, request, new ParcelableConnection( ...... connection.getExtras())); ...... } 建立来电Connection。 TelephonyConnectionService.java public Connection onCreateIncomingConnection( PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) { ......// 是否为video int videoState = originalConnection != null ? originalConnection.getVideoState() : VideoProfile.STATE_AUDIO_ONLY; Connection connection =createConnectionFor(phone, originalConnection, false /* isOutgoing */, request.getAccountHandle(), request.getTelecomCallId(), request.getAddress(), videoState); ...... } private TelephonyConnection createConnectionFor( ...... int videoState) { ...... if (phoneType == TelephonyManager.PHONE_TYPE_GSM) { // 建立Connection returnConnection = new GsmConnection(originalConnection, telecomCallId); } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) { ...... } if (returnConnection != null) { // 监听Connection配置完成的事件,在GsmConnection初始化完成后就会被触发 returnConnection.addTelephonyConnectionListener(mTelephonyConnectionListener); ...... } ...... } Connection现在就已经建立好了,然后接着看ConnectionService.createConnection()中mAdapter.handleCreateConnectionComplete()的流程。 ConnectionServiceAdapter.java void handleCreateConnectionComplete( String id, ConnectionRequest request, ParcelableConnection connection) { for (IConnectionServiceAdapter adapter : mAdapters) { try { adapter.handleCreateConnectionComplete(id, request, connection); } catch (RemoteException e) { } } } IConnectionServiceAdapter在ConnectionServiceWrapper中进行了实现。 ConnectionServiceWrapper.java private final class Adapter extends IConnectionServiceAdapter.Stub { public void handleCreateConnectionComplete(String callId, ConnectionRequest request, ParcelableConnection connection) { ...... ConnectionServiceWrapper.this .handleCreateConnectionComplete(callId, request, connection); ...... } } 然后又调用ConnectionServiceWrapper的handleCreateConnectionComplete()函数。 private void handleCreateConnectionComplete( String callId, ConnectionRequest request, ParcelableConnection connection) { ...... if (connection.getState() == Connection.STATE_DISCONNECTED) { ...... } else { if (mPendingResponses.containsKey(callId)) { mPendingResponses.remove(callId) .handleCreateConnectionSuccess(mCallIdMapper, connection); } } } mPendingResponses中的对象为com.android.server.telecom.Call,是在CreateConnectionProcessor.attemptNextPhoneAccount()中通过mService.createConnection(mCall, this)添加到mPendingResponses中的。 com.android.server.telecom.Call.java public void handleCreateConnectionSuccess( CallIdMapper idMapper, ParcelableConnection connection) { ...... switch (mCallDirection) { case CALL_DIRECTION_INCOMING: ...... for (Listener l : mListeners) { l.onSuccessfulIncomingCall(this); } break; ...... } } 回调到CallsManager,这里会判断是否阻止来电。 CallsManager.java public void onSuccessfulIncomingCall(Call incomingCall) { ...... List<IncomingCallFilter.CallFilter> filters = new ArrayList<>(); filters.add(new DirectToVoicemailCallFilter(mCallerInfoLookupHelper)); filters.add(new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter())); filters.add(new CallScreeningServiceFilter(mContext, this, mPhoneAccountRegistrar, mDefaultDialerManagerAdapter, new ParcelableCallUtils.Converter(), mLock)); new IncomingCallFilter(mContext, this, incomingCall, mLock, mTimeoutsAdapter, filters).performFiltering(); } 这里用到了3个filter,DirectToVoicemailCallFilter/AsyncBlockCheckFilter/CallScreeningServiceFilter,其中AsyncBlockCheckFilter就是用于黑名单处理的,而DirectToVoicemailCallFilter应该是Voice相关的,CallScreeningServiceFilter不大清楚是干啥的。 IncomingCallFilter.java public void performFiltering() { Log.event(mCall, Log.Events.FILTERING_INITIATED); for (CallFilter filter : mFilters) { filter.startFilterLookup(mCall, this); } ...... } 我们这里仅仅看下AsyncBlockCheckFilter的处理流程。 AsyncBlockCheckFilter.java public void startFilterLookup(Call call, CallFilterResultCallback callback) { ...... this.execute(number); } AsyncBlockCheckFilter是一个AsyncTask对象,在doInBackground()中执行给定的任务,其返回的结果将由onPostExecute()处理。 protected Boolean doInBackground(String... params) { ...... return mBlockCheckerAdapter.isBlocked(mContext, params[0]); ...... } mBlockCheckerAdapter是在CallsManager.onSuccessfulIncomingCall()中新建的BlockCheckerAdapter对象。 BlockCheckerAdapter.java public boolean isBlocked(Context context, String number) { return BlockChecker.isBlocked(context, number); } 最终会通过BlockedNumberProvider来判断来电号码是否在黑名单内,如果在,则返回true。 BlockChecker.java public static boolean isBlocked(Context context, String phoneNumber) { ...... if (BlockedNumberContract.SystemContract.shouldSystemBlockNumber( context, phoneNumber)) { ...... isBlocked = true; } ...... return isBlocked; } 判断完黑名单后,再转到AsyncBlockCheckFilter.onPostExecute()中处理结果。 根据block的状态创建返回结果,再回调。 AsyncBlockCheckFilter.java protected void onPostExecute(Boolean isBlocked) { ...... CallFilteringResult result; if (isBlocked) { result = new CallFilteringResult( false, // shouldAllowCall true, //shouldReject false, //shouldAddToCallLog false // shouldShowNotification ); } else { result = new CallFilteringResult( true, // shouldAllowCall false, // shouldReject true, // shouldAddToCallLog true // shouldShowNotification ); } ...... mCallback.onCallFilteringComplete(mIncomingCall, result); ...... } 回调到IncomingCallFilter。 IncomingCallFilter.java public void onCallFilteringComplete(Call call, CallFilteringResult result) { synchronized (mTelecomLock) { // synchronizing to prevent race on mResult mNumPendingFilters--; mResult = result.combine(mResult); if (mNumPendingFilters == 0) { // synchronized on mTelecomLock to enter into Telecom. mHandler.post(new Runnable("ICF.oCFC", mTelecomLock) { public void loggedRun() { if (mIsPending) { Log.event(mCall, Log.Events.FILTERING_COMPLETED, mResult); mListener.onCallFilteringComplete(mCall, mResult); mIsPending = false; } } }.prepare()); } } } 处理结果时,会把DirectToVoicemailCallFilter/AsyncBlockCheckFilter/CallScreeningServiceFilter的结果进行综合。 CallFilteringResult.java public CallFilteringResult combine(CallFilteringResult other) { ...... return new CallFilteringResult( shouldAllowCall && other.shouldAllowCall, shouldReject || other.shouldReject, shouldAddToCallLog && other.shouldAddToCallLog, shouldShowNotification && other.shouldShowNotification); } 当3个filter都处理完成后,最终又回调到CallsManager。 这里会将Call的状态设置为RINGING,并把Call添加到活动的Call列表中。 CallsManager.java public void onCallFilteringComplete(Call incomingCall, CallFilteringResult result) { ...... if (incomingCall.getState() != CallState.DISCONNECTED && incomingCall.getState() != CallState.DISCONNECTING) { // 设置Call的状态为RINGING setCallState(incomingCall, CallState.RINGING, result.shouldAllowCall ? "successful incoming call" : "blocking call"); } else { ...... } if (result.shouldAllowCall) { if (hasMaximumRingingCalls()) { ...... } else if (hasMaximumDialingCalls()) { ...... } else { addCall(incomingCall); } } else { ...... } } private void addCall(Call call) { ......// 为Call设置listener,并添加到Call的集合中 call.addListener(this); mCalls.add(call); ...... for (CallsManagerListener listener : mListeners) { ...... listener.onCallAdded(call); ...... } ...... }未完待续...... 添加call后,会回调InCallController.onCallAdded(),InCallController是在CallsManager的构造函数中初始化并添加到listener中的。 InCallController.java public void onCallAdded(Call call) { ...... addCall(call); // InCallController中也会跟踪call ...... for (Map.Entry<InCallServiceInfo, IInCallService> entry : mInCallServices.entrySet()) { ...... inCallService.addCall(parcelableCall); // AIDL调用InCallServiceBinder ...... } ...... } InCallServiceBinder.addCall()中未做任何处理,直接发送MSG_ADD_CALL消息给InCallService的Handler处理。 InCallService.java private final class InCallServiceBinder extends IInCallService.Stub { public void addCall(ParcelableCall call) { mHandler.obtainMessage(MSG_ADD_CALL, call).sendToTarget(); } } private final Handler mHandler = new Handler(Looper.getMainLooper()) { public void handleMessage(Message msg) { ...... switch (msg.what) { ...... case MSG_ADD_CALL: mPhone.internalAddCall((ParcelableCall) msg.obj); // 到android.telecom.Phone中进行处理 break; ...... } 注意,此Phone并非frameworks/opt/telephony中的Phone对象。 Phone中会把传入的ParcelableCall转换为android.telecom.Call对象进行保存,然后又通过InCallService中的mPhoneListener回调到onCallAdded()。 android.telecom.Phone.java final void internalAddCall(ParcelableCall parcelableCall) { Call call = new Call(this, parcelableCall.getId(), mInCallAdapter, parcelableCall.getState()); mCallByTelecomCallId.put(parcelableCall.getId(), call); mCalls.add(call); checkCallTree(parcelableCall); call.internalUpdate(parcelableCall, mCallByTelecomCallId); fireCallAdded(call); } private void fireCallAdded(Call call) { for (Listener listener : mListeners) { listener.onCallAdded(this, call); } } InCallService.onCallAdded()的具体实现在其子类InCallServiceImpl中。 InCallServiceImpl.java public void onCallAdded(Call call) { InCallPresenter.getInstance().onCallAdded(call); } 将Call添加到CallList。 InCallPresenter.java public void onCallAdded(final android.telecom.Call call) { ...... mCallList.onCallAdded(call); ...... } 对于来电,call状态当然是INCOMING,因此调用onIncoming()。 CallList.java public void onCallAdded(final android.telecom.Call telecomCall) { ...... if (call.getState() == Call.State.INCOMING || call.getState() == Call.State.CALL_WAITING) { onIncoming(call, call.getCannedSmsResponses()); } else { onUpdate(call); } ...... } onIncoming()又回调到InCallPresenter。 public void onIncoming(Call call, List<String> textMessages) { ...... for (Listener listener : mListeners) { listener.onIncomingCall(call); } } 调用startOrFinishUi(),最终启动来电界面。具体过程就略过了。 InCallPresenter.java public void onIncomingCall(Call call) { InCallState newState = startOrFinishUi(InCallState.INCOMING); InCallState oldState = mInCallState; Log.i(this, "Phone switching state: " + oldState + " -> " + newState); mInCallState = newState; for (IncomingCallListener listener : mIncomingCallListeners) { listener.onIncomingCall(oldState, mInCallState, call); } } ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ GsmCdmaCallTracker.handlePollCalls()中调用updatePhoneState() private void updatePhoneState() { PhoneConstants.State oldState = mState; if (mRingingCall.isRinging()) { mState = PhoneConstants.State.RINGING; } else if (mPendingMO != null || ...... if (mState == PhoneConstants.State.IDLE && oldState != mState) { mVoiceCallEndedRegistrants.notifyRegistrants( new AsyncResult(null, null, null)); } else if (oldState == PhoneConstants.State.IDLE && oldState != mState) { // 通知相关监听者Call已经建立起来了 mVoiceCallStartedRegistrants.notifyRegistrants ( new AsyncResult(null, null, null)); } ...... if (mState != oldState) { // 通知Phone状态变化 mPhone.notifyPhoneStateChanged(); TelephonyMetrics.getInstance().writePhoneState(mPhone.getPhoneId(), mState); } } notifyPhoneStateChanged()会通过GsmCdmaPhone → DefaultPhoneNotifier最终通知到TelephonyRegistry。 TelephonyRegistry.java public void notifyCallStateForPhoneId(int phoneId, int subId, int state, String incomingNumber) { ......// 回调监听了LISTEN_CALL_STATE事件的listener r.callback.onCallStateChanged(state, incomingNumberOrEmpty); ......broadcastCallStateChanged(state, incomingNumber, phoneId, subId); }