Loading src/java/com/android/internal/telephony/Connection.java +8 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ public abstract class Connection { public void onDisconnect(int cause); public void onRttInitiated(); public void onRttTerminated(); public void onOriginalConnectionReplaced(Connection newConnection); } /** Loading Loading @@ -152,6 +153,8 @@ public abstract class Connection { public void onRttInitiated() {} @Override public void onRttTerminated() {} @Override public void onOriginalConnectionReplaced(Connection newConnection) {} } public static final int AUDIO_QUALITY_STANDARD = 1; Loading Loading @@ -1022,6 +1025,11 @@ public abstract class Connection { } } public void onOriginalConnectionReplaced(Connection newConnection) { for (Listener l : mListeners) { l.onOriginalConnectionReplaced(newConnection); } } /** * Notifies the connection that there was a failure while handing over to WIFI. */ Loading src/java/com/android/internal/telephony/imsphone/ImsPhone.java +5 −0 Original line number Diff line number Diff line Loading @@ -649,6 +649,11 @@ public class ImsPhone extends ImsPhoneBase { mDefaultPhone.notifyForVideoCapabilityChanged(isVideoCapable); } @Override public void setRadioPower(boolean on) { mDefaultPhone.setRadioPower(on); } @Override public Connection dial(String dialString, DialArgs dialArgs) throws CallStateException { return dialInternal(dialString, dialArgs, null); Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +75 −21 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.Connection; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.PhoneInternalInterface; import com.android.internal.telephony.SubscriptionController; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.dataconnection.DataEnabledSettings; Loading Loading @@ -256,11 +257,15 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private static final int EVENT_CHECK_FOR_WIFI_HANDOVER = 25; private static final int EVENT_ON_FEATURE_CAPABILITY_CHANGED = 26; private static final int EVENT_SUPP_SERVICE_INDICATION = 27; private static final int EVENT_REDIAL_WIFI_E911_CALL = 28; private static final int EVENT_REDIAL_WIFI_E911_TIMEOUT = 29; private static final int TIMEOUT_HANGUP_PENDINGMO = 500; private static final int HANDOVER_TO_WIFI_TIMEOUT_MS = 60000; // ms private static final int TIMEOUT_REDIAL_WIFI_E911_MS = 10000; //***** Instance Variables private ArrayList<ImsPhoneConnection> mConnections = new ArrayList<ImsPhoneConnection>(); private RegistrantList mVoiceCallEndedRegistrants = new RegistrantList(); Loading Loading @@ -315,7 +320,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private boolean mIgnoreDataEnabledChangedForVideoCalls = false; private boolean mIsViLteDataMetered = false; private boolean mAlwaysPlayRemoteHoldTone = false; private boolean mAutoRetryFailedWifiEmergencyCall = false; private String mLastDialString = null; private PhoneInternalInterface.DialArgs mLastDialArgs = null; /** * Listeners to changes in the phone state. Intended for use by other interested IMS components * without the need to register a full blown {@link android.telephony.PhoneStateListener}. Loading Loading @@ -924,6 +932,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } } mLastDialString = dialString; mLastDialArgs = dialArgs; mPendingMO = new ImsPhoneConnection(mPhone, checkForTestEmergencyNumber(dialString), this, mForegroundCall, isEmergencyNumber); Loading Loading @@ -1047,6 +1057,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL); mAlwaysPlayRemoteHoldTone = carrierConfig.getBoolean( CarrierConfigManager.KEY_ALWAYS_PLAY_REMOTE_HOLD_TONE_BOOL); mAutoRetryFailedWifiEmergencyCall = carrierConfig.getBoolean( CarrierConfigManager.KEY_AUTO_RETRY_FAILED_WIFI_EMERGENCY_CALL); String[] mappings = carrierConfig .getStringArray(CarrierConfigManager.KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY); Loading Loading @@ -2151,7 +2163,17 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { if (mPendingMO != null) { // To initiate dialing circuit-switched call if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED if (reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL && mAutoRetryFailedWifiEmergencyCall) { Pair<ImsCall, ImsReasonInfo> callInfo = new Pair<>(imsCall, reasonInfo); mPhone.getDefaultPhone().getServiceStateTracker().registerForNetworkAttached( ImsPhoneCallTracker.this, EVENT_REDIAL_WIFI_E911_CALL, callInfo); sendMessageDelayed(obtainMessage(EVENT_REDIAL_WIFI_E911_TIMEOUT, callInfo), TIMEOUT_REDIAL_WIFI_E911_MS); final ConnectivityManager mgr = (ConnectivityManager) mPhone.getContext() .getSystemService(Context.CONNECTIVITY_SERVICE); mgr.setAirplaneMode(false); } else if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED && mBackgroundCall.getState() == ImsPhoneCall.State.IDLE && mRingingCall.getState() == ImsPhoneCall.State.IDLE) { mForegroundCall.detach(mPendingMO); Loading @@ -2161,26 +2183,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.initiateSilentRedial(); return; } else { mPendingMO = null; ImsPhoneConnection conn = findConnection(imsCall); Call.State callState; if (conn != null) { callState = conn.getState(); } else { // Need to fall back in case connection is null; it shouldn't be, but a sane // fallback is to assume we're dialing. This state is only used to // determine which disconnect string to show in the case of a low battery // disconnect. callState = Call.State.DIALING; } int cause = getDisconnectCauseFromReasonInfo(reasonInfo, callState); if(conn != null) { conn.setPreciseDisconnectCause( getPreciseDisconnectCauseFromReasonInfo(reasonInfo)); } processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause); sendCallStartFailedDisconnect(imsCall, reasonInfo); } mMetrics.writeOnImsCallStartFailed(mPhone.getPhoneId(), imsCall.getCallSession(), reasonInfo); Loading Loading @@ -2874,6 +2877,29 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } }; public void sendCallStartFailedDisconnect(ImsCall imsCall, ImsReasonInfo reasonInfo) { mPendingMO = null; ImsPhoneConnection conn = findConnection(imsCall); Call.State callState; if (conn != null) { callState = conn.getState(); } else { // Need to fall back in case connection is null; it shouldn't be, but a sane // fallback is to assume we're dialing. This state is only used to // determine which disconnect string to show in the case of a low battery // disconnect. callState = Call.State.DIALING; } int cause = getDisconnectCauseFromReasonInfo(reasonInfo, callState); if (conn != null) { conn.setPreciseDisconnectCause( getPreciseDisconnectCauseFromReasonInfo(reasonInfo)); } processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause); } public ImsUtInterface getUtInterface() throws ImsException { if (mImsManager == null) { throw getImsManagerIsNullException(); Loading Loading @@ -3033,6 +3059,34 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } 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().getServiceStateTracker() .unregisterForNetworkAttached(this); Connection oldConnection = mPendingMO; mForegroundCall.detach(mPendingMO); removeConnection(mPendingMO); mPendingMO.finalize(); mPendingMO = null; try { Connection newConnection = mPhone.getDefaultPhone().dial(mLastDialString, mLastDialArgs); oldConnection.onOriginalConnectionReplaced(newConnection); } 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().getServiceStateTracker() .unregisterForNetworkAttached(this); removeMessages(EVENT_REDIAL_WIFI_E911_CALL); sendCallStartFailedDisconnect(callInfo.first, callInfo.second); break; } } } Loading Loading
src/java/com/android/internal/telephony/Connection.java +8 −0 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ public abstract class Connection { public void onDisconnect(int cause); public void onRttInitiated(); public void onRttTerminated(); public void onOriginalConnectionReplaced(Connection newConnection); } /** Loading Loading @@ -152,6 +153,8 @@ public abstract class Connection { public void onRttInitiated() {} @Override public void onRttTerminated() {} @Override public void onOriginalConnectionReplaced(Connection newConnection) {} } public static final int AUDIO_QUALITY_STANDARD = 1; Loading Loading @@ -1022,6 +1025,11 @@ public abstract class Connection { } } public void onOriginalConnectionReplaced(Connection newConnection) { for (Listener l : mListeners) { l.onOriginalConnectionReplaced(newConnection); } } /** * Notifies the connection that there was a failure while handing over to WIFI. */ Loading
src/java/com/android/internal/telephony/imsphone/ImsPhone.java +5 −0 Original line number Diff line number Diff line Loading @@ -649,6 +649,11 @@ public class ImsPhone extends ImsPhoneBase { mDefaultPhone.notifyForVideoCapabilityChanged(isVideoCapable); } @Override public void setRadioPower(boolean on) { mDefaultPhone.setRadioPower(on); } @Override public Connection dial(String dialString, DialArgs dialArgs) throws CallStateException { return dialInternal(dialString, dialArgs, null); Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +75 −21 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ import com.android.internal.telephony.CommandsInterface; import com.android.internal.telephony.Connection; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.PhoneInternalInterface; import com.android.internal.telephony.SubscriptionController; import com.android.internal.telephony.TelephonyProperties; import com.android.internal.telephony.dataconnection.DataEnabledSettings; Loading Loading @@ -256,11 +257,15 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private static final int EVENT_CHECK_FOR_WIFI_HANDOVER = 25; private static final int EVENT_ON_FEATURE_CAPABILITY_CHANGED = 26; private static final int EVENT_SUPP_SERVICE_INDICATION = 27; private static final int EVENT_REDIAL_WIFI_E911_CALL = 28; private static final int EVENT_REDIAL_WIFI_E911_TIMEOUT = 29; private static final int TIMEOUT_HANGUP_PENDINGMO = 500; private static final int HANDOVER_TO_WIFI_TIMEOUT_MS = 60000; // ms private static final int TIMEOUT_REDIAL_WIFI_E911_MS = 10000; //***** Instance Variables private ArrayList<ImsPhoneConnection> mConnections = new ArrayList<ImsPhoneConnection>(); private RegistrantList mVoiceCallEndedRegistrants = new RegistrantList(); Loading Loading @@ -315,7 +320,10 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { private boolean mIgnoreDataEnabledChangedForVideoCalls = false; private boolean mIsViLteDataMetered = false; private boolean mAlwaysPlayRemoteHoldTone = false; private boolean mAutoRetryFailedWifiEmergencyCall = false; private String mLastDialString = null; private PhoneInternalInterface.DialArgs mLastDialArgs = null; /** * Listeners to changes in the phone state. Intended for use by other interested IMS components * without the need to register a full blown {@link android.telephony.PhoneStateListener}. Loading Loading @@ -924,6 +932,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } } mLastDialString = dialString; mLastDialArgs = dialArgs; mPendingMO = new ImsPhoneConnection(mPhone, checkForTestEmergencyNumber(dialString), this, mForegroundCall, isEmergencyNumber); Loading Loading @@ -1047,6 +1057,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { CarrierConfigManager.KEY_SUPPORT_PAUSE_IMS_VIDEO_CALLS_BOOL); mAlwaysPlayRemoteHoldTone = carrierConfig.getBoolean( CarrierConfigManager.KEY_ALWAYS_PLAY_REMOTE_HOLD_TONE_BOOL); mAutoRetryFailedWifiEmergencyCall = carrierConfig.getBoolean( CarrierConfigManager.KEY_AUTO_RETRY_FAILED_WIFI_EMERGENCY_CALL); String[] mappings = carrierConfig .getStringArray(CarrierConfigManager.KEY_IMS_REASONINFO_MAPPING_STRING_ARRAY); Loading Loading @@ -2151,7 +2163,17 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { if (mPendingMO != null) { // To initiate dialing circuit-switched call if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED if (reasonInfo.getCode() == ImsReasonInfo.CODE_SIP_ALTERNATE_EMERGENCY_CALL && mAutoRetryFailedWifiEmergencyCall) { Pair<ImsCall, ImsReasonInfo> callInfo = new Pair<>(imsCall, reasonInfo); mPhone.getDefaultPhone().getServiceStateTracker().registerForNetworkAttached( ImsPhoneCallTracker.this, EVENT_REDIAL_WIFI_E911_CALL, callInfo); sendMessageDelayed(obtainMessage(EVENT_REDIAL_WIFI_E911_TIMEOUT, callInfo), TIMEOUT_REDIAL_WIFI_E911_MS); final ConnectivityManager mgr = (ConnectivityManager) mPhone.getContext() .getSystemService(Context.CONNECTIVITY_SERVICE); mgr.setAirplaneMode(false); } else if (reasonInfo.getCode() == ImsReasonInfo.CODE_LOCAL_CALL_CS_RETRY_REQUIRED && mBackgroundCall.getState() == ImsPhoneCall.State.IDLE && mRingingCall.getState() == ImsPhoneCall.State.IDLE) { mForegroundCall.detach(mPendingMO); Loading @@ -2161,26 +2183,7 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { mPhone.initiateSilentRedial(); return; } else { mPendingMO = null; ImsPhoneConnection conn = findConnection(imsCall); Call.State callState; if (conn != null) { callState = conn.getState(); } else { // Need to fall back in case connection is null; it shouldn't be, but a sane // fallback is to assume we're dialing. This state is only used to // determine which disconnect string to show in the case of a low battery // disconnect. callState = Call.State.DIALING; } int cause = getDisconnectCauseFromReasonInfo(reasonInfo, callState); if(conn != null) { conn.setPreciseDisconnectCause( getPreciseDisconnectCauseFromReasonInfo(reasonInfo)); } processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause); sendCallStartFailedDisconnect(imsCall, reasonInfo); } mMetrics.writeOnImsCallStartFailed(mPhone.getPhoneId(), imsCall.getCallSession(), reasonInfo); Loading Loading @@ -2874,6 +2877,29 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } }; public void sendCallStartFailedDisconnect(ImsCall imsCall, ImsReasonInfo reasonInfo) { mPendingMO = null; ImsPhoneConnection conn = findConnection(imsCall); Call.State callState; if (conn != null) { callState = conn.getState(); } else { // Need to fall back in case connection is null; it shouldn't be, but a sane // fallback is to assume we're dialing. This state is only used to // determine which disconnect string to show in the case of a low battery // disconnect. callState = Call.State.DIALING; } int cause = getDisconnectCauseFromReasonInfo(reasonInfo, callState); if (conn != null) { conn.setPreciseDisconnectCause( getPreciseDisconnectCauseFromReasonInfo(reasonInfo)); } processCallStateChange(imsCall, ImsPhoneCall.State.DISCONNECTED, cause); } public ImsUtInterface getUtInterface() throws ImsException { if (mImsManager == null) { throw getImsManagerIsNullException(); Loading Loading @@ -3033,6 +3059,34 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { } 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().getServiceStateTracker() .unregisterForNetworkAttached(this); Connection oldConnection = mPendingMO; mForegroundCall.detach(mPendingMO); removeConnection(mPendingMO); mPendingMO.finalize(); mPendingMO = null; try { Connection newConnection = mPhone.getDefaultPhone().dial(mLastDialString, mLastDialArgs); oldConnection.onOriginalConnectionReplaced(newConnection); } 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().getServiceStateTracker() .unregisterForNetworkAttached(this); removeMessages(EVENT_REDIAL_WIFI_E911_CALL); sendCallStartFailedDisconnect(callInfo.first, callInfo.second); break; } } } Loading