Version:1.0 StartHTML:0000000194 EndHTML:0000209014 StartFragment:0000024273 EndFragment:0000208974 SourceURL:file:///Y:\Desktop\学习\新建文件夹\%5bAndroid%20O来电call流程.docx
Android O来电call流程
frameworktelephony
public void callStateChanged(int indicationType) {
mRil.processIndication(indicationType);
if (RIL.RILJ_LOGD) mRil.unsljLog(RIL_UNSOL_RESPONSE_CALL_STATE_CHANGED);
mRil.mCallStateRegistrants.notifyRegistrants();
}
public void processIndication(int indicationType) {
if (indicationType == RadioIndicationType.UNSOLICITED_ACK_EXP) {
sendAck();
if (RILJ_LOGD) riljLog("Unsol response received; Sending ack to ril.cpp");
} else {
// ack is not expected to be sent back. Nothing is required to be done here.
}
}
public GsmCdmaCallTracker (GsmCdmaPhone phone) {
…………………………
mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null);
…………………….
}
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
。。。。。。。。。。。。。。。。。
case EVENT_CALL_STATE_CHANGE:
pollCallsWhenSafe();
break;
。。。。。。。。。。。。。。。。。
}
}
protected void pollCallsWhenSafe() {
mNeedsPoll = true;
if (checkNoOperationsPending()) {
mLastRelevantPoll = obtainMessage(EVENT_POLL_CALLS_RESULT);
mCi.getCurrentCalls(mLastRelevantPoll);
}
}
public void getCurrentCalls(Message result) {
IRadio radioProxy = getRadioProxy(result);
if (radioProxy != null) {
//创建一个请求消息
RILRequest rr = obtainRequest(RIL_REQUEST_GET_CURRENT_CALLS, result,
mRILDefaultWorkSource);
…….
//向底层发起请求
try {
radioProxy.getCurrentCalls(rr.mSerial);
} catch (RemoteException | RuntimeException e) {
handleRadioProxyExceptionForRR(rr, "getCurrentCalls", e);
}
}
}
private void responseCurrentCalls(RadioResponseInfo responseInfo,
ArrayList
判断电话状态,进行notify通知
…………
//发送返回消息
if (responseInfo.error == RadioError.NONE) {
sendMessageResponse(rr.mResult, dcCalls);
}
mRil.processResponseDone(rr, responseInfo, dcCalls);
}
}
public void handleMessage(Message msg) {
AsyncResult ar;
switch (msg.what) {
case EVENT_POLL_CALLS_RESULT:
Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received");
if (msg == mLastRelevantPoll) {
if (DBG_POLL) log(
"handle EVENT_POLL_CALL_RESULT: set needsPoll=F");
mNeedsPoll = false;
mLastRelevantPoll = null;
handlePollCalls((AsyncResult)msg.obj);
}
break;
……..
}
}
protected synchronized void handlePollCalls(AsyncResult ar) {
//解析返回的结果
for (int i = 0, curDC = 0, dcSize = polledCalls.size()
; i < mConnections.length; i++) {
GsmCdmaConnection conn = mConnections[i];
DriverCall dc = null;
// polledCall list is sparse
if (curDC < dcSize) {
dc = (DriverCall) polledCalls.get(curDC);
if (dc.index == i+1) {
curDC++;
} else {
dc = null;
}
}
...
if (conn == null && dc != null) {
...状态的处理及识别
//响铃消息通知
if (newRinging != null) {
mPhone.notifyNewRingingConnection(newRinging);
}
// clear the "local hangup" and "missed/rejected call"
// cases from the "dropped during poll" list
// These cases need no "last call fail" reason
ArrayList
for (int i = mDroppedDuringPoll.size() - 1; i >= 0 ; i--) {
GsmCdmaConnection conn = mDroppedDuringPoll.get(i);
//CDMA
boolean wasDisconnected = false;
//来电处理,本地挂断或者未接,本地挂断的话直接设置挂断的原因为LOCAL或INVALID_NUMBER
if (conn.isIncoming() && conn.getConnectTime() == 0) {
// Missed or rejected call
int cause;
if (conn.mCause == DisconnectCause.LOCAL) {
cause = DisconnectCause.INCOMING_REJECTED;
} else {
cause = DisconnectCause.INCOMING_MISSED;
}
if (Phone.DEBUG_PHONE) {
log("missed/rejected call, conn.cause=" + conn.mCause);
log("setting cause to " + cause);
}
mDroppedDuringPoll.remove(i);
hasAnyCallDisconnected |= conn.onDisconnect(cause);
wasDisconnected = true;
locallyDisconnectedConnections.add(conn);
} else if (conn.mCause == DisconnectCause.LOCAL
|| conn.mCause == DisconnectCause.INVALID_NUMBER) {
mDroppedDuringPoll.remove(i);
hasAnyCallDisconnected |= conn.onDisconnect(conn.mCause);
wasDisconnected = true;
locallyDisconnectedConnections.add(conn);
}
if (!isPhoneTypeGsm() && wasDisconnected && unknownConnectionAppeared
&& conn == newUnknownConnectionCdma) {
unknownConnectionAppeared = false;
newUnknownConnectionCdma = null;
}
}
if (locallyDisconnectedConnections.size() > 0) {
mMetrics.writeRilCallList(mPhone.getPhoneId(), locallyDisconnectedConnections);
}
/* Disconnect any pending Handover connections */
//通话断开的一些处理操作
...
if (newRinging != null || hasNonHangupStateChanged || hasAnyCallDisconnected) {
internalClearDisconnected();
}
//更新phone状态
if (VDBG) log("handlePollCalls calling updatePhoneState()");
updatePhoneState();
...
}
public void notifyNewRingingConnectionP(Connection cn) {
if (!mIsVoiceCapable)
return;
AsyncResult ar = new AsyncResult(null, cn, null);
mNewRingingConnectionRegistrants.notifyRegistrants(ar);
}
查看发现,CallsManager注册了,所以这个时候会同时到CallsManager,
protected void registerForPhoneStates(Phone phone) {
…………..
phone.registerForNewRingingConnection(handler, EVENT_NEW_RINGING_CONNECTION,
mRegistrantidentifier);
}
同样的,来到CallsManager中的handleMessage方法查看EVENT_NEW_RINGING_CONNECTION消息处理。再判断完是否需要挂断之后,会通知到PstnIncommingCallNotifier来处理此消息。这里会调用handleNewRingingConnection方法,来
sendIncomingCallIntent。
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()) {
if (ExtensionManager.getDigitsUtilExt().isConnectionMatched(connection,
mPhoneAccountHandle, mPhone.getContext()) == false) {
return;
}
sendIncomingCallIntent(connection);
}
}
}
Telephony-Service
private void sendIncomingCallIntent(Connection connection) {
Bundle extras = new Bundle();
//extras填充一些数据
...
PhoneAccountHandle handle = findCorrectPhoneAccountHandle();
if (handle == null) {
//挂断
} else {
TelecomManager.from(mPhone.getContext()).addNewIncomingCall(handle, extras);
}
}
//获取telecomm服务
public static TelecomManager from(Context context) {
return (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
}
void processIncomingCallIntent(PhoneAccountHandle phoneAccountHandle, Bundle extras) {
Log.d(this, "processIncomingCallIntent");
...
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 */
mClockProxy);
...
call的一些状态设置
...
call.initAnalytics();
if (getForegroundCall() != null) {
getForegroundCall().getAnalytics().setCallIsInterrupted(true);
call.getAnalytics().setCallIsAdditional(true);
}
setIntentExtrasAndStartTime(call, extras);
//添加监听
// TODO: Move this to be a part of addCall()
call.addListener(this);
if (!isHandoverAllowed || (call.isSelfManaged() && !isIncomingCallPermitted(call,
call.getTargetPhoneAccount()))) {
notifyCreateConnectionFailed(phoneAccountHandle, call);
} else {
//成功上报上去建立连接
call.startCreateConnection(mPhoneAccountRegistrar);
}
}
Connection connection = isUnknown ? onCreateUnknownConnection(callManagerAccount, request)
: isIncoming ? onCreateIncomingConnection(callManagerAccount, request)
: onCreateOutgoingConnection(callManagerAccount, request);
public Connection onCreateIncomingConnection(
PhoneAccountHandle connectionManagerPhoneAccount,
ConnectionRequest request) {
return null;
}
public void handleCreateConnectionComplete(String callId, ConnectionRequest request,
ParcelableConnection connection, Session.Info sessionInfo) {
...
logIncoming("handleCreateConnectionComplete %s", callId);
ConnectionServiceWrapper.this
.handleCreateConnectionComplete(callId, request, connection);
...
}
跟进handleCreateConnectionComplete,mPendingResponses是hashMap容器,每次在 createConnection 的时候会将对象加入该容器,如果此时connection还未断开的,会移除此connection,调用hanleCreateConnectionSuccess方法。 往上追溯createConnection跟踪到mService.createConnection(mCall, this); CreateConnectionProcessor.java会把自身传入,发现该类也实现了 CreateConnectionResponse ,所以这里的 handleCreateConnectionSuccess
调用的是CreateConnectionProcessor类里面的方法
private void handleCreateConnectionComplete(
String callId,
ConnectionRequest request,
ParcelableConnection connection) {
...
if (connection.getState() == Connection.STATE_DISCONNECTED) {
removeCall(callId, connection.getDisconnectCause());
} else {
// Successful connection
if (mPendingResponses.containsKey(callId)) {
String num = connection.getHandle().getSchemeSpecificPart();
/// M: add for CMCC L + C ecc retry
if (PhoneNumberUtils.isEmergencyNumber(num)) {
mPendingResponses.get(callId).
handleCreateConnectionSuccess(mCallIdMapper, connection);
} else {
mPendingResponses.remove(callId)
.handleCreateConnectionSuccess(mCallIdMapper, connection);
}
}
}
}
public void handleCreateConnectionSuccess(
CallIdMapper idMapper,
ParcelableConnection connection) {
if (mCallResponse == null) {
mService.abort(mCall);
} else {
mCallResponse.handleCreateConnectionSuccess(idMapper, connection);
String number = connection == null || connection.getHandle() == null ?
null : connection.getHandle().getSchemeSpecificPart();
if (!PhoneNumberUtils.isEmergencyNumber(number)) {
mCallResponse = null;
}
}
}
public void onSuccessfulIncomingCall(Call incomingCall) {
Log.d(this, "onSuccessfulIncomingCall");
if (incomingCall.hasProperty(Connection.PROPERTY_EMERGENCY_CALLBACK_MODE)) {
Log.i(this, "Skipping call filtering due to ECBM");
onCallFilteringComplete(incomingCall, new CallFilteringResult(true, false, true, true));
return;
}
//迭代器模式
List
filters.add(new DirectToVoicemailCallFilter(mCallerInfoLookupHelper));
filters.add(new AsyncBlockCheckFilter(mContext, new BlockCheckerAdapter()));
filters.add(new CallScreeningServiceFilter(mContext, this, mPhoneAccountRegistrar,
mDefaultDialerCache, new ParcelableCallUtils.Converter(), mLock));
//IncomingCallFilter创建并执行 performFiltering
new IncomingCallFilter(mContext, this, incomingCall, mLock,
mTimeoutsAdapter, filters).performFiltering();
}
public void performFiltering() {
Log.addEvent(mCall, LogUtils.Events.FILTERING_INITIATED);
for (CallFilter filter : mFilters) {
//遍历调用,依次执行异步查询方法
filter.startFilterLookup(mCall, this);
}
// synchronized to prevent a race on mResult and to enter into Telecom.
mHandler.postDelayed(new Runnable("ICF.pFTO", mTelecomLock) { // performFiltering time-out
@Override
public void loggedRun() {
if (mIsPending) {
//超时处理的方法
Log.i(IncomingCallFilter.this, "Call filtering has timed out.");
Log.addEvent(mCall, LogUtils.Events.FILTERING_TIMED_OUT);
//回CallsManager中的监听事件
mListener.onCallFilteringComplete(mCall, mResult);
mIsPending = false;
}
}
}.prepare(), mTimeoutsAdapter.getCallScreeningTimeoutMillis(mContext.getContentResolver()));
}
private void addCall(Call call) {
call.addListener(this);
mCalls.add(call);
// Specifies the time telecom finished routing the call. This is used by the dialer for
// analytics.
Bundle extras = call.getIntentExtras();
extras.putLong(TelecomManager.EXTRA_CALL_TELECOM_ROUTING_END_TIME_MILLIS,
SystemClock.elapsedRealtime());
updateCanAddCall();
// onCallAdded for calls which immediately take the foreground (like the first call).
for (CallsManagerListener listener : mListeners) {
//通知监听Call添加的观察者,这里的mListeners在CallsManager初始化的时候就已经添加
listener.onCallAdded(call);
}
/// M: single video call mode
if (MtkUtil.isInSingleVideoCallMode(call)) {
for (Call c : mCalls) {
c.refreshConnectionCapabilities();
}
}
}
final void internalAddCall(ParcelableCall parcelableCall) {
//创建Call
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);
//调用phone的监听者的onCallAdded
fireCallAdded(call);
}
private void fireCallAdded(Call call) {
for (Listener listener : mListeners) {
listener.onCallAdded(this, call);
}
}
Private Phone.Listener mPhoneListener = new Phone.Listener()
...
@Override
public void onCallAdded(Phone phone, Call call) {
//调用InCallService对象的onCallAdded方法
InCallService.this.onCallAdded(call);
}
public class InCallServiceImpl extends InCallService
@Override
public void onCallAdded(Call call) {
if ((CallList.getInstance().getVideoUpgradeRequestCall() != null ||
CallList.getInstance().getSendingVideoUpgradeRequestCall() != null ||
/// M: When is cancel upgrade progress,we can't add another call in calllist. @{
CallList.getInstance().getSendingCancelUpgradeRequestCall() != null)
///@}
&& !isEmergency(call)) {
...
} else {
InCallPresenter.getInstance().onCallAdded(call);
}
}
public void onCallAdded(final android.telecom.Call call) {
LatencyReport latencyReport = new LatencyReport(call);
if (shouldAttemptBlocking(call)) {
maybeBlockCall(call, latencyReport);
} else {
if (call.getDetails().hasProperty(CallCompat.Details.PROPERTY_IS_EXTERNAL_CALL)) {
mExternalCallList.onCallAdded(call);
} else {
latencyReport.onCallBlockingDone();
//CallList(Call的维护列表)调用onCallAdded
mCallList.onCallAdded(mContext, call, latencyReport);
}
}
// Since a call has been added we are no longer waiting for Telecom to send us a call.
setBoundAndWaitingForOutgoingCall(false, null);
call.registerCallback(mCallCallback);
}
public void onCallAdded(
final Context context, final android.telecom.Call telecomCall, LatencyReport latencyReport) {
Trace.beginSection("onCallAdded");
...
if (call.getState() == DialerCall.State.INCOMING
|| call.getState() == DialerCall.State.CALL_WAITING) {
//来电调用
onIncoming(call);
} else {
dialerCallListener.onDialerCallUpdate();
}
...
}
private void onIncoming(DialerCall call) {
if (updateCallInMap(call)) {
LogUtil.i("CallList.onIncoming", String.valueOf(call));
}
///M:add for Dual ringing of DSDA. @{
updateIncomingCallList(call);
/// @}
for (Listener listener : mListeners) {
listener.onIncomingCall(call);
}
}