@Override public void onCallTerminated(ImsCall imsCall, ImsReasonInfo reasonInfo) { if (DBG) log("onCallTerminated reasonCode=" + reasonInfo.getCode()); ImsPhoneCall.State oldState = mForegroundCall.getState(); int cause = getDisconnectCauseFromReasonInfo(reasonInfo); ImsPhoneConnection conn = findConnection(imsCall); if (DBG) log("cause = " + cause + " conn = " + conn); if (conn != null && conn.isIncoming() && conn.getConnectTime() == 0) { // Missed if (cause == DisconnectCause.NORMAL) { cause = DisconnectCause.INCOMING_MISSED; } if (DBG) log("Incoming connection of 0 connect time detected - translated cause = " + cause); } if (cause == DisconnectCause.NORMAL && conn != null && conn.getImsCall().isMerged()) { // Call was terminated while it is merged instead of a remote disconnect. cause = DisconnectCause.IMS_MERGED_SUCCESSFULLY; } processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause); }
private int getDisconnectCauseFromReasonInfo(ImsReasonInfo reasonInfo) { int cause = DisconnectCause.ERROR_UNSPECIFIED; // int type = reasonInfo.getReasonType(); int code = reasonInfo.getCode(); switch (code) { case ImsReasonInfo.CODE_SIP_BAD_ADDRESS: case ImsReasonInfo.CODE_SIP_NOT_REACHABLE: return DisconnectCause.NUMBER_UNREACHABLE; case ImsReasonInfo.CODE_SIP_BUSY: return DisconnectCause.BUSY; case ImsReasonInfo.CODE_USER_TERMINATED: return DisconnectCause.LOCAL; case ImsReasonInfo.CODE_LOCAL_CALL_DECLINE: return DisconnectCause.INCOMING_REJECTED; case ImsReasonInfo.CODE_USER_TERMINATED_BY_REMOTE: return DisconnectCause.NORMAL; case ImsReasonInfo.CODE_SIP_REDIRECTED: case ImsReasonInfo.CODE_SIP_BAD_REQUEST: case ImsReasonInfo.CODE_SIP_FORBIDDEN: case ImsReasonInfo.CODE_SIP_NOT_ACCEPTABLE: case ImsReasonInfo.CODE_SIP_USER_REJECTED: case ImsReasonInfo.CODE_SIP_GLOBAL_ERROR: return DisconnectCause.SERVER_ERROR; case ImsReasonInfo.CODE_SIP_SERVICE_UNAVAILABLE: case ImsReasonInfo.CODE_SIP_NOT_FOUND: case ImsReasonInfo.CODE_SIP_SERVER_ERROR: return DisconnectCause.SERVER_UNREACHABLE; case ImsReasonInfo.CODE_LOCAL_NETWORK_ROAMING: case ImsReasonInfo.CODE_LOCAL_NETWORK_IP_CHANGED: case ImsReasonInfo.CODE_LOCAL_IMS_SERVICE_DOWN: case ImsReasonInfo.CODE_LOCAL_SERVICE_UNAVAILABLE: case ImsReasonInfo.CODE_LOCAL_NOT_REGISTERED: case ImsReasonInfo.CODE_LOCAL_NETWORK_NO_LTE_COVERAGE: case ImsReasonInfo.CODE_LOCAL_NETWORK_NO_SERVICE: case ImsReasonInfo.CODE_LOCAL_CALL_VCC_ON_PROGRESSING: return DisconnectCause.OUT_OF_SERVICE; case ImsReasonInfo.CODE_SIP_REQUEST_TIMEOUT: case ImsReasonInfo.CODE_TIMEOUT_1XX_WAITING: case ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER: case ImsReasonInfo.CODE_TIMEOUT_NO_ANSWER_CALL_UPDATE: return DisconnectCause.TIMED_OUT; case ImsReasonInfo.CODE_LOCAL_LOW_BATTERY: case ImsReasonInfo.CODE_LOCAL_POWER_OFF: return DisconnectCause.POWER_OFF; default: } return cause; }
@Override public void onCallHoldFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) { if (DBG) log("onCallHoldFailed reasonCode=" + reasonInfo.getCode()); synchronized (mSyncHold) { ImsPhoneCall.State bgState = mBackgroundCall.getState(); if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_TERMINATED) { // disconnected while processing hold if (mPendingMO != null) { sendEmptyMessage(EVENT_DIAL_PENDINGMO); } } else if (bgState == ImsPhoneCall.State.ACTIVE) { mForegroundCall.switchWith(mBackgroundCall); if (mPendingMO != null) { mPendingMO.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED); sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO); } } } }
/** * onCallStartFailed will be invoked when: case 1) Dialing fails case 2) Ringing call is * disconnected by local or remote user */ @Override public void onCallStartFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) { if (DBG) log("onCallStartFailed reasonCode=" + reasonInfo.getCode()); if (mPendingMO != null) { // To initiate dialing circuit-switched call if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED && mBackgroundCall.getState() == ImsPhoneCall.State.IDLE && mRingingCall.getState() == ImsPhoneCall.State.IDLE) { mForegroundCall.detach(mPendingMO); removeConnection(mPendingMO); mPendingMO.finalize(); mPendingMO = null; mPhone.initiateSilentRedial(); return; } else { int cause = getDisconnectCauseFromReasonInfo(reasonInfo); processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause); } mPendingMO = null; } }
@Override public void onCallTerminated(ImsCall imsCall, ImsReasonInfo reasonInfo) { if (DBG) log("mImsUssdListener onCallTerminated reasonCode=" + reasonInfo.getCode()); if (imsCall == mUssdSession) { mUssdSession = null; if (mPendingUssd != null) { CommandException ex = new CommandException(CommandException.Error.GENERIC_FAILURE); AsyncResult.forMessage(mPendingUssd, null, ex); mPendingUssd.sendToTarget(); mPendingUssd = null; } } imsCall.close(); }
@Override public void onCallStartFailed(ImsCall imsCall, ImsReasonInfo reasonInfo) { if (DBG) log("mImsUssdListener onCallStartFailed reasonCode=" + reasonInfo.getCode()); onCallTerminated(imsCall, reasonInfo); }