Merge "Handle normal call when satellite is enabled" into udc-dev
diff --git a/res/values/strings.xml b/res/values/strings.xml
index b445cc6..b32b030 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1239,6 +1239,8 @@
     <string name="incall_error_wfc_only_no_wireless_network">Connect to a wireless network to make a call.</string>
     <!-- In-call screen: call failure message displayed in an error dialog when the user is connected to a wireless network, but wifi calling is turned off. [CHAR_LIMIT=NONE] -->
     <string name="incall_error_promote_wfc">Enable Wi-Fi calling to make a call.</string>
+    <!-- In-call screen: call failure message displayed in an error dialog when the satellite modem is on. [CHAR_LIMIT=NONE] -->
+    <string name="incall_error_satellite_enabled">Disable satellite mode to make a call.</string>
 
     <!-- Hint for the button of emergency information -->
     <string name="emergency_information_hint">Emergency information</string>
@@ -1711,6 +1713,8 @@
     <string name="clh_callFailed_simError_txt">Can\'t access SIM card</string>
     <!-- In-call screen: call failure message displayed in an error dialog -->
     <string name="clh_incall_error_out_of_service_txt">Mobile network not available</string>
+    <!-- In-call screen: call failure reason (satellite modem is enabled) -->
+    <string name="clh_callFailed_satelliteEnabled_txt">Satellite mode is on</string>
 
     <!-- See CallFailCause for details on what causes each message -->
     <!-- In-call screen: call failure reason (Cause Number 1) -->
diff --git a/src/com/android/services/telephony/DisconnectCauseUtil.java b/src/com/android/services/telephony/DisconnectCauseUtil.java
index 587ac43..d36f8be 100644
--- a/src/com/android/services/telephony/DisconnectCauseUtil.java
+++ b/src/com/android/services/telephony/DisconnectCauseUtil.java
@@ -232,6 +232,7 @@
             case android.telephony.DisconnectCause.IMS_ACCESS_BLOCKED:
             case android.telephony.DisconnectCause.IMS_SIP_ALTERNATE_EMERGENCY_CALL:
             case android.telephony.DisconnectCause.MEDIA_TIMEOUT:
+            case android.telephony.DisconnectCause.SATELLITE_ENABLED:
                 return DisconnectCause.ERROR;
 
             case android.telephony.DisconnectCause.DIALED_MMI:
@@ -418,6 +419,9 @@
             case android.telephony.DisconnectCause.WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
                 resourceId = R.string.callFailed_wfc_service_not_available_in_this_location;
                 break;
+            case android.telephony.DisconnectCause.SATELLITE_ENABLED:
+                resourceId = R.string.incall_error_satellite_enabled;
+                break;
             default:
                 break;
         }
@@ -599,6 +603,9 @@
                     case android.telephony.DisconnectCause.OUT_OF_SERVICE:
                         resourceId = R.string.clh_incall_error_out_of_service_txt;
                         break;
+                    case android.telephony.DisconnectCause.SATELLITE_ENABLED:
+                        resourceId = R.string.clh_callFailed_satelliteEnabled_txt;
+                        break;
                     default:
                         resourceId = R.string.clh_card_title_call_ended_txt;
                         break;
@@ -822,6 +829,9 @@
             case android.telephony.DisconnectCause.WFC_SERVICE_NOT_AVAILABLE_IN_THIS_LOCATION:
                 resourceId = R.string.callFailed_wfc_service_not_available_in_this_location;
                 break;
+            case android.telephony.DisconnectCause.SATELLITE_ENABLED:
+                resourceId = R.string.incall_error_satellite_enabled;
+                break;
             default:
                 break;
         }
diff --git a/src/com/android/services/telephony/TelephonyConnectionService.java b/src/com/android/services/telephony/TelephonyConnectionService.java
index 18b95e1..16d27b3 100644
--- a/src/com/android/services/telephony/TelephonyConnectionService.java
+++ b/src/com/android/services/telephony/TelephonyConnectionService.java
@@ -87,6 +87,7 @@
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneConnection;
 import com.android.internal.telephony.imsphone.ImsPhoneMmiCode;
+import com.android.internal.telephony.satellite.SatelliteController;
 import com.android.internal.telephony.satellite.SatelliteSOSMessageRecommender;
 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
@@ -227,6 +228,7 @@
     private ImsManager mImsManager = null;
     private DomainSelectionConnection mDomainSelectionConnection;
     private TelephonyConnection mNormalCallConnection;
+    private SatelliteController mSatelliteController;
 
     /**
      * Keeps track of the status of a SIM slot.
@@ -799,6 +801,7 @@
         mIsTtyEnabled = mDeviceState.isTtyModeEnabled(this);
         mDomainSelectionMainExecutor = getApplicationContext().getMainExecutor();
         mDomainSelectionResolver = DomainSelectionResolver.getInstance();
+        mSatelliteController = SatelliteController.getInstance();
 
         IntentFilter intentFilter = new IntentFilter(
                 TelecomManager.ACTION_TTY_PREFERRED_MODE_CHANGED);
@@ -1165,6 +1168,13 @@
             }
 
             if (!isEmergencyNumber) {
+                if (mSatelliteController.isSatelliteEnabled()) {
+                    Log.d(this, "onCreateOutgoingConnection, cannot make call in satellite mode.");
+                    return Connection.createFailedConnection(
+                            mDisconnectCauseFactory.toTelecomDisconnectCause(
+                                    android.telephony.DisconnectCause.SATELLITE_ENABLED,
+                                    "Call failed because satellite modem is enabled."));
+                }
                 final Connection resultConnection = getTelephonyConnection(request, numberToDial,
                         false, handle, phone);
                 if (isAdhocConference) {
@@ -1481,6 +1491,14 @@
             }
         }
 
+        if (!isSatelliteStateValid(isEmergencyNumber)) {
+            Log.d(this, "onCreateOutgoingConnection, cannot make call in satellite mode.");
+            return Connection.createFailedConnection(
+                    mDisconnectCauseFactory.toTelecomDisconnectCause(
+                            android.telephony.DisconnectCause.SATELLITE_ENABLED,
+                            "Call failed because satellite modem is enabled."));
+        }
+
         final boolean isTtyModeEnabled = mDeviceState.isTtyModeEnabled(this);
         if (VideoProfile.isVideo(request.getVideoState()) && isTtyModeEnabled
                 && !isEmergencyNumber) {
@@ -1959,6 +1977,14 @@
         return result;
     }
 
+    private boolean isSatelliteStateValid(boolean isEmergencyNumber) {
+        if (isEmergencyNumber) {
+            return !mSatelliteController.isSatelliteEnabled();
+        } else {
+            return !mSatelliteController.isDemoModeEnabled();
+        }
+    }
+
     private Pair<WeakReference<TelephonyConnection>, Queue<Phone>> makeCachedConnectionPhonePair(
             TelephonyConnection c) {
         Queue<Phone> phones = new LinkedList<>(Arrays.asList(mPhoneFactoryProxy.getPhones()));
diff --git a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
index fadfaaf..90fc0a9 100644
--- a/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
+++ b/tests/src/com/android/services/telephony/TelephonyConnectionServiceTest.java
@@ -99,6 +99,7 @@
 import com.android.internal.telephony.emergency.RadioOnStateListener;
 import com.android.internal.telephony.gsm.SuppServiceNotification;
 import com.android.internal.telephony.imsphone.ImsPhone;
+import com.android.internal.telephony.satellite.SatelliteController;
 import com.android.internal.telephony.satellite.SatelliteSOSMessageRecommender;
 
 import org.junit.After;
@@ -192,7 +193,7 @@
     @Mock TelephonyConnectionService.PhoneNumberUtilsProxy mPhoneNumberUtilsProxy;
     @Mock TelephonyConnectionService.PhoneUtilsProxy mPhoneUtilsProxy;
     @Mock TelephonyConnectionService.DisconnectCauseFactory mDisconnectCauseFactory;
-    @Mock Handler mMockHandler;
+    @Mock SatelliteController mSatelliteController;
     @Mock EmergencyNumberTracker mEmergencyNumberTracker;
     @Mock PhoneSwitcher mPhoneSwitcher;
     @Mock RadioOnHelper mRadioOnHelper;
@@ -205,9 +206,8 @@
     @Mock EmergencyCallDomainSelectionConnection mEmergencyCallDomainSelectionConnection;
     @Mock NormalCallDomainSelectionConnection mNormalCallDomainSelectionConnection;
     @Mock ImsPhone mImsPhone;
-    @Mock
-    private SatelliteSOSMessageRecommender mSatelliteSOSMessageRecommender;
-    private EmergencyStateTracker mEmergencyStateTracker;
+    @Mock private SatelliteSOSMessageRecommender mSatelliteSOSMessageRecommender;
+    @Mock private EmergencyStateTracker mEmergencyStateTracker;
     private Phone mPhone0;
     private Phone mPhone1;
 
@@ -247,16 +247,18 @@
         mTestConnectionService.setPhoneUtilsProxy(mPhoneUtilsProxy);
         mTestConnectionService.setDeviceState(mDeviceState);
         mTestConnectionService.setRadioOnHelper(mRadioOnHelper);
-        doReturn(new DisconnectCause(DisconnectCause.UNKNOWN)).when(mDisconnectCauseFactory)
-                .toTelecomDisconnectCause(anyInt(), any());
-        doReturn(new DisconnectCause(DisconnectCause.UNKNOWN)).when(mDisconnectCauseFactory)
-                .toTelecomDisconnectCause(anyInt(), any(), anyInt());
+        doAnswer(invocation -> DisconnectCauseUtil.toTelecomDisconnectCause(
+                invocation.getArgument(0), invocation.getArgument(1)))
+                .when(mDisconnectCauseFactory).toTelecomDisconnectCause(anyInt(), any());
+        doAnswer(invocation -> DisconnectCauseUtil.toTelecomDisconnectCause(
+                invocation.getArgument(0), invocation.getArgument(1),
+                (int) invocation.getArgument(2)))
+                .when(mDisconnectCauseFactory).toTelecomDisconnectCause(anyInt(), any(), anyInt());
         mTestConnectionService.setDisconnectCauseFactory(mDisconnectCauseFactory);
         mTestConnectionService.onCreate();
         mTestConnectionService.setTelephonyManagerProxy(mTelephonyManagerProxy);
         replaceInstance(TelephonyConnectionService.class, "mDomainSelectionResolver",
                 mTestConnectionService, mDomainSelectionResolver);
-        mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class);
         replaceInstance(TelephonyConnectionService.class, "mEmergencyStateTracker",
                 mTestConnectionService, mEmergencyStateTracker);
         replaceInstance(TelephonyConnectionService.class, "mSatelliteSOSMessageRecommender",
@@ -272,6 +274,8 @@
         doReturn(false).when(mDomainSelectionResolver).isDomainSelectionSupported();
         doReturn(null).when(mDomainSelectionResolver).getDomainSelectionConnection(
                 any(), anyInt(), anyBoolean());
+        replaceInstance(TelephonyConnectionService.class,
+                "mSatelliteController", mTestConnectionService, mSatelliteController);
         mBinderStub = (IConnectionService.Stub) mTestConnectionService.onBind(null);
     }
 
@@ -598,7 +602,7 @@
      */
     @Test
     @SmallTest
-    public void testSlot1HigherCapablity() {
+    public void testSlot1HigherCapability() {
         Phone slot0Phone = makeTestPhone(SLOT_0_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
                 false /*isEmergencyOnly*/);
         Phone slot1Phone = makeTestPhone(SLOT_1_PHONE_ID, ServiceState.STATE_OUT_OF_SERVICE,
@@ -2848,6 +2852,17 @@
                 selectedDomain, dialArgs.intentExtras.getInt(PhoneConstants.EXTRA_DIAL_DOMAIN, -1));
     }
 
+    @Test
+    public void testNormalCallSatelliteEnabled() {
+        setupForCallTest();
+        doReturn(true).when(mSatelliteController).isSatelliteEnabled();
+        mConnection = mTestConnectionService.onCreateOutgoingConnection(PHONE_ACCOUNT_HANDLE_1,
+                createConnectionRequest(PHONE_ACCOUNT_HANDLE_1, "1234", TELECOM_CALL_ID1));
+        DisconnectCause disconnectCause = mConnection.getDisconnectCause();
+        assertEquals(android.telephony.DisconnectCause.SATELLITE_ENABLED,
+                disconnectCause.getTelephonyDisconnectCause());
+    }
+
     private void setupForDialForDomainSelection(Phone mockPhone, int domain, boolean isEmergency) {
         if (isEmergency) {
             doReturn(mEmergencyCallDomainSelectionConnection).when(mDomainSelectionResolver)