Loading src/java/com/android/internal/telephony/CallFailCause.java +9 −0 Original line number Diff line number Diff line Loading @@ -440,6 +440,15 @@ public interface CallFailCause { */ int WIFI_LOST = 2507; /** * Indicates a call was disconnected because retry over volte is needed. */ int EMC_REDIAL_ON_IMS = 3001; /** * Indicates a call was disconnected because retry over vowifi is needed. */ int EMC_REDIAL_ON_VOWIFI = 3002; /* OEM specific error codes. To be used by OEMs when they don't want to reveal error code which would be replaced by ERROR_UNSPECIFIED */ Loading src/java/com/android/internal/telephony/GsmCdmaCallTracker.java +24 −0 Original line number Diff line number Diff line Loading @@ -1552,6 +1552,22 @@ public class GsmCdmaCallTracker extends CallTracker { TelephonyManager.getDefault().getNetworkType()); } if (isEmcRetryCause(causeCode)) { String dialString = ""; for(Connection conn : mForegroundCall.mConnections) { GsmCdmaConnection gsmCdmaConnection = (GsmCdmaConnection)conn; dialString = gsmCdmaConnection.getOrigDialString(); gsmCdmaConnection.getCall().detach(gsmCdmaConnection); mDroppedDuringPoll.remove(gsmCdmaConnection); } mPhone.notifyVolteSilentRedial(dialString, causeCode); updatePhoneState(); if (mDroppedDuringPoll.isEmpty()) { log("LAST_CALL_FAIL_CAUSE - no Dropped normal Call"); return; } } for (int i = 0, s = mDroppedDuringPoll.size(); i < s ; i++) { GsmCdmaConnection conn = mDroppedDuringPoll.get(i); Loading Loading @@ -1758,6 +1774,14 @@ public class GsmCdmaCallTracker extends CallTracker { return mPhone; } private boolean isEmcRetryCause(int causeCode) { if (causeCode == CallFailCause.EMC_REDIAL_ON_IMS || causeCode == CallFailCause.EMC_REDIAL_ON_VOWIFI) { return true; } return false; } @UnsupportedAppUsage @Override protected void log(String msg) { Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +22 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import com.android.internal.telephony.dataconnection.TransportManager; import com.android.internal.telephony.emergency.EmergencyNumberTracker; import com.android.internal.telephony.gsm.GsmMmiCode; import com.android.internal.telephony.gsm.SuppServiceNotification; import com.android.internal.telephony.imsphone.ImsPhone; import com.android.internal.telephony.test.SimulatedRadioControl; import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; import com.android.internal.telephony.uicc.IccCardStatus; Loading Loading @@ -195,6 +196,9 @@ public class GsmCdmaPhone extends Phone { // mEcmTimerResetRegistrants are informed after Ecm timer is canceled or re-started private final RegistrantList mEcmTimerResetRegistrants = new RegistrantList(); private final RegistrantList mVolteSilentRedialRegistrants = new RegistrantList(); private DialArgs mDialArgs = null; private String mImei; private String mImeiSv; private String mVmNumber; Loading Loading @@ -1264,6 +1268,7 @@ public class GsmCdmaPhone extends Phone { boolean isEmergency = PhoneNumberUtils.isEmergencyNumber(getSubId(), dialString); Phone imsPhone = mImsPhone; mDialArgs = dialArgs; CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); Loading Loading @@ -4088,6 +4093,23 @@ public class GsmCdmaPhone extends Phone { mEcmTimerResetRegistrants.remove(h); } @Override public void registerForVolteSilentRedial(Handler h, int what, Object obj) { mVolteSilentRedialRegistrants.addUnique(h, what, obj); } @Override public void unregisterForVolteSilentRedial(Handler h) { mVolteSilentRedialRegistrants.remove(h); } public void notifyVolteSilentRedial(String dialString, int causeCode) { logd("notifyVolteSilentRedial: dialString=" + dialString + " causeCode=" + causeCode); AsyncResult ar = new AsyncResult(null, new SilentRedialParam(dialString, causeCode, mDialArgs), null); mVolteSilentRedialRegistrants.notifyRegistrants(ar); } /** * Sets the SIM voice message waiting indicator records. * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported Loading src/java/com/android/internal/telephony/Phone.java +18 −0 Original line number Diff line number Diff line Loading @@ -254,6 +254,18 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { public String operatorAlphaShort; } public static class SilentRedialParam { public String dialString; public int causeCode; public DialArgs dialArgs; public SilentRedialParam(String dialString, int causeCode, DialArgs dialArgs) { this.dialString = dialString; this.causeCode = causeCode; this.dialArgs = dialArgs; } } /* Instance Variables */ @UnsupportedAppUsage public CommandsInterface mCi; Loading Loading @@ -744,6 +756,12 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { public void unregisterForSilentRedial(Handler h) { } public void registerForVolteSilentRedial(Handler h, int what, Object obj) { } public void unregisterForVolteSilentRedial(Handler h) { } private void handleSrvccStateChanged(int[] ret) { Rlog.d(LOG_TAG, "handleSrvccStateChanged"); Loading src/java/com/android/internal/telephony/imsphone/ImsPhone.java +67 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ import com.android.ims.ImsManager; import com.android.ims.ImsUtInterface; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.Call; import com.android.internal.telephony.CallFailCause; import com.android.internal.telephony.CallForwardInfo; import com.android.internal.telephony.CallStateException; import com.android.internal.telephony.CallTracker; Loading Loading @@ -136,6 +137,7 @@ public class ImsPhone extends ImsPhoneBase { @VisibleForTesting public static final int EVENT_SERVICE_STATE_CHANGED = EVENT_LAST + 8; private static final int EVENT_VOICE_CALL_ENDED = EVENT_LAST + 9; private static final int EVENT_INITIATE_VOLTE_SILENT_REDIAL = EVENT_LAST + 10; static final int RESTART_ECM_TIMER = 0; // restart Ecm timer static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer Loading Loading @@ -334,6 +336,8 @@ public class ImsPhone extends ImsPhoneBase { mDefaultPhone.registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null); // Force initial roaming state update later, on EVENT_CARRIER_CONFIG_CHANGED. // Settings provider or CarrierConfig may not be loaded now. mDefaultPhone.registerForVolteSilentRedial(this, EVENT_INITIATE_VOLTE_SILENT_REDIAL, null); } //todo: get rid of this function. It is not needed since parentPhone obj never changes Loading @@ -356,6 +360,10 @@ public class ImsPhone extends ImsPhoneBase { } mDefaultPhone.unregisterForServiceStateChanged(this); } if (mDefaultPhone != null) { mDefaultPhone.unregisterForVolteSilentRedial(this); } } @UnsupportedAppUsage Loading Loading @@ -1597,6 +1605,36 @@ public class ImsPhone extends ImsPhoneBase { updateRoamingState(sst.mSS); } break; case EVENT_INITIATE_VOLTE_SILENT_REDIAL: { if (VDBG) logd("EVENT_INITIATE_VOLTE_SILENT_REDIAL"); ar = (AsyncResult) msg.obj; if (ar.exception == null && ar.result != null) { SilentRedialParam result = (SilentRedialParam) ar.result; String dialString = result.dialString; int causeCode = result.causeCode; DialArgs dialArgs = result.dialArgs; if (VDBG) logd("dialString=" + dialString + " causeCode=" + causeCode); try { Connection cn = dial(dialString, updateDialArgsForVolteSilentRedial(dialArgs, causeCode)); Rlog.d(LOG_TAG, "Notify volte redial connection changed cn: " + cn); if (mDefaultPhone != null) { // don't care it is null or not. mDefaultPhone.notifyRedialConnectionChanged(cn); } } catch (CallStateException e) { Rlog.e(LOG_TAG, "volte silent redial failed: " + e); if (mDefaultPhone != null) { mDefaultPhone.notifyRedialConnectionChanged(null); } } } else { if (VDBG) logd("EVENT_INITIATE_VOLTE_SILENT_REDIAL" + " has exception or empty result"); } break; } default: super.handleMessage(msg); Loading Loading @@ -2113,6 +2151,35 @@ public class ImsPhone extends ImsPhoneBase { return mDefaultPhone.getIccRecords(); } public DialArgs updateDialArgsForVolteSilentRedial(DialArgs dialArgs, int causeCode) { if (dialArgs != null) { ImsPhone.ImsDialArgs.Builder imsDialArgsBuilder; if (dialArgs instanceof ImsPhone.ImsDialArgs) { imsDialArgsBuilder = ImsPhone.ImsDialArgs.Builder .from((ImsPhone.ImsDialArgs) dialArgs); } else { imsDialArgsBuilder = ImsPhone.ImsDialArgs.Builder .from(dialArgs); } Bundle extras = new Bundle(dialArgs.intentExtras); if (causeCode == CallFailCause.EMC_REDIAL_ON_VOWIFI && isWifiCallingEnabled()) { extras.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE, String.valueOf(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)); logd("trigger VoWifi emergency call"); imsDialArgsBuilder.setIntentExtras(extras); } else if (causeCode == CallFailCause.EMC_REDIAL_ON_IMS) { logd("trigger VoLte emergency call"); } return imsDialArgsBuilder.build(); } return new DialArgs.Builder<>().build(); } public boolean hasAliveCall() { return (getForegroundCall().getState() != Call.State.IDLE || getBackgroundCall().getState() != Call.State.IDLE); } @Override public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); Loading Loading
src/java/com/android/internal/telephony/CallFailCause.java +9 −0 Original line number Diff line number Diff line Loading @@ -440,6 +440,15 @@ public interface CallFailCause { */ int WIFI_LOST = 2507; /** * Indicates a call was disconnected because retry over volte is needed. */ int EMC_REDIAL_ON_IMS = 3001; /** * Indicates a call was disconnected because retry over vowifi is needed. */ int EMC_REDIAL_ON_VOWIFI = 3002; /* OEM specific error codes. To be used by OEMs when they don't want to reveal error code which would be replaced by ERROR_UNSPECIFIED */ Loading
src/java/com/android/internal/telephony/GsmCdmaCallTracker.java +24 −0 Original line number Diff line number Diff line Loading @@ -1552,6 +1552,22 @@ public class GsmCdmaCallTracker extends CallTracker { TelephonyManager.getDefault().getNetworkType()); } if (isEmcRetryCause(causeCode)) { String dialString = ""; for(Connection conn : mForegroundCall.mConnections) { GsmCdmaConnection gsmCdmaConnection = (GsmCdmaConnection)conn; dialString = gsmCdmaConnection.getOrigDialString(); gsmCdmaConnection.getCall().detach(gsmCdmaConnection); mDroppedDuringPoll.remove(gsmCdmaConnection); } mPhone.notifyVolteSilentRedial(dialString, causeCode); updatePhoneState(); if (mDroppedDuringPoll.isEmpty()) { log("LAST_CALL_FAIL_CAUSE - no Dropped normal Call"); return; } } for (int i = 0, s = mDroppedDuringPoll.size(); i < s ; i++) { GsmCdmaConnection conn = mDroppedDuringPoll.get(i); Loading Loading @@ -1758,6 +1774,14 @@ public class GsmCdmaCallTracker extends CallTracker { return mPhone; } private boolean isEmcRetryCause(int causeCode) { if (causeCode == CallFailCause.EMC_REDIAL_ON_IMS || causeCode == CallFailCause.EMC_REDIAL_ON_VOWIFI) { return true; } return false; } @UnsupportedAppUsage @Override protected void log(String msg) { Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +22 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,7 @@ import com.android.internal.telephony.dataconnection.TransportManager; import com.android.internal.telephony.emergency.EmergencyNumberTracker; import com.android.internal.telephony.gsm.GsmMmiCode; import com.android.internal.telephony.gsm.SuppServiceNotification; import com.android.internal.telephony.imsphone.ImsPhone; import com.android.internal.telephony.test.SimulatedRadioControl; import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType; import com.android.internal.telephony.uicc.IccCardStatus; Loading Loading @@ -195,6 +196,9 @@ public class GsmCdmaPhone extends Phone { // mEcmTimerResetRegistrants are informed after Ecm timer is canceled or re-started private final RegistrantList mEcmTimerResetRegistrants = new RegistrantList(); private final RegistrantList mVolteSilentRedialRegistrants = new RegistrantList(); private DialArgs mDialArgs = null; private String mImei; private String mImeiSv; private String mVmNumber; Loading Loading @@ -1264,6 +1268,7 @@ public class GsmCdmaPhone extends Phone { boolean isEmergency = PhoneNumberUtils.isEmergencyNumber(getSubId(), dialString); Phone imsPhone = mImsPhone; mDialArgs = dialArgs; CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); Loading Loading @@ -4088,6 +4093,23 @@ public class GsmCdmaPhone extends Phone { mEcmTimerResetRegistrants.remove(h); } @Override public void registerForVolteSilentRedial(Handler h, int what, Object obj) { mVolteSilentRedialRegistrants.addUnique(h, what, obj); } @Override public void unregisterForVolteSilentRedial(Handler h) { mVolteSilentRedialRegistrants.remove(h); } public void notifyVolteSilentRedial(String dialString, int causeCode) { logd("notifyVolteSilentRedial: dialString=" + dialString + " causeCode=" + causeCode); AsyncResult ar = new AsyncResult(null, new SilentRedialParam(dialString, causeCode, mDialArgs), null); mVolteSilentRedialRegistrants.notifyRegistrants(ar); } /** * Sets the SIM voice message waiting indicator records. * @param line GSM Subscriber Profile Number, one-based. Only '1' is supported Loading
src/java/com/android/internal/telephony/Phone.java +18 −0 Original line number Diff line number Diff line Loading @@ -254,6 +254,18 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { public String operatorAlphaShort; } public static class SilentRedialParam { public String dialString; public int causeCode; public DialArgs dialArgs; public SilentRedialParam(String dialString, int causeCode, DialArgs dialArgs) { this.dialString = dialString; this.causeCode = causeCode; this.dialArgs = dialArgs; } } /* Instance Variables */ @UnsupportedAppUsage public CommandsInterface mCi; Loading Loading @@ -744,6 +756,12 @@ public abstract class Phone extends Handler implements PhoneInternalInterface { public void unregisterForSilentRedial(Handler h) { } public void registerForVolteSilentRedial(Handler h, int what, Object obj) { } public void unregisterForVolteSilentRedial(Handler h) { } private void handleSrvccStateChanged(int[] ret) { Rlog.d(LOG_TAG, "handleSrvccStateChanged"); Loading
src/java/com/android/internal/telephony/imsphone/ImsPhone.java +67 −0 Original line number Diff line number Diff line Loading @@ -87,6 +87,7 @@ import com.android.ims.ImsManager; import com.android.ims.ImsUtInterface; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.Call; import com.android.internal.telephony.CallFailCause; import com.android.internal.telephony.CallForwardInfo; import com.android.internal.telephony.CallStateException; import com.android.internal.telephony.CallTracker; Loading Loading @@ -136,6 +137,7 @@ public class ImsPhone extends ImsPhoneBase { @VisibleForTesting public static final int EVENT_SERVICE_STATE_CHANGED = EVENT_LAST + 8; private static final int EVENT_VOICE_CALL_ENDED = EVENT_LAST + 9; private static final int EVENT_INITIATE_VOLTE_SILENT_REDIAL = EVENT_LAST + 10; static final int RESTART_ECM_TIMER = 0; // restart Ecm timer static final int CANCEL_ECM_TIMER = 1; // cancel Ecm timer Loading Loading @@ -334,6 +336,8 @@ public class ImsPhone extends ImsPhoneBase { mDefaultPhone.registerForServiceStateChanged(this, EVENT_SERVICE_STATE_CHANGED, null); // Force initial roaming state update later, on EVENT_CARRIER_CONFIG_CHANGED. // Settings provider or CarrierConfig may not be loaded now. mDefaultPhone.registerForVolteSilentRedial(this, EVENT_INITIATE_VOLTE_SILENT_REDIAL, null); } //todo: get rid of this function. It is not needed since parentPhone obj never changes Loading @@ -356,6 +360,10 @@ public class ImsPhone extends ImsPhoneBase { } mDefaultPhone.unregisterForServiceStateChanged(this); } if (mDefaultPhone != null) { mDefaultPhone.unregisterForVolteSilentRedial(this); } } @UnsupportedAppUsage Loading Loading @@ -1597,6 +1605,36 @@ public class ImsPhone extends ImsPhoneBase { updateRoamingState(sst.mSS); } break; case EVENT_INITIATE_VOLTE_SILENT_REDIAL: { if (VDBG) logd("EVENT_INITIATE_VOLTE_SILENT_REDIAL"); ar = (AsyncResult) msg.obj; if (ar.exception == null && ar.result != null) { SilentRedialParam result = (SilentRedialParam) ar.result; String dialString = result.dialString; int causeCode = result.causeCode; DialArgs dialArgs = result.dialArgs; if (VDBG) logd("dialString=" + dialString + " causeCode=" + causeCode); try { Connection cn = dial(dialString, updateDialArgsForVolteSilentRedial(dialArgs, causeCode)); Rlog.d(LOG_TAG, "Notify volte redial connection changed cn: " + cn); if (mDefaultPhone != null) { // don't care it is null or not. mDefaultPhone.notifyRedialConnectionChanged(cn); } } catch (CallStateException e) { Rlog.e(LOG_TAG, "volte silent redial failed: " + e); if (mDefaultPhone != null) { mDefaultPhone.notifyRedialConnectionChanged(null); } } } else { if (VDBG) logd("EVENT_INITIATE_VOLTE_SILENT_REDIAL" + " has exception or empty result"); } break; } default: super.handleMessage(msg); Loading Loading @@ -2113,6 +2151,35 @@ public class ImsPhone extends ImsPhoneBase { return mDefaultPhone.getIccRecords(); } public DialArgs updateDialArgsForVolteSilentRedial(DialArgs dialArgs, int causeCode) { if (dialArgs != null) { ImsPhone.ImsDialArgs.Builder imsDialArgsBuilder; if (dialArgs instanceof ImsPhone.ImsDialArgs) { imsDialArgsBuilder = ImsPhone.ImsDialArgs.Builder .from((ImsPhone.ImsDialArgs) dialArgs); } else { imsDialArgsBuilder = ImsPhone.ImsDialArgs.Builder .from(dialArgs); } Bundle extras = new Bundle(dialArgs.intentExtras); if (causeCode == CallFailCause.EMC_REDIAL_ON_VOWIFI && isWifiCallingEnabled()) { extras.putString(ImsCallProfile.EXTRA_CALL_RAT_TYPE, String.valueOf(ServiceState.RIL_RADIO_TECHNOLOGY_IWLAN)); logd("trigger VoWifi emergency call"); imsDialArgsBuilder.setIntentExtras(extras); } else if (causeCode == CallFailCause.EMC_REDIAL_ON_IMS) { logd("trigger VoLte emergency call"); } return imsDialArgsBuilder.build(); } return new DialArgs.Builder<>().build(); } public boolean hasAliveCall() { return (getForegroundCall().getState() != Call.State.IDLE || getBackgroundCall().getState() != Call.State.IDLE); } @Override public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); Loading