handlePollCalls
GsmCdmaCallTracker 第二次收到Message消息的处理handleMessage(),其中msg的obj是RIL返回的数据(包含Dc列表)
GsmCdmaCallTracker —>>public void handleMessage(Message msg)
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;
//在RIL.processSolicited中从底层返回的数据构造一个AsyncResult添加进msg.obj
handlePollCalls((AsyncResult)msg.obj);//msg的obj什么时候进行的初始化,创建msg
的时候没有初始化obj,只有what
}
break;
protected synchronized void handlePollCalls(AsyncResult ar) {
List polledCalls;
if (VDBG) log("handlePollCalls");
if (ar.exception == null) {
polledCalls = (List)ar.result;//RIL进行查询获取的ar,mCi.getCurrentCalls(mLastRelevantPoll);
} else if (isCommandExceptionRadioNotAvailable(ar.exception)) {
// just a dummy empty ArrayList to cause the loop
// to hang up all the calls
polledCalls = new ArrayList();
} else {
// Radio probably wasn't ready--try again in a bit
// But don't keep polling if the channel is closed
pollCallsAfterDelay();
return;
}
Connection newRinging = null; //or waiting
ArrayList<Connection> newUnknownConnectionsGsm = new ArrayList<Connection>();
Connection newUnknownConnectionCdma = null;
boolean hasNonHangupStateChanged = false; // Any change besides
// a dropped connection
boolean hasAnyCallDisconnected = false;
boolean needsPollDelay = false;
boolean unknownConnectionAppeared = false;
int handoverConnectionsSize = mHandoverConnections.size();
//CDMA
boolean noConnectionExists = true;
for (int i = 0, curDC = 0, dcSize = polledCalls.size()//dcSize应该为1
; i < mConnections.length; i++) {
GsmCdmaConnection conn = mConnections[i];// mConnections在哪里进行初始化的?在启动初始化时进行,但是没有进行赋值
// mConnections = new GsmCdmaConnection[MAX_CONNECTIONS_GSM];
//因此conn=null
DriverCall dc = null;
// polledCall list is sparse
if (curDC < dcSize) {
dc = (DriverCall) polledCalls.get(curDC);//取出dc,只有一个
if (dc.index == i+1) {
curDC++;
} else {
dc = null;
}
}
//CDMA
if (conn != null || dc != null) {
noConnectionExists = false;
}
if (DBG_POLL) log("poll: conn[i=" + i + "]=" +
conn+", dc=" + dc);
if (conn == null && dc != null) {//新电话;第一次拨打电话/第一次接收来电
// Connection appeared in CLCC response that we don't know about
if (mPendingMO != null && mPendingMO.compareTo(dc)) {//这个应该是拨打电话的流程
if (DBG_POLL) log("poll: pendingMO=" + mPendingMO);
// It's our pending mobile originating call
mConnections[i] = mPendingMO;//这才进行了赋值,mPendingMO在什么地方进行的初始化,
//在dial()方法中进行的实例化创建
//mPendingMO = new GsmCdmaConnection(mPhone, checkForTestEmergencyNumber(dialString),this, mForegroundCall, isEmergencyCall);
mPendingMO.mIndex = i;
mPendingMO.update(dc);
mPendingMO = null;
// Someone has already asked to hangup this call,没挂断跳过
if (mHangupPendingMO) {
mHangupPendingMO = false;
// Re-start Ecm timer when an uncompleted emergency call ends
if (!isPhoneTypeGsm() && mIsEcmTimerCanceled) {
handleEcmTimer(GsmCdmaPhone.RESTART_ECM_TIMER);
}
try {
if (Phone.DEBUG_PHONE) log(//这个字段也不知道什么时候进行的修改,默认值是true
"poll: hangupPendingMO, hangup conn " + i);
hangup(mConnections[i]);
} catch (CallStateException ex) {
Rlog.e(LOG_TAG, "unexpected error on hangup");
}
// Do not continue processing this poll
// Wait for hangup and repoll
return;
}
} else {
if (Phone.DEBUG_PHONE) {
log("pendingMo=" + mPendingMO + ", dc=" + dc);
}
mConnections[i] = new GsmCdmaConnection(mPhone, dc, this, i);
Connection hoConnection = getHoConnection(dc);
if (hoConnection != null) {
// Single Radio Voice Call Continuity (SRVCC) completed
mConnections[i].migrateFrom(hoConnection);
// Updating connect time for silent redial cases (ex: Calls are transferred
// from DIALING/ALERTING/INCOMING/WAITING to ACTIVE)
if (hoConnection.mPreHandoverState != GsmCdmaCall.State.ACTIVE &&
hoConnection.mPreHandoverState != GsmCdmaCall.State.HOLDING &&
dc.state == DriverCall.State.ACTIVE) {
mConnections[i].onConnectedInOrOut();
}
mHandoverConnections.remove(hoConnection);
if (isPhoneTypeGsm()) {
for (Iterator<Connection> it = mHandoverConnections.iterator();
it.hasNext(); ) {
Connection c = it.next();
Rlog.i(LOG_TAG, "HO Conn state is " + c.mPreHandoverState);
if (c.mPreHandoverState == mConnections[i].getState()) {
Rlog.i(LOG_TAG, "Removing HO conn "
+ hoConnection + c.mPreHandoverState);
it.remove();
}
}
}
mPhone.notifyHandoverStateChanged(mConnections[i]);
} else {
// find if the MT call is a new ring or unknown connection
newRinging = checkMtFindNewRinging(dc,i);
if (newRinging == null) {
unknownConnectionAppeared = true;
if (isPhoneTypeGsm()) {
newUnknownConnectionsGsm.add(mConnections[i]);
} else {
newUnknownConnectionCdma = mConnections[i];
}
}
}
}
hasNonHangupStateChanged = true;
}//还有其他很多情况
//else if (conn != null && dc == null)
//lse if (conn != null && dc != null && !conn.compareTo(dc) && isPhoneTypeGsm()) {
//else if (conn != null && dc != null) {
//默认false
if (REPEAT_POLLING) {
if (dc != null) {
// FIXME with RIL, we should not need this anymore
if ((dc.state == DriverCall.State.DIALING
/*&& cm.getOption(cm.OPTION_POLL_DIALING)*/)
|| (dc.state == DriverCall.State.ALERTING
/*&& cm.getOption(cm.OPTION_POLL_ALERTING)*/)
|| (dc.state == DriverCall.State.INCOMING
/*&& cm.getOption(cm.OPTION_POLL_INCOMING)*/)
|| (dc.state == DriverCall.State.WAITING
/*&& cm.getOption(cm.OPTION_POLL_WAITING)*/)) {
// Sometimes there's no unsolicited notification
// for state transitions
needsPollDelay = true;
}
}
}
}
// Safety check so that obj is not stuck with mIsInEmergencyCall set to true (and data
// disabled). This should never happen though.
if (!isPhoneTypeGsm() && noConnectionExists) {
checkAndEnableDataCallAfterEmergencyCallDropped();
}
// This is the first poll after an ATD.
// We expect the pending call to appear in the list
// If it does not, we land here,在上面已经置为null了
if (mPendingMO != null) {
Rlog.d(LOG_TAG, "Pending MO dropped before poll fg state:"
+ mForegroundCall.getState());
mDroppedDuringPoll.add(mPendingMO);
mPendingMO = null;
mHangupPendingMO = false;
if (!isPhoneTypeGsm()) {
if( mPendingCallInEcm) {
mPendingCallInEcm = false;
}
checkAndEnableDataCallAfterEmergencyCallDropped();
}
}
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
for (int i = mDroppedDuringPoll.size() - 1; i >= 0 ; i--) {
GsmCdmaConnection conn = mDroppedDuringPoll.get(i);
//CDMA
boolean wasDisconnected = false;
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;
} else if (conn.mCause == DisconnectCause.LOCAL
|| conn.mCause == DisconnectCause.INVALID_NUMBER) {
mDroppedDuringPoll.remove(i);
hasAnyCallDisconnected |= conn.onDisconnect(conn.mCause);
wasDisconnected = true;
}
if (!isPhoneTypeGsm() && wasDisconnected && unknownConnectionAppeared
&& conn == newUnknownConnectionCdma) {
unknownConnectionAppeared = false;
newUnknownConnectionCdma = null;
}
}
/* Disconnect any pending Handover connections */
for (Iterator<Connection> it = mHandoverConnections.iterator();
it.hasNext();) {
Connection hoConnection = it.next();
log("handlePollCalls - disconnect hoConn= " + hoConnection +
" hoConn.State= " + hoConnection.getState());
if (hoConnection.getState().isRinging()) {
hoConnection.onDisconnect(DisconnectCause.INCOMING_MISSED);
} else {
hoConnection.onDisconnect(DisconnectCause.NOT_VALID);
}
it.remove();
}
// Any non-local disconnects: determine cause
if (mDroppedDuringPoll.size() > 0) {
mCi.getLastCallFailCause(
obtainNoPollCompleteMessage(EVENT_GET_LAST_CALL_FAIL_CAUSE));
}
if (needsPollDelay) {
pollCallsAfterDelay();
}
// Cases when we can no longer keep disconnected Connection's
// with their previous calls
// 1) the phone has started to ring
// 2) A Call/Connection object has changed state...
// we may have switched or held or answered (but not hung up)
if (newRinging != null || hasNonHangupStateChanged || hasAnyCallDisconnected) {
internalClearDisconnected();
}
//默认false
if (VDBG) log("handlePollCalls calling updatePhoneState()");
//重点方法
updatePhoneState();//同步更新Phone.State手机状态
if (unknownConnectionAppeared) {
if (isPhoneTypeGsm()) {
for (Connection c : newUnknownConnectionsGsm) {
log("Notify unknown for " + c);
mPhone.notifyUnknownConnection(c);
}
} else {
mPhone.notifyUnknownConnection(newUnknownConnectionCdma);
}
}
if (hasNonHangupStateChanged || newRinging != null || hasAnyCallDisconnected) {
mPhone.notifyPreciseCallStateChanged();
}
// If all handover connections are mapped during this poll process clean it up
if (handoverConnectionsSize > 0 && mHandoverConnections.size() == 0) {
Phone imsPhone = mPhone.getImsPhone();
if (imsPhone != null) {
imsPhone.callEndCleanupHandOverCallIfAny();
}
}
//dumpState();
}