Loading src/java/com/android/internal/telephony/GsmCdmaCallTracker.java +2 −1 Original line number Diff line number Diff line Loading @@ -509,7 +509,8 @@ public class GsmCdmaCallTracker extends CallTracker { obtainCompleteMessage()); } }; EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete); EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete, TelephonyManager.STOP_REASON_OUTGOING_NORMAL_CALL_INITIATED); } else { mPhone.exitEmergencyCallbackMode(); mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null); Loading src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java +101 −24 Original line number Diff line number Diff line Loading @@ -20,6 +20,12 @@ import static android.telecom.Connection.STATE_ACTIVE; import static android.telecom.Connection.STATE_DISCONNECTED; import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL; import static android.telephony.TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL; import static android.telephony.TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS; import static android.telephony.TelephonyManager.STOP_REASON_EMERGENCY_SMS_SENT; import static android.telephony.TelephonyManager.STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED; import static android.telephony.TelephonyManager.STOP_REASON_TIMER_EXPIRED; import static android.telephony.TelephonyManager.STOP_REASON_UNKNOWN; import static com.android.internal.telephony.TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED; import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_CALLBACK; Loading Loading @@ -65,6 +71,7 @@ import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.data.PhoneSwitcher; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.imsphone.ImsPhoneConnection; import com.android.internal.telephony.satellite.SatelliteController; import com.android.telephony.Rlog; Loading Loading @@ -148,7 +155,8 @@ public class EmergencyStateTracker { /** For emergency calls */ private final long mEcmExitTimeoutMs; // A runnable which is used to automatically exit from Ecm after a period of time. private final Runnable mExitEcmRunnable = this::exitEmergencyCallbackMode; private final Runnable mExitEcmRunnable = () -> exitEmergencyCallbackMode( STOP_REASON_TIMER_EXPIRED); // Tracks emergency calls by callId that have reached {@link Call.State#ACTIVE}. private final Set<android.telecom.Connection> mActiveEmergencyCalls = new ArraySet<>(); private Phone mPhone; Loading Loading @@ -184,6 +192,8 @@ public class EmergencyStateTracker { private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener = (slotIndex, subId, carrierId, specificCarrierId) -> onCarrierConfigurationChanged( slotIndex, subId); /** Feature flags */ private final FeatureFlags mFeatureFlags; /** * Listens for Emergency Callback Mode state change intents Loading Loading @@ -326,12 +336,14 @@ public class EmergencyStateTracker { if (!isSamePhone(mPhone, mSmsPhone)) { completeEmergencyMode(emergencyType, DisconnectCause.OUTGOING_EMERGENCY_CALL_PLACED); exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode( STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); } } else { completeEmergencyMode(emergencyType); mIsEmergencyCallStartedDuringEmergencySms = false; exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode( STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL, mIsTestEmergencyNumber); } Loading @@ -343,7 +355,8 @@ public class EmergencyStateTracker { if (mIsEmergencyCallStartedDuringEmergencySms) { mIsEmergencyCallStartedDuringEmergencySms = false; exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode( STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL, mIsTestEmergencyNumber); } Loading Loading @@ -409,7 +422,8 @@ public class EmergencyStateTracker { // the emergency call was started, needs to exit the emergency mode first. if (mIsEmergencyCallStartedDuringEmergencySms) { final Phone smsPhone = mSmsPhone; exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode( STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); if (mPhone != null && smsPhone != null && !isSamePhone(mPhone, smsPhone)) { Loading @@ -428,7 +442,7 @@ public class EmergencyStateTracker { break; } case MSG_EXIT_SCBM: { exitEmergencySmsCallbackModeAndEmergencyMode(); exitEmergencySmsCallbackModeAndEmergencyMode(STOP_REASON_TIMER_EXPIRED); break; } case MSG_NEW_RINGING_CONNECTION: { Loading Loading @@ -457,11 +471,13 @@ public class EmergencyStateTracker { * @param context The context of the application. * @param isSuplDdsSwitchRequiredForEmergencyCall Whether gnss supl requires default data for * emergency call. * @param featureFlags The telephony feature flags. */ public static void make(Context context, boolean isSuplDdsSwitchRequiredForEmergencyCall) { public static void make(Context context, boolean isSuplDdsSwitchRequiredForEmergencyCall, @NonNull FeatureFlags featureFlags) { if (INSTANCE == null) { INSTANCE = new EmergencyStateTracker(context, Looper.myLooper(), isSuplDdsSwitchRequiredForEmergencyCall); isSuplDdsSwitchRequiredForEmergencyCall, featureFlags); } } Loading @@ -481,12 +497,12 @@ public class EmergencyStateTracker { * Initializes EmergencyStateTracker. */ private EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall) { boolean isSuplDdsSwitchRequiredForEmergencyCall, @NonNull FeatureFlags featureFlags) { mEcmExitTimeoutMs = DEFAULT_ECM_EXIT_TIMEOUT_MS; mContext = context; mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; mFeatureFlags = featureFlags; PowerManager pm = context.getSystemService(PowerManager.class); mWakeLock = (pm != null) ? pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "telephony:" + TAG) : null; Loading Loading @@ -523,12 +539,13 @@ public class EmergencyStateTracker { * @param telephonyManagerProxy The {@link TelephonyManagerProxy} to be * injected. * @param radioOnHelper The {@link RadioOnHelper} to be injected. * @param featureFlags The {@link FeatureFlags} to be injected. */ @VisibleForTesting public EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall, PhoneFactoryProxy phoneFactoryProxy, PhoneSwitcherProxy phoneSwitcherProxy, TelephonyManagerProxy telephonyManagerProxy, RadioOnHelper radioOnHelper, long ecmExitTimeoutMs) { RadioOnHelper radioOnHelper, long ecmExitTimeoutMs, FeatureFlags featureFlags) { mContext = context; mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; Loading @@ -537,6 +554,7 @@ public class EmergencyStateTracker { mTelephonyManagerProxy = telephonyManagerProxy; mRadioOnHelper = radioOnHelper; mEcmExitTimeoutMs = ecmExitTimeoutMs; mFeatureFlags = featureFlags; mWakeLock = null; // Don't declare a wakelock in tests mConfigManager = context.getSystemService(CarrierConfigManager.class); mConfigManager.registerCarrierConfigChangeListener(mHandler::post, Loading Loading @@ -574,7 +592,7 @@ public class EmergencyStateTracker { // Case1) When 2nd emergency call is initiated during an active call on the same phone. // Case2) While the device is in ECBM, an emergency call is initiated on the same phone. if (isSamePhone(mPhone, phone) && (!mActiveEmergencyCalls.isEmpty() || isInEcm())) { exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode(STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); mOngoingConnection = c; mIsTestEmergencyNumber = isTestEmergencyNumber; if (isInEcm()) { Loading Loading @@ -622,7 +640,7 @@ public class EmergencyStateTracker { mIsEmergencyCallStartedDuringEmergencySms = false; } exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode(STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); } if (mIsEmergencyCallStartedDuringEmergencySms) { Loading Loading @@ -1087,7 +1105,7 @@ public class EmergencyStateTracker { * Handles the radio power off request. */ public void onCellularRadioPowerOffRequested() { exitEmergencySmsCallbackModeAndEmergencyMode(); exitEmergencySmsCallbackModeAndEmergencyMode(STOP_REASON_UNKNOWN); exitEmergencyCallbackMode(); } Loading Loading @@ -1159,10 +1177,14 @@ public class EmergencyStateTracker { setEmergencyCallbackMode(mPhone, EMERGENCY_TYPE_CALL); // Post this runnable so we will automatically exit if no one invokes // exitEmergencyCallbackMode() directly. long delayInMillis = TelephonyProperties.ecm_exit_timer() .orElse(mEcmExitTimeoutMs); if (mFeatureFlags.emergencyCallbackModeNotification()) { mPhone.startEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_CALL, delayInMillis); } // Post this runnable so we will automatically exit if no one invokes // exitEmergencyCallbackMode() directly. mHandler.postDelayed(mExitEcmRunnable, delayInMillis); // We don't want to go to sleep while in ECM. Loading @@ -1170,9 +1192,27 @@ public class EmergencyStateTracker { } /** * Exits emergency callback mode and notifies relevant listeners. * Exits the emergency callback mode. * * <p>This method exits the emergency callback mode with an unknown stop reason. It removes * any pending exit requests and notifies relevant listeners about the change in status. */ public void exitEmergencyCallbackMode() { exitEmergencyCallbackMode(STOP_REASON_UNKNOWN); } /** * Exits the emergency callback mode. * * <p>This method exits the emergency callback mode with the specified stop reason. It removes * any pending exit requests and notifies relevant listeners about the change in status, * providing the reason for exiting. * * @param reason The reason for exiting. See * {@link TelephonyManager.EmergencyCallbackModeStopReason} for possible values. */ public void exitEmergencyCallbackMode( @TelephonyManager.EmergencyCallbackModeStopReason int reason) { Rlog.d(TAG, "exit ECBM"); // Remove pending exit ECM runnable, if any. mHandler.removeCallbacks(mExitEcmRunnable); Loading @@ -1191,6 +1231,10 @@ public class EmergencyStateTracker { sendEmergencyCallbackModeChange(); gsmCdmaPhone.notifyEmergencyCallRegistrants(false); if (mFeatureFlags.emergencyCallbackModeNotification()) { gsmCdmaPhone.stopEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_CALL, reason); } // Exit emergency mode on modem. exitEmergencyMode(gsmCdmaPhone, EMERGENCY_TYPE_CALL); } Loading @@ -1213,11 +1257,20 @@ public class EmergencyStateTracker { } /** * Exits emergency callback mode and triggers runnable after exit response is received. * Exits the emergency callback mode and triggers {@link Runnable} after exit response is * received. * * <p>This method exits the emergency callback mode with the specified stop reason and then * executes the provided {@link Runnable}. * * @param onComplete The {@link Runnable} to execute after exiting emergency callback mode. * @param reason The reason for exiting. See * {@link TelephonyManager.EmergencyCallbackModeStopReason} for possible values. */ public void exitEmergencyCallbackMode(Runnable onComplete) { public void exitEmergencyCallbackMode(Runnable onComplete, @TelephonyManager.EmergencyCallbackModeStopReason int reason) { mOnEcmExitCompleteRunnable = onComplete; exitEmergencyCallbackMode(); exitEmergencyCallbackMode(reason); } /** Loading Loading @@ -1323,7 +1376,7 @@ public class EmergencyStateTracker { // emergency SMS callback mode first. exitScbmInOtherPhone = true; mIsEmergencySmsStartedDuringScbm = true; exitEmergencySmsCallbackModeAndEmergencyMode(); exitEmergencySmsCallbackModeAndEmergencyMode(STOP_REASON_EMERGENCY_SMS_SENT); } else { Rlog.e(TAG, "Emergency SMS is in progress on the other slot."); return CompletableFuture.completedFuture(DisconnectCause.ERROR_UNSPECIFIED); Loading Loading @@ -1460,6 +1513,9 @@ public class EmergencyStateTracker { */ private void enterEmergencySmsCallbackMode() { Rlog.d(TAG, "enter SCBM while " + (isInScbm() ? "in" : "not in") + " SCBM"); boolean shouldRestartEcm = isInScbm(); // Remove pending message if present. mHandler.removeMessages(MSG_EXIT_SCBM); Loading @@ -1484,17 +1540,29 @@ public class EmergencyStateTracker { // Post the message so we will automatically exit if no one invokes // exitEmergencySmsCallbackModeAndEmergencyMode() directly. mHandler.sendEmptyMessageDelayed(MSG_EXIT_SCBM, delayInMillis); if (mFeatureFlags.emergencyCallbackModeNotification()) { if (shouldRestartEcm) { mSmsPhone.restartEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_SMS, delayInMillis); } else { mSmsPhone.startEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_SMS, delayInMillis); } } } /** * Exits emergency SMS callback mode and emergency mode if the device is in SCBM and * the emergency mode is in CALLBACK. * * @param reason The reason for exiting. See * {@link TelephonyManager.EmergencyCallbackModeStopReason} for possible values. */ private void exitEmergencySmsCallbackModeAndEmergencyMode() { private void exitEmergencySmsCallbackModeAndEmergencyMode( @TelephonyManager.EmergencyCallbackModeStopReason int reason) { Rlog.d(TAG, "exit SCBM and emergency mode"); final Phone smsPhone = mSmsPhone; boolean wasInScbm = isInScbm(); exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode(reason); // The emergency mode needs to be checked to ensure that there is no ongoing emergency SMS. if (wasInScbm && mOngoingEmergencySmsIds.isEmpty()) { Loading @@ -1505,13 +1573,22 @@ public class EmergencyStateTracker { /** * Exits emergency SMS callback mode. * * @param reason The reason for exiting. See * {@link TelephonyManager.EmergencyCallbackModeStopReason} for possible values. */ private void exitEmergencySmsCallbackMode() { private void exitEmergencySmsCallbackMode( @TelephonyManager.EmergencyCallbackModeStopReason int reason) { // Remove pending message if present. mHandler.removeMessages(MSG_EXIT_SCBM); if (isInScbm()) { Rlog.i(TAG, "exit SCBM"); if (mFeatureFlags.emergencyCallbackModeNotification()) { mSmsPhone.stopEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_SMS, reason); } setIsInScbm(false); } Loading src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +2 −1 Original line number Diff line number Diff line Loading @@ -1797,7 +1797,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { dialArgs.intentExtras); } }; EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete); EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete, TelephonyManager.STOP_REASON_OUTGOING_NORMAL_CALL_INITIATED); } else { try { getEcbmInterface().exitEmergencyCallbackMode(); Loading tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java +35 −4 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
src/java/com/android/internal/telephony/GsmCdmaCallTracker.java +2 −1 Original line number Diff line number Diff line Loading @@ -509,7 +509,8 @@ public class GsmCdmaCallTracker extends CallTracker { obtainCompleteMessage()); } }; EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete); EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete, TelephonyManager.STOP_REASON_OUTGOING_NORMAL_CALL_INITIATED); } else { mPhone.exitEmergencyCallbackMode(); mPhone.setOnEcbModeExitResponse(this, EVENT_EXIT_ECM_RESPONSE_CDMA, null); Loading
src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java +101 −24 Original line number Diff line number Diff line Loading @@ -20,6 +20,12 @@ import static android.telecom.Connection.STATE_ACTIVE; import static android.telecom.Connection.STATE_DISCONNECTED; import static android.telephony.CarrierConfigManager.ImsEmergency.KEY_EMERGENCY_CALLBACK_MODE_SUPPORTED_BOOL; import static android.telephony.CarrierConfigManager.KEY_BROADCAST_EMERGENCY_CALL_STATE_CHANGES_BOOL; import static android.telephony.TelephonyManager.EMERGENCY_CALLBACK_MODE_CALL; import static android.telephony.TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS; import static android.telephony.TelephonyManager.STOP_REASON_EMERGENCY_SMS_SENT; import static android.telephony.TelephonyManager.STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED; import static android.telephony.TelephonyManager.STOP_REASON_TIMER_EXPIRED; import static android.telephony.TelephonyManager.STOP_REASON_UNKNOWN; import static com.android.internal.telephony.TelephonyIntents.ACTION_EMERGENCY_CALL_STATE_CHANGED; import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_CALLBACK; Loading Loading @@ -65,6 +71,7 @@ import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.PhoneFactory; import com.android.internal.telephony.TelephonyIntents; import com.android.internal.telephony.data.PhoneSwitcher; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.imsphone.ImsPhoneConnection; import com.android.internal.telephony.satellite.SatelliteController; import com.android.telephony.Rlog; Loading Loading @@ -148,7 +155,8 @@ public class EmergencyStateTracker { /** For emergency calls */ private final long mEcmExitTimeoutMs; // A runnable which is used to automatically exit from Ecm after a period of time. private final Runnable mExitEcmRunnable = this::exitEmergencyCallbackMode; private final Runnable mExitEcmRunnable = () -> exitEmergencyCallbackMode( STOP_REASON_TIMER_EXPIRED); // Tracks emergency calls by callId that have reached {@link Call.State#ACTIVE}. private final Set<android.telecom.Connection> mActiveEmergencyCalls = new ArraySet<>(); private Phone mPhone; Loading Loading @@ -184,6 +192,8 @@ public class EmergencyStateTracker { private final CarrierConfigManager.CarrierConfigChangeListener mCarrierConfigChangeListener = (slotIndex, subId, carrierId, specificCarrierId) -> onCarrierConfigurationChanged( slotIndex, subId); /** Feature flags */ private final FeatureFlags mFeatureFlags; /** * Listens for Emergency Callback Mode state change intents Loading Loading @@ -326,12 +336,14 @@ public class EmergencyStateTracker { if (!isSamePhone(mPhone, mSmsPhone)) { completeEmergencyMode(emergencyType, DisconnectCause.OUTGOING_EMERGENCY_CALL_PLACED); exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode( STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); } } else { completeEmergencyMode(emergencyType); mIsEmergencyCallStartedDuringEmergencySms = false; exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode( STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL, mIsTestEmergencyNumber); } Loading @@ -343,7 +355,8 @@ public class EmergencyStateTracker { if (mIsEmergencyCallStartedDuringEmergencySms) { mIsEmergencyCallStartedDuringEmergencySms = false; exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode( STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); turnOnRadioAndSwitchDds(mPhone, EMERGENCY_TYPE_CALL, mIsTestEmergencyNumber); } Loading Loading @@ -409,7 +422,8 @@ public class EmergencyStateTracker { // the emergency call was started, needs to exit the emergency mode first. if (mIsEmergencyCallStartedDuringEmergencySms) { final Phone smsPhone = mSmsPhone; exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode( STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); if (mPhone != null && smsPhone != null && !isSamePhone(mPhone, smsPhone)) { Loading @@ -428,7 +442,7 @@ public class EmergencyStateTracker { break; } case MSG_EXIT_SCBM: { exitEmergencySmsCallbackModeAndEmergencyMode(); exitEmergencySmsCallbackModeAndEmergencyMode(STOP_REASON_TIMER_EXPIRED); break; } case MSG_NEW_RINGING_CONNECTION: { Loading Loading @@ -457,11 +471,13 @@ public class EmergencyStateTracker { * @param context The context of the application. * @param isSuplDdsSwitchRequiredForEmergencyCall Whether gnss supl requires default data for * emergency call. * @param featureFlags The telephony feature flags. */ public static void make(Context context, boolean isSuplDdsSwitchRequiredForEmergencyCall) { public static void make(Context context, boolean isSuplDdsSwitchRequiredForEmergencyCall, @NonNull FeatureFlags featureFlags) { if (INSTANCE == null) { INSTANCE = new EmergencyStateTracker(context, Looper.myLooper(), isSuplDdsSwitchRequiredForEmergencyCall); isSuplDdsSwitchRequiredForEmergencyCall, featureFlags); } } Loading @@ -481,12 +497,12 @@ public class EmergencyStateTracker { * Initializes EmergencyStateTracker. */ private EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall) { boolean isSuplDdsSwitchRequiredForEmergencyCall, @NonNull FeatureFlags featureFlags) { mEcmExitTimeoutMs = DEFAULT_ECM_EXIT_TIMEOUT_MS; mContext = context; mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; mFeatureFlags = featureFlags; PowerManager pm = context.getSystemService(PowerManager.class); mWakeLock = (pm != null) ? pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "telephony:" + TAG) : null; Loading Loading @@ -523,12 +539,13 @@ public class EmergencyStateTracker { * @param telephonyManagerProxy The {@link TelephonyManagerProxy} to be * injected. * @param radioOnHelper The {@link RadioOnHelper} to be injected. * @param featureFlags The {@link FeatureFlags} to be injected. */ @VisibleForTesting public EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall, PhoneFactoryProxy phoneFactoryProxy, PhoneSwitcherProxy phoneSwitcherProxy, TelephonyManagerProxy telephonyManagerProxy, RadioOnHelper radioOnHelper, long ecmExitTimeoutMs) { RadioOnHelper radioOnHelper, long ecmExitTimeoutMs, FeatureFlags featureFlags) { mContext = context; mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; Loading @@ -537,6 +554,7 @@ public class EmergencyStateTracker { mTelephonyManagerProxy = telephonyManagerProxy; mRadioOnHelper = radioOnHelper; mEcmExitTimeoutMs = ecmExitTimeoutMs; mFeatureFlags = featureFlags; mWakeLock = null; // Don't declare a wakelock in tests mConfigManager = context.getSystemService(CarrierConfigManager.class); mConfigManager.registerCarrierConfigChangeListener(mHandler::post, Loading Loading @@ -574,7 +592,7 @@ public class EmergencyStateTracker { // Case1) When 2nd emergency call is initiated during an active call on the same phone. // Case2) While the device is in ECBM, an emergency call is initiated on the same phone. if (isSamePhone(mPhone, phone) && (!mActiveEmergencyCalls.isEmpty() || isInEcm())) { exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode(STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); mOngoingConnection = c; mIsTestEmergencyNumber = isTestEmergencyNumber; if (isInEcm()) { Loading Loading @@ -622,7 +640,7 @@ public class EmergencyStateTracker { mIsEmergencyCallStartedDuringEmergencySms = false; } exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode(STOP_REASON_OUTGOING_EMERGENCY_CALL_INITIATED); } if (mIsEmergencyCallStartedDuringEmergencySms) { Loading Loading @@ -1087,7 +1105,7 @@ public class EmergencyStateTracker { * Handles the radio power off request. */ public void onCellularRadioPowerOffRequested() { exitEmergencySmsCallbackModeAndEmergencyMode(); exitEmergencySmsCallbackModeAndEmergencyMode(STOP_REASON_UNKNOWN); exitEmergencyCallbackMode(); } Loading Loading @@ -1159,10 +1177,14 @@ public class EmergencyStateTracker { setEmergencyCallbackMode(mPhone, EMERGENCY_TYPE_CALL); // Post this runnable so we will automatically exit if no one invokes // exitEmergencyCallbackMode() directly. long delayInMillis = TelephonyProperties.ecm_exit_timer() .orElse(mEcmExitTimeoutMs); if (mFeatureFlags.emergencyCallbackModeNotification()) { mPhone.startEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_CALL, delayInMillis); } // Post this runnable so we will automatically exit if no one invokes // exitEmergencyCallbackMode() directly. mHandler.postDelayed(mExitEcmRunnable, delayInMillis); // We don't want to go to sleep while in ECM. Loading @@ -1170,9 +1192,27 @@ public class EmergencyStateTracker { } /** * Exits emergency callback mode and notifies relevant listeners. * Exits the emergency callback mode. * * <p>This method exits the emergency callback mode with an unknown stop reason. It removes * any pending exit requests and notifies relevant listeners about the change in status. */ public void exitEmergencyCallbackMode() { exitEmergencyCallbackMode(STOP_REASON_UNKNOWN); } /** * Exits the emergency callback mode. * * <p>This method exits the emergency callback mode with the specified stop reason. It removes * any pending exit requests and notifies relevant listeners about the change in status, * providing the reason for exiting. * * @param reason The reason for exiting. See * {@link TelephonyManager.EmergencyCallbackModeStopReason} for possible values. */ public void exitEmergencyCallbackMode( @TelephonyManager.EmergencyCallbackModeStopReason int reason) { Rlog.d(TAG, "exit ECBM"); // Remove pending exit ECM runnable, if any. mHandler.removeCallbacks(mExitEcmRunnable); Loading @@ -1191,6 +1231,10 @@ public class EmergencyStateTracker { sendEmergencyCallbackModeChange(); gsmCdmaPhone.notifyEmergencyCallRegistrants(false); if (mFeatureFlags.emergencyCallbackModeNotification()) { gsmCdmaPhone.stopEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_CALL, reason); } // Exit emergency mode on modem. exitEmergencyMode(gsmCdmaPhone, EMERGENCY_TYPE_CALL); } Loading @@ -1213,11 +1257,20 @@ public class EmergencyStateTracker { } /** * Exits emergency callback mode and triggers runnable after exit response is received. * Exits the emergency callback mode and triggers {@link Runnable} after exit response is * received. * * <p>This method exits the emergency callback mode with the specified stop reason and then * executes the provided {@link Runnable}. * * @param onComplete The {@link Runnable} to execute after exiting emergency callback mode. * @param reason The reason for exiting. See * {@link TelephonyManager.EmergencyCallbackModeStopReason} for possible values. */ public void exitEmergencyCallbackMode(Runnable onComplete) { public void exitEmergencyCallbackMode(Runnable onComplete, @TelephonyManager.EmergencyCallbackModeStopReason int reason) { mOnEcmExitCompleteRunnable = onComplete; exitEmergencyCallbackMode(); exitEmergencyCallbackMode(reason); } /** Loading Loading @@ -1323,7 +1376,7 @@ public class EmergencyStateTracker { // emergency SMS callback mode first. exitScbmInOtherPhone = true; mIsEmergencySmsStartedDuringScbm = true; exitEmergencySmsCallbackModeAndEmergencyMode(); exitEmergencySmsCallbackModeAndEmergencyMode(STOP_REASON_EMERGENCY_SMS_SENT); } else { Rlog.e(TAG, "Emergency SMS is in progress on the other slot."); return CompletableFuture.completedFuture(DisconnectCause.ERROR_UNSPECIFIED); Loading Loading @@ -1460,6 +1513,9 @@ public class EmergencyStateTracker { */ private void enterEmergencySmsCallbackMode() { Rlog.d(TAG, "enter SCBM while " + (isInScbm() ? "in" : "not in") + " SCBM"); boolean shouldRestartEcm = isInScbm(); // Remove pending message if present. mHandler.removeMessages(MSG_EXIT_SCBM); Loading @@ -1484,17 +1540,29 @@ public class EmergencyStateTracker { // Post the message so we will automatically exit if no one invokes // exitEmergencySmsCallbackModeAndEmergencyMode() directly. mHandler.sendEmptyMessageDelayed(MSG_EXIT_SCBM, delayInMillis); if (mFeatureFlags.emergencyCallbackModeNotification()) { if (shouldRestartEcm) { mSmsPhone.restartEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_SMS, delayInMillis); } else { mSmsPhone.startEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_SMS, delayInMillis); } } } /** * Exits emergency SMS callback mode and emergency mode if the device is in SCBM and * the emergency mode is in CALLBACK. * * @param reason The reason for exiting. See * {@link TelephonyManager.EmergencyCallbackModeStopReason} for possible values. */ private void exitEmergencySmsCallbackModeAndEmergencyMode() { private void exitEmergencySmsCallbackModeAndEmergencyMode( @TelephonyManager.EmergencyCallbackModeStopReason int reason) { Rlog.d(TAG, "exit SCBM and emergency mode"); final Phone smsPhone = mSmsPhone; boolean wasInScbm = isInScbm(); exitEmergencySmsCallbackMode(); exitEmergencySmsCallbackMode(reason); // The emergency mode needs to be checked to ensure that there is no ongoing emergency SMS. if (wasInScbm && mOngoingEmergencySmsIds.isEmpty()) { Loading @@ -1505,13 +1573,22 @@ public class EmergencyStateTracker { /** * Exits emergency SMS callback mode. * * @param reason The reason for exiting. See * {@link TelephonyManager.EmergencyCallbackModeStopReason} for possible values. */ private void exitEmergencySmsCallbackMode() { private void exitEmergencySmsCallbackMode( @TelephonyManager.EmergencyCallbackModeStopReason int reason) { // Remove pending message if present. mHandler.removeMessages(MSG_EXIT_SCBM); if (isInScbm()) { Rlog.i(TAG, "exit SCBM"); if (mFeatureFlags.emergencyCallbackModeNotification()) { mSmsPhone.stopEmergencyCallbackMode(EMERGENCY_CALLBACK_MODE_SMS, reason); } setIsInScbm(false); } Loading
src/java/com/android/internal/telephony/imsphone/ImsPhoneCallTracker.java +2 −1 Original line number Diff line number Diff line Loading @@ -1797,7 +1797,8 @@ public class ImsPhoneCallTracker extends CallTracker implements ImsPullCall { dialArgs.intentExtras); } }; EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete); EmergencyStateTracker.getInstance().exitEmergencyCallbackMode(onComplete, TelephonyManager.STOP_REASON_OUTGOING_NORMAL_CALL_INITIATED); } else { try { getEcbmInterface().exitEmergencyCallbackMode(); Loading
tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java +35 −4 File changed.Preview size limit exceeded, changes collapsed. Show changes