use of com.android.ims.ImsCall in project android_frameworks_opt_telephony by LineageOS.
the class ImsPhoneCallTracker method resumeForegroundCall.
private void resumeForegroundCall() throws ImsException {
// resume foreground call after holding background call
// they were switched before holding
ImsCall imsCall = mForegroundCall.getImsCall();
if (imsCall != null) {
imsCall.resume();
mMetrics.writeOnImsCommand(mPhone.getPhoneId(), imsCall.getSession(), ImsCommand.IMS_CMD_RESUME);
}
}
use of com.android.ims.ImsCall in project android_frameworks_opt_telephony by LineageOS.
the class ImsPhoneCallTracker method handleMessage.
// ****** Overridden from Handler
@Override
public void handleMessage(Message msg) {
AsyncResult ar;
if (DBG)
log("handleMessage what=" + msg.what);
switch(msg.what) {
case EVENT_HANGUP_PENDINGMO:
if (mPendingMO != null) {
mPendingMO.onDisconnect();
removeConnection(mPendingMO);
mPendingMO = null;
}
mPendingIntentExtras = null;
updatePhoneState();
mPhone.notifyPreciseCallStateChanged();
break;
case EVENT_RESUME_NOW_FOREGROUND_CALL:
try {
resumeForegroundCall();
} catch (ImsException e) {
if (Phone.DEBUG_PHONE) {
loge("handleMessage EVENT_RESUME_NOW_FOREGROUND_CALL exception=" + e);
}
}
break;
case EVENT_ANSWER_WAITING_CALL:
try {
answerWaitingCall();
} catch (ImsException e) {
if (Phone.DEBUG_PHONE) {
loge("handleMessage EVENT_ANSWER_WAITING_CALL exception=" + e);
}
}
break;
case EVENT_DIAL_PENDINGMO:
dialInternal(mPendingMO, mClirMode, mPendingCallVideoState, mPendingIntentExtras);
mPendingIntentExtras = null;
break;
case EVENT_EXIT_ECBM_BEFORE_PENDINGMO:
if (mPendingMO != null) {
// Send ECBM exit request
try {
getEcbmInterface().exitEmergencyCallbackMode();
mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null);
pendingCallClirMode = mClirMode;
pendingCallInEcm = true;
} catch (ImsException e) {
e.printStackTrace();
mPendingMO.setDisconnectCause(DisconnectCause.ERROR_UNSPECIFIED);
sendEmptyMessageDelayed(EVENT_HANGUP_PENDINGMO, TIMEOUT_HANGUP_PENDINGMO);
}
}
break;
case EVENT_EXIT_ECM_RESPONSE_CDMA:
// no matter the result, we still do the same here
if (pendingCallInEcm) {
dialInternal(mPendingMO, pendingCallClirMode, mPendingCallVideoState, mPendingIntentExtras);
mPendingIntentExtras = null;
pendingCallInEcm = false;
}
mPhone.unsetOnEcbModeExitResponse(this);
break;
case EVENT_VT_DATA_USAGE_UPDATE:
ar = (AsyncResult) msg.obj;
ImsCall call = (ImsCall) ar.userObj;
Long usage = (long) ar.result;
log("VT data usage update. usage = " + usage + ", imsCall = " + call);
if (usage > 0) {
updateVtDataUsage(call, usage);
}
break;
case EVENT_DATA_ENABLED_CHANGED:
ar = (AsyncResult) msg.obj;
if (ar.result instanceof Pair) {
Pair<Boolean, Integer> p = (Pair<Boolean, Integer>) ar.result;
onDataEnabledChanged(p.first, p.second);
}
break;
case EVENT_CHECK_FOR_WIFI_HANDOVER:
if (msg.obj instanceof ImsCall) {
ImsCall imsCall = (ImsCall) msg.obj;
if (imsCall != mForegroundCall.getImsCall()) {
Rlog.i(LOG_TAG, "handoverCheck: no longer FG; check skipped.");
unregisterForConnectivityChanges();
// Handover check and its not the foreground call any more.
return;
}
if (!mHasAttemptedStartOfCallHandover) {
mHasAttemptedStartOfCallHandover = true;
}
if (!imsCall.isWifiCall()) {
// Call did not handover to wifi, notify of handover failure.
ImsPhoneConnection conn = findConnection(imsCall);
if (conn != null) {
Rlog.i(LOG_TAG, "handoverCheck: handover failed.");
conn.onHandoverToWifiFailed();
}
if (imsCall.isVideoCall() && conn.getDisconnectCause() == DisconnectCause.NOT_DISCONNECTED) {
registerForConnectivityChanges();
}
}
}
break;
case EVENT_ON_FEATURE_CAPABILITY_CHANGED:
{
SomeArgs args = (SomeArgs) msg.obj;
try {
ImsFeature.Capabilities capabilities = (ImsFeature.Capabilities) args.arg1;
handleFeatureCapabilityChanged(capabilities);
} finally {
args.recycle();
}
break;
}
case EVENT_SUPP_SERVICE_INDICATION:
{
ar = (AsyncResult) msg.obj;
ImsPhoneMmiCode mmiCode = new ImsPhoneMmiCode(mPhone);
try {
mmiCode.setIsSsInfo(true);
mmiCode.processImsSsData(ar);
} catch (ImsException e) {
Rlog.e(LOG_TAG, "Exception in parsing SS Data: " + e);
}
break;
}
case EVENT_REDIAL_WIFI_E911_CALL:
{
Pair<ImsCall, ImsReasonInfo> callInfo = (Pair<ImsCall, ImsReasonInfo>) ((AsyncResult) msg.obj).userObj;
removeMessages(EVENT_REDIAL_WIFI_E911_TIMEOUT);
mPhone.getDefaultPhone().mCi.unregisterForOn(this);
ImsPhoneConnection oldConnection = findConnection(callInfo.first);
if (oldConnection == null) {
sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
break;
}
mForegroundCall.detach(oldConnection);
removeConnection(oldConnection);
try {
Connection newConnection = mPhone.getDefaultPhone().dial(mLastDialString, mLastDialArgs);
oldConnection.onOriginalConnectionReplaced(newConnection);
final ImsCall imsCall = mForegroundCall.getImsCall();
final ImsCallProfile callProfile = imsCall.getCallProfile();
/* update EXTRA_EMERGENCY_CALL for clients to infer
from this extra that the call is emergency call */
callProfile.setCallExtraBoolean(ImsCallProfile.EXTRA_EMERGENCY_CALL, true);
ImsPhoneConnection conn = findConnection(imsCall);
conn.updateExtras(imsCall);
} catch (CallStateException e) {
sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
}
break;
}
case EVENT_REDIAL_WIFI_E911_TIMEOUT:
{
Pair<ImsCall, ImsReasonInfo> callInfo = (Pair<ImsCall, ImsReasonInfo>) msg.obj;
mPhone.getDefaultPhone().mCi.unregisterForOn(this);
removeMessages(EVENT_REDIAL_WIFI_E911_CALL);
sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
break;
}
case EVENT_REDIAL_WITHOUT_RTT:
{
Pair<ImsCall, ImsReasonInfo> callInfo = (Pair<ImsCall, ImsReasonInfo>) msg.obj;
removeMessages(EVENT_REDIAL_WITHOUT_RTT);
ImsPhoneConnection oldConnection = findConnection(callInfo.first);
if (oldConnection == null) {
sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
break;
}
mForegroundCall.detach(oldConnection);
removeConnection(oldConnection);
try {
mPendingMO = null;
ImsDialArgs newDialArgs = ImsDialArgs.Builder.from(mLastDialArgs).setRttTextStream(null).setRetryCallFailCause(ImsReasonInfo.CODE_RETRY_ON_IMS_WITHOUT_RTT).setRetryCallFailNetworkType(ServiceState.rilRadioTechnologyToNetworkType(oldConnection.getCallRadioTech())).build();
Connection newConnection = mPhone.getDefaultPhone().dial(mLastDialString, newDialArgs);
oldConnection.onOriginalConnectionReplaced(newConnection);
} catch (CallStateException e) {
sendCallStartFailedDisconnect(callInfo.first, callInfo.second);
}
break;
}
}
}
use of com.android.ims.ImsCall in project android_frameworks_opt_telephony by LineageOS.
the class ImsPhoneCallTracker method onDataEnabledChanged.
/**
* Handler of data enabled changed event
* @param enabled True if data is enabled, otherwise disabled.
* @param reason Reason for data enabled/disabled. See {@link DataEnabledChangedReason}.
*/
private void onDataEnabledChanged(boolean enabled, @DataEnabledChangedReason int reason) {
log("onDataEnabledChanged: enabled=" + enabled + ", reason=" + reason);
mIsDataEnabled = enabled;
if (!mIsViLteDataMetered) {
log("Ignore data " + ((enabled) ? "enabled" : "disabled") + " - carrier policy " + "indicates that data is not metered for ViLTE calls.");
return;
}
// if this is an LTE call.
for (ImsPhoneConnection conn : mConnections) {
ImsCall imsCall = conn.getImsCall();
boolean isLocalVideoCapable = enabled || (imsCall != null && imsCall.isWifiCall());
conn.setLocalVideoCapable(isLocalVideoCapable);
}
int reasonCode;
if (reason == DataEnabledSettings.REASON_POLICY_DATA_ENABLED) {
reasonCode = ImsReasonInfo.CODE_DATA_LIMIT_REACHED;
} else if (reason == DataEnabledSettings.REASON_USER_DATA_ENABLED) {
reasonCode = ImsReasonInfo.CODE_DATA_DISABLED;
} else {
// Unexpected code, default to data disabled.
reasonCode = ImsReasonInfo.CODE_DATA_DISABLED;
}
// Potentially send connection events so the InCall UI knows that video calls are being
// downgraded due to data being enabled/disabled.
maybeNotifyDataDisabled(enabled, reasonCode);
// Handle video state changes required as a result of data being enabled/disabled.
handleDataEnabledChange(enabled, reasonCode);
// the carrier config has loaded and will deregister IMS.
if (!mShouldUpdateImsConfigOnDisconnect && reason != DataEnabledSettings.REASON_REGISTERED && mCarrierConfigLoaded) {
// asynchronously notified that the availability of VT over LTE has changed.
if (mImsManager != null) {
mImsManager.updateImsServiceConfig(true);
}
}
}
use of com.android.ims.ImsCall in project android_frameworks_opt_telephony by LineageOS.
the class ImsPhoneCallTracker method unholdHeldCall.
/**
* Unhold the currently held call.
*/
public void unholdHeldCall() throws CallStateException {
ImsCall imsCall = mBackgroundCall.getImsCall();
if (mHoldSwitchingState == HoldSwapState.PENDING_SINGLE_CALL_UNHOLD || mHoldSwitchingState == HoldSwapState.SWAPPING_ACTIVE_AND_HELD) {
logi("Ignoring unhold request while already unholding or swapping");
return;
}
if (imsCall != null) {
mCallExpectedToResume = imsCall;
HoldSwapState oldHoldState = mHoldSwitchingState;
mHoldSwitchingState = HoldSwapState.PENDING_SINGLE_CALL_UNHOLD;
mForegroundCall.switchWith(mBackgroundCall);
logHoldSwapState("unholdCurrentCall");
try {
imsCall.resume();
mMetrics.writeOnImsCommand(mPhone.getPhoneId(), imsCall.getSession(), ImsCommand.IMS_CMD_RESUME);
} catch (ImsException e) {
mForegroundCall.switchWith(mBackgroundCall);
mHoldSwitchingState = oldHoldState;
logHoldSwapState("unholdCurrentCall - fail");
throw new CallStateException(e.getMessage());
}
}
}
use of com.android.ims.ImsCall in project android_frameworks_opt_telephony by LineageOS.
the class ImsPhoneCallTracker method acceptCall.
/**
* Accepts a call with the specified video state. The video state is the video state that the
* user has agreed upon in the InCall UI.
*
* @param videoState The video State
* @throws CallStateException
*/
public void acceptCall(int videoState) throws CallStateException {
if (DBG)
log("acceptCall");
mOperationLocalLog.log("accepted incoming call");
if (mForegroundCall.getState().isAlive() && mBackgroundCall.getState().isAlive()) {
throw new CallStateException("cannot accept call");
}
if ((mRingingCall.getState() == ImsPhoneCall.State.WAITING) && mForegroundCall.getState().isAlive()) {
setMute(false);
boolean answeringWillDisconnect = false;
ImsCall activeCall = mForegroundCall.getImsCall();
ImsCall ringingCall = mRingingCall.getImsCall();
if (mForegroundCall.hasConnections() && mRingingCall.hasConnections()) {
answeringWillDisconnect = shouldDisconnectActiveCallOnAnswer(activeCall, ringingCall);
}
// Cache video state for pending MT call.
mPendingCallVideoState = videoState;
if (answeringWillDisconnect) {
// We need to disconnect the foreground call before answering the background call.
mForegroundCall.hangup();
mPhone.getVoiceCallSessionStats().onImsAcceptCall(mRingingCall.getConnections());
try {
ringingCall.accept(ImsCallProfile.getCallTypeFromVideoState(videoState));
} catch (ImsException e) {
throw new CallStateException("cannot accept call");
}
} else {
holdActiveCallForWaitingCall();
}
} else if (mRingingCall.getState().isRinging()) {
if (DBG)
log("acceptCall: incoming...");
// Always unmute when answering a new call
setMute(false);
try {
ImsCall imsCall = mRingingCall.getImsCall();
if (imsCall != null) {
mPhone.getVoiceCallSessionStats().onImsAcceptCall(mRingingCall.getConnections());
imsCall.accept(ImsCallProfile.getCallTypeFromVideoState(videoState));
mMetrics.writeOnImsCommand(mPhone.getPhoneId(), imsCall.getSession(), ImsCommand.IMS_CMD_ACCEPT);
} else {
throw new CallStateException("no valid ims call");
}
} catch (ImsException e) {
throw new CallStateException("cannot accept call");
}
} else {
throw new CallStateException("phone not ringing");
}
}
Aggregations