Loading res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -429,4 +429,7 @@ <!-- In-call screen: error message shown when the user attempts to dial an MMI code, but there is an ongoing call on a different phone account. --> <string name="callFailed_reject_mmi">This MMI code is not available for calls across multiple accounts.</string> <!-- In-call screen: error message shown when the user attempts to dial an MMI code during an ongoing emergency call. --> <string name="emergencyCall_reject_mmi">MMI codes cannot be dialed during an emergency call.</string> </resources> src/com/android/server/telecom/CallsManager.java +9 −2 Original line number Diff line number Diff line Loading @@ -800,7 +800,7 @@ public class CallsManager extends Call.ListenerBase : null; mCallSequencingAdapter = new CallsManagerCallSequencingAdapter(this, mContext, new CallSequencingController(this, mContext, mClockProxy, mAnomalyReporter, mTimeoutsAdapter, mMetricsController, mAnomalyReporter, mTimeoutsAdapter, mMetricsController, mMmiUtils, mFeatureFlags), mCallAudioManager, mFeatureFlags); if (mFeatureFlags.useImprovedListenerOrder()) { Loading Loading @@ -2213,12 +2213,15 @@ public class CallsManager extends Call.ListenerBase potentialPhoneAccounts -> { Log.i(CallsManager.this, "make room for outgoing call stage"); if (mMmiUtils.isPotentialInCallMMICode(handle) && !isSelfManaged) { // We will allow the MMI code if call sequencing is not enabled or there // are only calls on the same phone account. boolean shouldAllowMmiCode = mCallSequencingAdapter .shouldAllowMmiCode(finalCall); if (shouldAllowMmiCode) { return CompletableFuture.completedFuture(true); } else { Log.i(this, "Rejecting the MMI code because there is an " // Reject the in-call MMI code. Log.i(this, "Rejecting the in-call MMI code because there is an " + "ongoing call on a different phone account."); return CompletableFuture.completedFuture(false); } Loading Loading @@ -2254,6 +2257,10 @@ public class CallsManager extends Call.ListenerBase finalCall.getTargetPhoneAccount(), finalCall); } finalCall.setStartFailCause(CallFailureCause.IN_EMERGENCY_CALL); // Show an error message when dialing a MMI code during an emergency call. if (mMmiUtils.isPotentialMMICode(handle)) { showErrorMessage(R.string.emergencyCall_reject_mmi); } return CompletableFuture.completedFuture(false); } Loading src/com/android/server/telecom/callsequencing/CallSequencingController.java +15 −3 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import com.android.server.telecom.CallsManager; import com.android.server.telecom.ClockProxy; import com.android.server.telecom.LogUtils; import com.android.server.telecom.LoggedHandlerExecutor; import com.android.server.telecom.MmiUtils; import com.android.server.telecom.R; import com.android.server.telecom.Timeouts; import com.android.server.telecom.callsequencing.voip.OutgoingCallTransaction; Loading Loading @@ -85,6 +86,7 @@ public class CallSequencingController { private final TelecomMetricsController mMetricsController; private final Handler mHandler; private final Context mContext; private final MmiUtils mMmiUtils; private final FeatureFlags mFeatureFlags; private static String TAG = CallSequencingController.class.getSimpleName(); public static final UUID SEQUENCING_CANNOT_HOLD_ACTIVE_CALL_UUID = Loading @@ -95,7 +97,7 @@ public class CallSequencingController { public CallSequencingController(CallsManager callsManager, Context context, ClockProxy clockProxy, AnomalyReporterAdapter anomalyReporter, Timeouts.Adapter timeoutsAdapter, TelecomMetricsController metricsController, FeatureFlags featureFlags) { MmiUtils mmiUtils, FeatureFlags featureFlags) { mCallsManager = callsManager; mClockProxy = clockProxy; mAnomalyReporter = anomalyReporter; Loading @@ -104,6 +106,7 @@ public class CallSequencingController { HandlerThread handlerThread = new HandlerThread(this.toString()); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); mMmiUtils = mmiUtils; mFeatureFlags = featureFlags; mContext = context; } Loading Loading @@ -759,9 +762,18 @@ public class CallSequencingController { return CompletableFuture.completedFuture(false); } // If we detect a MMI code, allow it to go through since we are not treating it as an actual // call. if (mMmiUtils.isPotentialMMICode(call.getHandle())) { Log.i(this, "makeRoomForOutgoingCall: Detected mmi code. Allowing to go through."); return CompletableFuture.completedFuture(true); } // Early check to see if we already have a held call + live call. It's possible if a device // switches to DSDS with two ongoing calls for the phone account to be null in which case // we will return true from this method and report a different failure cause instead. // switches to DSDS with two ongoing calls for the phone account to be null in which case, // based on the logic below, we would've completed the future with true and reported a // different failure cause. Now, we perform this early check to ensure the right max // outgoing call restriction error is displayed instead. if (mCallsManager.hasMaximumManagedHoldingCalls(call) && !mCallsManager.canHold(liveCall)) { showErrorDialogForMaxOutgoingCall(call); return CompletableFuture.completedFuture(false); Loading tests/src/com/android/server/telecom/tests/CallSequencingTests.java +3 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import com.android.server.telecom.CallState; import com.android.server.telecom.CallsManager; import com.android.server.telecom.ClockProxy; import com.android.server.telecom.ConnectionServiceFocusManager; import com.android.server.telecom.MmiUtils; import com.android.server.telecom.PhoneAccountRegistrar; import com.android.server.telecom.Timeouts; import com.android.server.telecom.callsequencing.CallSequencingController; Loading Loading @@ -104,6 +105,7 @@ public class CallSequencingTests extends TelecomTestCase { @Mock AnomalyReporterAdapter mAnomalyReporter; @Mock Timeouts.Adapter mTimeoutsAdapter; @Mock TelecomMetricsController mMetricsController; @Mock MmiUtils mMmiUtils; @Mock ConnectionServiceFocusManager mConnectionServiceFocusManager; @Mock Call mActiveCall; Loading @@ -117,7 +119,7 @@ public class CallSequencingTests extends TelecomTestCase { super.setUp(); when(mFeatureFlags.enableCallSequencing()).thenReturn(true); mController = new CallSequencingController(mCallsManager, mContext, mClockProxy, mAnomalyReporter, mTimeoutsAdapter, mMetricsController, mFeatureFlags); mAnomalyReporter, mTimeoutsAdapter, mMetricsController, mMmiUtils, mFeatureFlags); when(mActiveCall.getState()).thenReturn(CallState.ACTIVE); when(mRingingCall.getState()).thenReturn(CallState.RINGING); Loading Loading
res/values/strings.xml +3 −0 Original line number Diff line number Diff line Loading @@ -429,4 +429,7 @@ <!-- In-call screen: error message shown when the user attempts to dial an MMI code, but there is an ongoing call on a different phone account. --> <string name="callFailed_reject_mmi">This MMI code is not available for calls across multiple accounts.</string> <!-- In-call screen: error message shown when the user attempts to dial an MMI code during an ongoing emergency call. --> <string name="emergencyCall_reject_mmi">MMI codes cannot be dialed during an emergency call.</string> </resources>
src/com/android/server/telecom/CallsManager.java +9 −2 Original line number Diff line number Diff line Loading @@ -800,7 +800,7 @@ public class CallsManager extends Call.ListenerBase : null; mCallSequencingAdapter = new CallsManagerCallSequencingAdapter(this, mContext, new CallSequencingController(this, mContext, mClockProxy, mAnomalyReporter, mTimeoutsAdapter, mMetricsController, mAnomalyReporter, mTimeoutsAdapter, mMetricsController, mMmiUtils, mFeatureFlags), mCallAudioManager, mFeatureFlags); if (mFeatureFlags.useImprovedListenerOrder()) { Loading Loading @@ -2213,12 +2213,15 @@ public class CallsManager extends Call.ListenerBase potentialPhoneAccounts -> { Log.i(CallsManager.this, "make room for outgoing call stage"); if (mMmiUtils.isPotentialInCallMMICode(handle) && !isSelfManaged) { // We will allow the MMI code if call sequencing is not enabled or there // are only calls on the same phone account. boolean shouldAllowMmiCode = mCallSequencingAdapter .shouldAllowMmiCode(finalCall); if (shouldAllowMmiCode) { return CompletableFuture.completedFuture(true); } else { Log.i(this, "Rejecting the MMI code because there is an " // Reject the in-call MMI code. Log.i(this, "Rejecting the in-call MMI code because there is an " + "ongoing call on a different phone account."); return CompletableFuture.completedFuture(false); } Loading Loading @@ -2254,6 +2257,10 @@ public class CallsManager extends Call.ListenerBase finalCall.getTargetPhoneAccount(), finalCall); } finalCall.setStartFailCause(CallFailureCause.IN_EMERGENCY_CALL); // Show an error message when dialing a MMI code during an emergency call. if (mMmiUtils.isPotentialMMICode(handle)) { showErrorMessage(R.string.emergencyCall_reject_mmi); } return CompletableFuture.completedFuture(false); } Loading
src/com/android/server/telecom/callsequencing/CallSequencingController.java +15 −3 Original line number Diff line number Diff line Loading @@ -54,6 +54,7 @@ import com.android.server.telecom.CallsManager; import com.android.server.telecom.ClockProxy; import com.android.server.telecom.LogUtils; import com.android.server.telecom.LoggedHandlerExecutor; import com.android.server.telecom.MmiUtils; import com.android.server.telecom.R; import com.android.server.telecom.Timeouts; import com.android.server.telecom.callsequencing.voip.OutgoingCallTransaction; Loading Loading @@ -85,6 +86,7 @@ public class CallSequencingController { private final TelecomMetricsController mMetricsController; private final Handler mHandler; private final Context mContext; private final MmiUtils mMmiUtils; private final FeatureFlags mFeatureFlags; private static String TAG = CallSequencingController.class.getSimpleName(); public static final UUID SEQUENCING_CANNOT_HOLD_ACTIVE_CALL_UUID = Loading @@ -95,7 +97,7 @@ public class CallSequencingController { public CallSequencingController(CallsManager callsManager, Context context, ClockProxy clockProxy, AnomalyReporterAdapter anomalyReporter, Timeouts.Adapter timeoutsAdapter, TelecomMetricsController metricsController, FeatureFlags featureFlags) { MmiUtils mmiUtils, FeatureFlags featureFlags) { mCallsManager = callsManager; mClockProxy = clockProxy; mAnomalyReporter = anomalyReporter; Loading @@ -104,6 +106,7 @@ public class CallSequencingController { HandlerThread handlerThread = new HandlerThread(this.toString()); handlerThread.start(); mHandler = new Handler(handlerThread.getLooper()); mMmiUtils = mmiUtils; mFeatureFlags = featureFlags; mContext = context; } Loading Loading @@ -759,9 +762,18 @@ public class CallSequencingController { return CompletableFuture.completedFuture(false); } // If we detect a MMI code, allow it to go through since we are not treating it as an actual // call. if (mMmiUtils.isPotentialMMICode(call.getHandle())) { Log.i(this, "makeRoomForOutgoingCall: Detected mmi code. Allowing to go through."); return CompletableFuture.completedFuture(true); } // Early check to see if we already have a held call + live call. It's possible if a device // switches to DSDS with two ongoing calls for the phone account to be null in which case // we will return true from this method and report a different failure cause instead. // switches to DSDS with two ongoing calls for the phone account to be null in which case, // based on the logic below, we would've completed the future with true and reported a // different failure cause. Now, we perform this early check to ensure the right max // outgoing call restriction error is displayed instead. if (mCallsManager.hasMaximumManagedHoldingCalls(call) && !mCallsManager.canHold(liveCall)) { showErrorDialogForMaxOutgoingCall(call); return CompletableFuture.completedFuture(false); Loading
tests/src/com/android/server/telecom/tests/CallSequencingTests.java +3 −1 Original line number Diff line number Diff line Loading @@ -62,6 +62,7 @@ import com.android.server.telecom.CallState; import com.android.server.telecom.CallsManager; import com.android.server.telecom.ClockProxy; import com.android.server.telecom.ConnectionServiceFocusManager; import com.android.server.telecom.MmiUtils; import com.android.server.telecom.PhoneAccountRegistrar; import com.android.server.telecom.Timeouts; import com.android.server.telecom.callsequencing.CallSequencingController; Loading Loading @@ -104,6 +105,7 @@ public class CallSequencingTests extends TelecomTestCase { @Mock AnomalyReporterAdapter mAnomalyReporter; @Mock Timeouts.Adapter mTimeoutsAdapter; @Mock TelecomMetricsController mMetricsController; @Mock MmiUtils mMmiUtils; @Mock ConnectionServiceFocusManager mConnectionServiceFocusManager; @Mock Call mActiveCall; Loading @@ -117,7 +119,7 @@ public class CallSequencingTests extends TelecomTestCase { super.setUp(); when(mFeatureFlags.enableCallSequencing()).thenReturn(true); mController = new CallSequencingController(mCallsManager, mContext, mClockProxy, mAnomalyReporter, mTimeoutsAdapter, mMetricsController, mFeatureFlags); mAnomalyReporter, mTimeoutsAdapter, mMetricsController, mMmiUtils, mFeatureFlags); when(mActiveCall.getState()).thenReturn(CallState.ACTIVE); when(mRingingCall.getState()).thenReturn(CallState.RINGING); Loading