Loading src/java/com/android/internal/telephony/SMSDispatcher.java +98 −7 Original line number Diff line number Diff line Loading @@ -825,6 +825,9 @@ public abstract class SMSDispatcher extends Handler { SmsResponse smsResponse = new SmsResponse(messageRef, null /* ackPdu */, NO_ERROR_CODE, tracker.mMessageId); if (Flags.temporaryFailuresInCarrierMessagingService()) { tracker.mResultCodeFromCarrierMessagingService = result; } switch (result) { case CarrierMessagingService.SEND_STATUS_OK: Loading @@ -836,8 +839,32 @@ public abstract class SMSDispatcher extends Handler { smsResponse, null /* exception*/))); break; case CarrierMessagingService.SEND_STATUS_ERROR: Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService" case CarrierMessagingService.SEND_STATUS_ERROR: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_GENERIC_FAILURE: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NULL_PDU: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NO_SERVICE: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_LIMIT_EXCEEDED: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_FDN_CHECK_FAILURE: // fall through case CarrierMessagingService .SEND_STATUS_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED: // fall through case CarrierMessagingService .SEND_STATUS_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_REJECT: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_ARGUMENTS: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_STATE: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMS_FORMAT: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_ERROR: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ENCODING_ERROR: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMSC_ADDRESS: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_OPERATION_NOT_ALLOWED: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_CANCELLED: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_REQUEST_NOT_SUPPORTED: // fall through case CarrierMessagingService .SEND_STATUS_RESULT_SMS_BLOCKED_DURING_EMERGENCY: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_SMS_SEND_RETRY_FAILED: // fall through Rlog.d( TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService" + " failed. " + SmsController.formatCrossStackMessageId(tracker.mMessageId)); sendMessage(obtainMessage(EVENT_SEND_SMS_COMPLETE, Loading @@ -858,6 +885,55 @@ public abstract class SMSDispatcher extends Handler { } } private int toSmsManagerResultForSendSms(int carrierMessagingServiceResult) { switch (carrierMessagingServiceResult) { case CarrierMessagingService.SEND_STATUS_OK: return Activity.RESULT_OK; case CarrierMessagingService.SEND_STATUS_ERROR: return SmsManager.RESULT_RIL_GENERIC_ERROR; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_GENERIC_FAILURE: return SmsManager.RESULT_ERROR_GENERIC_FAILURE; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NULL_PDU: return SmsManager.RESULT_ERROR_NULL_PDU; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NO_SERVICE: return SmsManager.RESULT_ERROR_NO_SERVICE; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_LIMIT_EXCEEDED: return SmsManager.RESULT_ERROR_LIMIT_EXCEEDED; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_FDN_CHECK_FAILURE: return SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED: return SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED: return SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED; case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_REJECT: return SmsManager.RESULT_NETWORK_REJECT; case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_ARGUMENTS: return SmsManager.RESULT_INVALID_ARGUMENTS; case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_STATE: return SmsManager.RESULT_INVALID_STATE; case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMS_FORMAT: return SmsManager.RESULT_INVALID_SMS_FORMAT; case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_ERROR: return SmsManager.RESULT_NETWORK_ERROR; case CarrierMessagingService.SEND_STATUS_RESULT_ENCODING_ERROR: return SmsManager.RESULT_ENCODING_ERROR; case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMSC_ADDRESS: return SmsManager.RESULT_INVALID_SMSC_ADDRESS; case CarrierMessagingService.SEND_STATUS_RESULT_OPERATION_NOT_ALLOWED: return SmsManager.RESULT_OPERATION_NOT_ALLOWED; case CarrierMessagingService.SEND_STATUS_RESULT_CANCELLED: return SmsManager.RESULT_CANCELLED; case CarrierMessagingService.SEND_STATUS_RESULT_REQUEST_NOT_SUPPORTED: return SmsManager.RESULT_REQUEST_NOT_SUPPORTED; case CarrierMessagingService.SEND_STATUS_RESULT_SMS_BLOCKED_DURING_EMERGENCY: return SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY; case CarrierMessagingService.SEND_STATUS_RESULT_SMS_SEND_RETRY_FAILED: return SmsManager.RESULT_SMS_SEND_RETRY_FAILED; default: return SmsManager.RESULT_ERROR_GENERIC_FAILURE; } } /** * Use the carrier messaging service to send a multipart text SMS. */ Loading Loading @@ -1084,10 +1160,20 @@ public abstract class SMSDispatcher extends Handler { + SmsController.formatCrossStackMessageId(tracker.mMessageId)); } int ss = mPhone.getServiceState().getState(); int error = rilErrorToSmsManagerResult( int error; if (Flags.temporaryFailuresInCarrierMessagingService() && tracker.mResultCodeFromCarrierMessagingService != CarrierMessagingService.SEND_STATUS_OK) { error = toSmsManagerResultForSendSms( tracker.mResultCodeFromCarrierMessagingService); } else { error = rilErrorToSmsManagerResult( ((CommandException) (ar.exception)).getCommandError(), tracker); } int ss = mPhone.getServiceState().getState(); if (tracker.mImsRetry > 0 && ss != ServiceState.STATE_IN_SERVICE) { // This is retry after failure over IMS but voice is not available. // Set retry to max allowed, so no retry is sent and cause Loading Loading @@ -2489,6 +2575,9 @@ public abstract class SMSDispatcher extends Handler { public final long mMessageId; // A CarrierMessagingService result code to be returned to the caller. public int mResultCodeFromCarrierMessagingService; private Boolean mIsFromDefaultSmsApplication; private int mCarrierId; Loading Loading @@ -2533,6 +2622,7 @@ public abstract class SMSDispatcher extends Handler { mCarrierId = carrierId; mSkipShortCodeDestAddrCheck = skipShortCodeDestAddrCheck; mUniqueMessageId = uniqueMessageId; mResultCodeFromCarrierMessagingService = CarrierMessagingService.SEND_STATUS_OK; } @VisibleForTesting Loading @@ -2552,6 +2642,7 @@ public abstract class SMSDispatcher extends Handler { mCarrierId = 0; mSkipShortCodeDestAddrCheck = false; mUniqueMessageId = 0; mResultCodeFromCarrierMessagingService = CarrierMessagingService.SEND_STATUS_OK; } public HashMap<String, Object> getData() { Loading src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java +16 −10 Original line number Diff line number Diff line Loading @@ -109,8 +109,6 @@ public class EmergencyStateTracker { * from the modem. */ private static final int DEFAULT_DATA_SWITCH_TIMEOUT_MS = 1 * 1000; @VisibleForTesting public static final int DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS = 3 * 1000; /** Default value for if Emergency Callback Mode is supported. */ private static final boolean DEFAULT_EMERGENCY_CALLBACK_MODE_SUPPORTED = true; /** Default Emergency Callback Mode exit timeout value. */ Loading Loading @@ -142,6 +140,7 @@ public class EmergencyStateTracker { private final CarrierConfigManager mConfigManager; private final Handler mHandler; private final boolean mIsSuplDdsSwitchRequiredForEmergencyCall; private final int mWaitForInServiceTimeoutMs; private final PowerManager.WakeLock mWakeLock; private RadioOnHelper mRadioOnHelper; @EmergencyConstants.EmergencyMode Loading Loading @@ -474,10 +473,10 @@ public class EmergencyStateTracker { * @param featureFlags The telephony feature flags. */ public static void make(Context context, boolean isSuplDdsSwitchRequiredForEmergencyCall, @NonNull FeatureFlags featureFlags) { int waitForInServiceTimeout, @NonNull FeatureFlags featureFlags) { if (INSTANCE == null) { INSTANCE = new EmergencyStateTracker(context, Looper.myLooper(), isSuplDdsSwitchRequiredForEmergencyCall, featureFlags); isSuplDdsSwitchRequiredForEmergencyCall, waitForInServiceTimeout, featureFlags); } } Loading @@ -497,11 +496,13 @@ public class EmergencyStateTracker { * Initializes EmergencyStateTracker. */ private EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall, @NonNull FeatureFlags featureFlags) { boolean isSuplDdsSwitchRequiredForEmergencyCall, int waitForInServiceTimeout, @NonNull FeatureFlags featureFlags) { mEcmExitTimeoutMs = DEFAULT_ECM_EXIT_TIMEOUT_MS; mContext = context; mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; mWaitForInServiceTimeoutMs = waitForInServiceTimeout; mFeatureFlags = featureFlags; PowerManager pm = context.getSystemService(PowerManager.class); mWakeLock = (pm != null) ? pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Loading Loading @@ -534,6 +535,10 @@ public class EmergencyStateTracker { * @param looper The {@link Looper} of the application. * @param isSuplDdsSwitchRequiredForEmergencyCall Whether gnss supl requires default data for * emergency call. * @param waitForInServiceTimeout The timeout duration how long does it wait for * modem to get in-service state when emergency * call is dialed in airplane mode before * starting the emergency call. * @param phoneFactoryProxy The {@link PhoneFactoryProxy} to be injected. * @param phoneSwitcherProxy The {@link PhoneSwitcherProxy} to be injected. * @param telephonyManagerProxy The {@link TelephonyManagerProxy} to be Loading @@ -543,12 +548,14 @@ public class EmergencyStateTracker { */ @VisibleForTesting public EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall, PhoneFactoryProxy phoneFactoryProxy, PhoneSwitcherProxy phoneSwitcherProxy, TelephonyManagerProxy telephonyManagerProxy, RadioOnHelper radioOnHelper, long ecmExitTimeoutMs, FeatureFlags featureFlags) { boolean isSuplDdsSwitchRequiredForEmergencyCall, int waitForInServiceTimeout, PhoneFactoryProxy phoneFactoryProxy, PhoneSwitcherProxy phoneSwitcherProxy, TelephonyManagerProxy telephonyManagerProxy, RadioOnHelper radioOnHelper, long ecmExitTimeoutMs, FeatureFlags featureFlags) { mContext = context; mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; mWaitForInServiceTimeoutMs = waitForInServiceTimeout; mPhoneFactoryProxy = phoneFactoryProxy; mPhoneSwitcherProxy = phoneSwitcherProxy; mTelephonyManagerProxy = telephonyManagerProxy; Loading Loading @@ -1689,8 +1696,7 @@ public class EmergencyStateTracker { final Phone phoneForEmergency = phone; final android.telecom.Connection expectedConnection = mOngoingConnection; final int waitForInServiceTimeout = needToTurnOnRadio ? DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS : 0; final int waitForInServiceTimeout = needToTurnOnRadio ? mWaitForInServiceTimeoutMs : 0; Rlog.i(TAG, "turnOnRadioAndSwitchDds: timeout=" + waitForInServiceTimeout); mRadioOnHelper.triggerRadioOnAndListen(new RadioOnStateListener.Callback() { @Override Loading src/java/com/android/internal/telephony/satellite/SatelliteController.java +8 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.stream.Collectors; import com.android.internal.R; /** * Satellite controller is the backend service of Loading Loading @@ -6395,6 +6396,13 @@ public class SatelliteController extends Handler { */ private void updateSatelliteSystemNotification(int subId, @CARRIER_ROAMING_NTN_CONNECT_TYPE int carrierRoamingNtnConnectType, boolean visible) { boolean notifySatelliteAvailabilityEnabled = mContext.getResources().getBoolean(R.bool.config_satellite_should_notify_availability); if (!mFeatureFlags.carrierRoamingNbIotNtn() || !notifySatelliteAvailabilityEnabled) { plogd("updateSatelliteSystemNotification: satellite notifications are not enabled."); return; } plogd("updateSatelliteSystemNotification subId=" + subId + ", carrierRoamingNtnConnectType=" + SatelliteServiceUtils.carrierRoamingNtnConnectTypeToString( carrierRoamingNtnConnectType) + ", visible=" + visible); Loading tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java +12 −9 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import static android.telephony.TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS; import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_CALLBACK; import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WLAN; import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WWAN; import static com.android.internal.telephony.emergency.EmergencyStateTracker.DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading Loading @@ -106,6 +105,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { private static final String TEST_SMS_ID = "1111"; private static final String TEST_SMS_ID_2 = "2222"; private static final int TEST_ECM_EXIT_TIMEOUT_MS = 500; private static final int TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS = 3000; private static final EmergencyRegistrationResult E_REG_RESULT = new EmergencyRegistrationResult( EUTRAN, REGISTRATION_STATE_HOME, DOMAIN_CS_PS, true, true, 0, 1, "001", "01", "US"); Loading Loading @@ -139,7 +139,8 @@ public class EmergencyStateTrackerTest extends TelephonyTest { EmergencyStateTracker.getInstance(); }); EmergencyStateTracker.make(mContext, true, mFeatureFlags); EmergencyStateTracker .make(mContext, true, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, mFeatureFlags); assertNotNull(EmergencyStateTracker.getInstance()); } Loading @@ -147,7 +148,8 @@ public class EmergencyStateTrackerTest extends TelephonyTest { @Test @SmallTest public void getInstance_returnsSameInstance() { EmergencyStateTracker.make(mContext, true, mFeatureFlags); EmergencyStateTracker .make(mContext, true, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, mFeatureFlags); EmergencyStateTracker instance1 = EmergencyStateTracker.getInstance(); EmergencyStateTracker instance2 = EmergencyStateTracker.getInstance(); Loading Loading @@ -184,7 +186,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor .forClass(RadioOnStateListener.Callback.class); verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone), eq(false), eq(DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); eq(false), eq(TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); // isOkToCall() should return true when IN_SERVICE state assertFalse(callback.getValue() .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); Loading Loading @@ -243,7 +245,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor .forClass(RadioOnStateListener.Callback.class); verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone), eq(false), eq(DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); eq(false), eq(TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); // onTimeout should return true when radion on assertFalse(callback.getValue() .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); Loading Loading @@ -292,7 +294,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor .forClass(RadioOnStateListener.Callback.class); verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone), eq(false), eq(DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); eq(false), eq(TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); // Hangup the call testConnection.setDisconnected(null); Loading Loading @@ -330,7 +332,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor .forClass(RadioOnStateListener.Callback.class); verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone), eq(false), eq(DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); eq(false), eq(TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); // Verify future completes with DisconnectCause.POWER_OFF if radio not ready CompletableFuture<Void> unused = future.thenAccept((result) -> { assertEquals((Integer) result, (Integer) DisconnectCause.POWER_OFF); Loading Loading @@ -3411,8 +3413,9 @@ public class EmergencyStateTrackerTest extends TelephonyTest { doNothing().when(mPhoneSwitcher).overrideDefaultDataForEmergency( anyInt(), anyInt(), any()); return new EmergencyStateTracker(mContext, mTestableLooper.getLooper(), isSuplDdsSwitchRequiredForEmergencyCall, mPhoneFactoryProxy, mPhoneSwitcherProxy, mTelephonyManagerProxy, mRadioOnHelper, TEST_ECM_EXIT_TIMEOUT_MS, mFeatureFlags); isSuplDdsSwitchRequiredForEmergencyCall, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, mPhoneFactoryProxy, mPhoneSwitcherProxy, mTelephonyManagerProxy, mRadioOnHelper, TEST_ECM_EXIT_TIMEOUT_MS, mFeatureFlags); } private Phone setupTestPhoneForEmergencyCall(boolean isRoaming, boolean isRadioOn) { Loading tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java +62 −16 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ import com.android.internal.telephony.SmsDispatchersController; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.TelephonyTestUtils; import com.android.internal.telephony.TestApplication; import com.android.internal.telephony.flags.Flags; import com.android.internal.telephony.uicc.IccUtils; import com.android.internal.telephony.uicc.IsimUiccRecords; Loading Loading @@ -377,23 +378,35 @@ public class GsmSmsDispatcherTest extends TelephonyTest { any(ICarrierMessagingCallback.class)); } @Test @SmallTest @Ignore("b/256282780") public void testSendSmsByCarrierApp() throws Exception { private int sendSmsWithCarrierAppResponse(int carrierAppResultCode) throws Exception { mockCarrierApp(); mockCarrierAppStubResults(CarrierMessagingService.SEND_STATUS_OK, mICarrierAppMessagingService, true); mockCarrierAppStubResults(carrierAppResultCode, mICarrierAppMessagingService, true); registerTestIntentReceiver(); PendingIntent pendingIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0, PendingIntent pendingIntent = PendingIntent.getBroadcast( TestApplication.getAppContext(), 0, new Intent(TEST_INTENT) .setPackage(TestApplication.getAppContext().getPackageName()), PendingIntent.FLAG_MUTABLE); mReceivedTestIntent = false; mGsmSmsDispatcher.sendText("6501002000", "121" /*scAddr*/, "test sms", pendingIntent, null, null, null, mCallingUserId, false, -1, false, -1, false, 0L); mGsmSmsDispatcher.sendText( "6501002000", "121" /*scAddr*/, "test sms", pendingIntent, null, null, null, mCallingUserId, false, -1, false, -1, false, 0L); processAllMessages(); synchronized (mLock) { if (!mReceivedTestIntent) { Loading @@ -402,11 +415,44 @@ public class GsmSmsDispatcherTest extends TelephonyTest { } assertEquals(true, mReceivedTestIntent); int resultCode = mTestReceiver.getResultCode(); assertTrue("Unexpected result code: " + resultCode, verify(mSimulatedCommandsVerifier, times(0)) .sendSMS(anyString(), anyString(), any(Message.class)); return resultCode; } } @Test @SmallTest @Ignore("b/256282780") public void testSendSmsByCarrierApp() throws Exception { int resultCode = sendSmsWithCarrierAppResponse(CarrierMessagingService.SEND_STATUS_OK); assertTrue( "Unexpected result code: " + resultCode, resultCode == SmsManager.RESULT_ERROR_NONE || resultCode == Activity.RESULT_OK); verify(mSimulatedCommandsVerifier, times(0)).sendSMS(anyString(), anyString(), any(Message.class)); } @Test @SmallTest public void testSendSmsByCarrierApp_PermanentFailure() throws Exception { int resultCode = sendSmsWithCarrierAppResponse(CarrierMessagingService.SEND_STATUS_ERROR); assertTrue( "Unexpected result code: " + resultCode, resultCode == SmsManager.RESULT_RIL_GENERIC_ERROR); } @Test @SmallTest public void testSendSmsByCarrierApp_FailureWithReason() throws Exception { if (!Flags.temporaryFailuresInCarrierMessagingService()) { return; } doReturn(true).when(mFeatureFlags).temporaryFailuresInCarrierMessagingService(); int resultCode = sendSmsWithCarrierAppResponse( CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NO_SERVICE); assertTrue( "Unexpected result code: " + resultCode, resultCode == SmsManager.RESULT_ERROR_NO_SERVICE); } @Test Loading Loading
src/java/com/android/internal/telephony/SMSDispatcher.java +98 −7 Original line number Diff line number Diff line Loading @@ -825,6 +825,9 @@ public abstract class SMSDispatcher extends Handler { SmsResponse smsResponse = new SmsResponse(messageRef, null /* ackPdu */, NO_ERROR_CODE, tracker.mMessageId); if (Flags.temporaryFailuresInCarrierMessagingService()) { tracker.mResultCodeFromCarrierMessagingService = result; } switch (result) { case CarrierMessagingService.SEND_STATUS_OK: Loading @@ -836,8 +839,32 @@ public abstract class SMSDispatcher extends Handler { smsResponse, null /* exception*/))); break; case CarrierMessagingService.SEND_STATUS_ERROR: Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService" case CarrierMessagingService.SEND_STATUS_ERROR: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_GENERIC_FAILURE: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NULL_PDU: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NO_SERVICE: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_LIMIT_EXCEEDED: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_FDN_CHECK_FAILURE: // fall through case CarrierMessagingService .SEND_STATUS_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED: // fall through case CarrierMessagingService .SEND_STATUS_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_REJECT: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_ARGUMENTS: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_STATE: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMS_FORMAT: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_ERROR: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_ENCODING_ERROR: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMSC_ADDRESS: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_OPERATION_NOT_ALLOWED: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_CANCELLED: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_REQUEST_NOT_SUPPORTED: // fall through case CarrierMessagingService .SEND_STATUS_RESULT_SMS_BLOCKED_DURING_EMERGENCY: // fall through case CarrierMessagingService.SEND_STATUS_RESULT_SMS_SEND_RETRY_FAILED: // fall through Rlog.d( TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService" + " failed. " + SmsController.formatCrossStackMessageId(tracker.mMessageId)); sendMessage(obtainMessage(EVENT_SEND_SMS_COMPLETE, Loading @@ -858,6 +885,55 @@ public abstract class SMSDispatcher extends Handler { } } private int toSmsManagerResultForSendSms(int carrierMessagingServiceResult) { switch (carrierMessagingServiceResult) { case CarrierMessagingService.SEND_STATUS_OK: return Activity.RESULT_OK; case CarrierMessagingService.SEND_STATUS_ERROR: return SmsManager.RESULT_RIL_GENERIC_ERROR; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_GENERIC_FAILURE: return SmsManager.RESULT_ERROR_GENERIC_FAILURE; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NULL_PDU: return SmsManager.RESULT_ERROR_NULL_PDU; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NO_SERVICE: return SmsManager.RESULT_ERROR_NO_SERVICE; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_LIMIT_EXCEEDED: return SmsManager.RESULT_ERROR_LIMIT_EXCEEDED; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_FDN_CHECK_FAILURE: return SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_SHORT_CODE_NOT_ALLOWED: return SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED; case CarrierMessagingService.SEND_STATUS_RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED: return SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED; case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_REJECT: return SmsManager.RESULT_NETWORK_REJECT; case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_ARGUMENTS: return SmsManager.RESULT_INVALID_ARGUMENTS; case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_STATE: return SmsManager.RESULT_INVALID_STATE; case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMS_FORMAT: return SmsManager.RESULT_INVALID_SMS_FORMAT; case CarrierMessagingService.SEND_STATUS_RESULT_NETWORK_ERROR: return SmsManager.RESULT_NETWORK_ERROR; case CarrierMessagingService.SEND_STATUS_RESULT_ENCODING_ERROR: return SmsManager.RESULT_ENCODING_ERROR; case CarrierMessagingService.SEND_STATUS_RESULT_INVALID_SMSC_ADDRESS: return SmsManager.RESULT_INVALID_SMSC_ADDRESS; case CarrierMessagingService.SEND_STATUS_RESULT_OPERATION_NOT_ALLOWED: return SmsManager.RESULT_OPERATION_NOT_ALLOWED; case CarrierMessagingService.SEND_STATUS_RESULT_CANCELLED: return SmsManager.RESULT_CANCELLED; case CarrierMessagingService.SEND_STATUS_RESULT_REQUEST_NOT_SUPPORTED: return SmsManager.RESULT_REQUEST_NOT_SUPPORTED; case CarrierMessagingService.SEND_STATUS_RESULT_SMS_BLOCKED_DURING_EMERGENCY: return SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY; case CarrierMessagingService.SEND_STATUS_RESULT_SMS_SEND_RETRY_FAILED: return SmsManager.RESULT_SMS_SEND_RETRY_FAILED; default: return SmsManager.RESULT_ERROR_GENERIC_FAILURE; } } /** * Use the carrier messaging service to send a multipart text SMS. */ Loading Loading @@ -1084,10 +1160,20 @@ public abstract class SMSDispatcher extends Handler { + SmsController.formatCrossStackMessageId(tracker.mMessageId)); } int ss = mPhone.getServiceState().getState(); int error = rilErrorToSmsManagerResult( int error; if (Flags.temporaryFailuresInCarrierMessagingService() && tracker.mResultCodeFromCarrierMessagingService != CarrierMessagingService.SEND_STATUS_OK) { error = toSmsManagerResultForSendSms( tracker.mResultCodeFromCarrierMessagingService); } else { error = rilErrorToSmsManagerResult( ((CommandException) (ar.exception)).getCommandError(), tracker); } int ss = mPhone.getServiceState().getState(); if (tracker.mImsRetry > 0 && ss != ServiceState.STATE_IN_SERVICE) { // This is retry after failure over IMS but voice is not available. // Set retry to max allowed, so no retry is sent and cause Loading Loading @@ -2489,6 +2575,9 @@ public abstract class SMSDispatcher extends Handler { public final long mMessageId; // A CarrierMessagingService result code to be returned to the caller. public int mResultCodeFromCarrierMessagingService; private Boolean mIsFromDefaultSmsApplication; private int mCarrierId; Loading Loading @@ -2533,6 +2622,7 @@ public abstract class SMSDispatcher extends Handler { mCarrierId = carrierId; mSkipShortCodeDestAddrCheck = skipShortCodeDestAddrCheck; mUniqueMessageId = uniqueMessageId; mResultCodeFromCarrierMessagingService = CarrierMessagingService.SEND_STATUS_OK; } @VisibleForTesting Loading @@ -2552,6 +2642,7 @@ public abstract class SMSDispatcher extends Handler { mCarrierId = 0; mSkipShortCodeDestAddrCheck = false; mUniqueMessageId = 0; mResultCodeFromCarrierMessagingService = CarrierMessagingService.SEND_STATUS_OK; } public HashMap<String, Object> getData() { Loading
src/java/com/android/internal/telephony/emergency/EmergencyStateTracker.java +16 −10 Original line number Diff line number Diff line Loading @@ -109,8 +109,6 @@ public class EmergencyStateTracker { * from the modem. */ private static final int DEFAULT_DATA_SWITCH_TIMEOUT_MS = 1 * 1000; @VisibleForTesting public static final int DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS = 3 * 1000; /** Default value for if Emergency Callback Mode is supported. */ private static final boolean DEFAULT_EMERGENCY_CALLBACK_MODE_SUPPORTED = true; /** Default Emergency Callback Mode exit timeout value. */ Loading Loading @@ -142,6 +140,7 @@ public class EmergencyStateTracker { private final CarrierConfigManager mConfigManager; private final Handler mHandler; private final boolean mIsSuplDdsSwitchRequiredForEmergencyCall; private final int mWaitForInServiceTimeoutMs; private final PowerManager.WakeLock mWakeLock; private RadioOnHelper mRadioOnHelper; @EmergencyConstants.EmergencyMode Loading Loading @@ -474,10 +473,10 @@ public class EmergencyStateTracker { * @param featureFlags The telephony feature flags. */ public static void make(Context context, boolean isSuplDdsSwitchRequiredForEmergencyCall, @NonNull FeatureFlags featureFlags) { int waitForInServiceTimeout, @NonNull FeatureFlags featureFlags) { if (INSTANCE == null) { INSTANCE = new EmergencyStateTracker(context, Looper.myLooper(), isSuplDdsSwitchRequiredForEmergencyCall, featureFlags); isSuplDdsSwitchRequiredForEmergencyCall, waitForInServiceTimeout, featureFlags); } } Loading @@ -497,11 +496,13 @@ public class EmergencyStateTracker { * Initializes EmergencyStateTracker. */ private EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall, @NonNull FeatureFlags featureFlags) { boolean isSuplDdsSwitchRequiredForEmergencyCall, int waitForInServiceTimeout, @NonNull FeatureFlags featureFlags) { mEcmExitTimeoutMs = DEFAULT_ECM_EXIT_TIMEOUT_MS; mContext = context; mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; mWaitForInServiceTimeoutMs = waitForInServiceTimeout; mFeatureFlags = featureFlags; PowerManager pm = context.getSystemService(PowerManager.class); mWakeLock = (pm != null) ? pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, Loading Loading @@ -534,6 +535,10 @@ public class EmergencyStateTracker { * @param looper The {@link Looper} of the application. * @param isSuplDdsSwitchRequiredForEmergencyCall Whether gnss supl requires default data for * emergency call. * @param waitForInServiceTimeout The timeout duration how long does it wait for * modem to get in-service state when emergency * call is dialed in airplane mode before * starting the emergency call. * @param phoneFactoryProxy The {@link PhoneFactoryProxy} to be injected. * @param phoneSwitcherProxy The {@link PhoneSwitcherProxy} to be injected. * @param telephonyManagerProxy The {@link TelephonyManagerProxy} to be Loading @@ -543,12 +548,14 @@ public class EmergencyStateTracker { */ @VisibleForTesting public EmergencyStateTracker(Context context, Looper looper, boolean isSuplDdsSwitchRequiredForEmergencyCall, PhoneFactoryProxy phoneFactoryProxy, PhoneSwitcherProxy phoneSwitcherProxy, TelephonyManagerProxy telephonyManagerProxy, RadioOnHelper radioOnHelper, long ecmExitTimeoutMs, FeatureFlags featureFlags) { boolean isSuplDdsSwitchRequiredForEmergencyCall, int waitForInServiceTimeout, PhoneFactoryProxy phoneFactoryProxy, PhoneSwitcherProxy phoneSwitcherProxy, TelephonyManagerProxy telephonyManagerProxy, RadioOnHelper radioOnHelper, long ecmExitTimeoutMs, FeatureFlags featureFlags) { mContext = context; mHandler = new MyHandler(looper); mIsSuplDdsSwitchRequiredForEmergencyCall = isSuplDdsSwitchRequiredForEmergencyCall; mWaitForInServiceTimeoutMs = waitForInServiceTimeout; mPhoneFactoryProxy = phoneFactoryProxy; mPhoneSwitcherProxy = phoneSwitcherProxy; mTelephonyManagerProxy = telephonyManagerProxy; Loading Loading @@ -1689,8 +1696,7 @@ public class EmergencyStateTracker { final Phone phoneForEmergency = phone; final android.telecom.Connection expectedConnection = mOngoingConnection; final int waitForInServiceTimeout = needToTurnOnRadio ? DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS : 0; final int waitForInServiceTimeout = needToTurnOnRadio ? mWaitForInServiceTimeoutMs : 0; Rlog.i(TAG, "turnOnRadioAndSwitchDds: timeout=" + waitForInServiceTimeout); mRadioOnHelper.triggerRadioOnAndListen(new RadioOnStateListener.Callback() { @Override Loading
src/java/com/android/internal/telephony/satellite/SatelliteController.java +8 −0 Original line number Diff line number Diff line Loading @@ -193,6 +193,7 @@ import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; import java.util.function.Consumer; import java.util.stream.Collectors; import com.android.internal.R; /** * Satellite controller is the backend service of Loading Loading @@ -6395,6 +6396,13 @@ public class SatelliteController extends Handler { */ private void updateSatelliteSystemNotification(int subId, @CARRIER_ROAMING_NTN_CONNECT_TYPE int carrierRoamingNtnConnectType, boolean visible) { boolean notifySatelliteAvailabilityEnabled = mContext.getResources().getBoolean(R.bool.config_satellite_should_notify_availability); if (!mFeatureFlags.carrierRoamingNbIotNtn() || !notifySatelliteAvailabilityEnabled) { plogd("updateSatelliteSystemNotification: satellite notifications are not enabled."); return; } plogd("updateSatelliteSystemNotification subId=" + subId + ", carrierRoamingNtnConnectType=" + SatelliteServiceUtils.carrierRoamingNtnConnectTypeToString( carrierRoamingNtnConnectType) + ", visible=" + visible); Loading
tests/telephonytests/src/com/android/internal/telephony/emergency/EmergencyStateTrackerTest.java +12 −9 Original line number Diff line number Diff line Loading @@ -27,7 +27,6 @@ import static android.telephony.TelephonyManager.EMERGENCY_CALLBACK_MODE_SMS; import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_CALLBACK; import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WLAN; import static com.android.internal.telephony.emergency.EmergencyConstants.MODE_EMERGENCY_WWAN; import static com.android.internal.telephony.emergency.EmergencyStateTracker.DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; Loading Loading @@ -106,6 +105,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { private static final String TEST_SMS_ID = "1111"; private static final String TEST_SMS_ID_2 = "2222"; private static final int TEST_ECM_EXIT_TIMEOUT_MS = 500; private static final int TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS = 3000; private static final EmergencyRegistrationResult E_REG_RESULT = new EmergencyRegistrationResult( EUTRAN, REGISTRATION_STATE_HOME, DOMAIN_CS_PS, true, true, 0, 1, "001", "01", "US"); Loading Loading @@ -139,7 +139,8 @@ public class EmergencyStateTrackerTest extends TelephonyTest { EmergencyStateTracker.getInstance(); }); EmergencyStateTracker.make(mContext, true, mFeatureFlags); EmergencyStateTracker .make(mContext, true, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, mFeatureFlags); assertNotNull(EmergencyStateTracker.getInstance()); } Loading @@ -147,7 +148,8 @@ public class EmergencyStateTrackerTest extends TelephonyTest { @Test @SmallTest public void getInstance_returnsSameInstance() { EmergencyStateTracker.make(mContext, true, mFeatureFlags); EmergencyStateTracker .make(mContext, true, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, mFeatureFlags); EmergencyStateTracker instance1 = EmergencyStateTracker.getInstance(); EmergencyStateTracker instance2 = EmergencyStateTracker.getInstance(); Loading Loading @@ -184,7 +186,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor .forClass(RadioOnStateListener.Callback.class); verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone), eq(false), eq(DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); eq(false), eq(TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); // isOkToCall() should return true when IN_SERVICE state assertFalse(callback.getValue() .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); Loading Loading @@ -243,7 +245,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor .forClass(RadioOnStateListener.Callback.class); verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone), eq(false), eq(DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); eq(false), eq(TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); // onTimeout should return true when radion on assertFalse(callback.getValue() .isOkToCall(testPhone, ServiceState.STATE_OUT_OF_SERVICE, false)); Loading Loading @@ -292,7 +294,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor .forClass(RadioOnStateListener.Callback.class); verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone), eq(false), eq(DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); eq(false), eq(TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); // Hangup the call testConnection.setDisconnected(null); Loading Loading @@ -330,7 +332,7 @@ public class EmergencyStateTrackerTest extends TelephonyTest { ArgumentCaptor<RadioOnStateListener.Callback> callback = ArgumentCaptor .forClass(RadioOnStateListener.Callback.class); verify(mRadioOnHelper).triggerRadioOnAndListen(callback.capture(), eq(true), eq(testPhone), eq(false), eq(DEFAULT_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); eq(false), eq(TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS)); // Verify future completes with DisconnectCause.POWER_OFF if radio not ready CompletableFuture<Void> unused = future.thenAccept((result) -> { assertEquals((Integer) result, (Integer) DisconnectCause.POWER_OFF); Loading Loading @@ -3411,8 +3413,9 @@ public class EmergencyStateTrackerTest extends TelephonyTest { doNothing().when(mPhoneSwitcher).overrideDefaultDataForEmergency( anyInt(), anyInt(), any()); return new EmergencyStateTracker(mContext, mTestableLooper.getLooper(), isSuplDdsSwitchRequiredForEmergencyCall, mPhoneFactoryProxy, mPhoneSwitcherProxy, mTelephonyManagerProxy, mRadioOnHelper, TEST_ECM_EXIT_TIMEOUT_MS, mFeatureFlags); isSuplDdsSwitchRequiredForEmergencyCall, TEST_WAIT_FOR_IN_SERVICE_TIMEOUT_MS, mPhoneFactoryProxy, mPhoneSwitcherProxy, mTelephonyManagerProxy, mRadioOnHelper, TEST_ECM_EXIT_TIMEOUT_MS, mFeatureFlags); } private Phone setupTestPhoneForEmergencyCall(boolean isRoaming, boolean isRadioOn) { Loading
tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java +62 −16 Original line number Diff line number Diff line Loading @@ -70,6 +70,7 @@ import com.android.internal.telephony.SmsDispatchersController; import com.android.internal.telephony.TelephonyTest; import com.android.internal.telephony.TelephonyTestUtils; import com.android.internal.telephony.TestApplication; import com.android.internal.telephony.flags.Flags; import com.android.internal.telephony.uicc.IccUtils; import com.android.internal.telephony.uicc.IsimUiccRecords; Loading Loading @@ -377,23 +378,35 @@ public class GsmSmsDispatcherTest extends TelephonyTest { any(ICarrierMessagingCallback.class)); } @Test @SmallTest @Ignore("b/256282780") public void testSendSmsByCarrierApp() throws Exception { private int sendSmsWithCarrierAppResponse(int carrierAppResultCode) throws Exception { mockCarrierApp(); mockCarrierAppStubResults(CarrierMessagingService.SEND_STATUS_OK, mICarrierAppMessagingService, true); mockCarrierAppStubResults(carrierAppResultCode, mICarrierAppMessagingService, true); registerTestIntentReceiver(); PendingIntent pendingIntent = PendingIntent.getBroadcast(TestApplication.getAppContext(), 0, PendingIntent pendingIntent = PendingIntent.getBroadcast( TestApplication.getAppContext(), 0, new Intent(TEST_INTENT) .setPackage(TestApplication.getAppContext().getPackageName()), PendingIntent.FLAG_MUTABLE); mReceivedTestIntent = false; mGsmSmsDispatcher.sendText("6501002000", "121" /*scAddr*/, "test sms", pendingIntent, null, null, null, mCallingUserId, false, -1, false, -1, false, 0L); mGsmSmsDispatcher.sendText( "6501002000", "121" /*scAddr*/, "test sms", pendingIntent, null, null, null, mCallingUserId, false, -1, false, -1, false, 0L); processAllMessages(); synchronized (mLock) { if (!mReceivedTestIntent) { Loading @@ -402,11 +415,44 @@ public class GsmSmsDispatcherTest extends TelephonyTest { } assertEquals(true, mReceivedTestIntent); int resultCode = mTestReceiver.getResultCode(); assertTrue("Unexpected result code: " + resultCode, verify(mSimulatedCommandsVerifier, times(0)) .sendSMS(anyString(), anyString(), any(Message.class)); return resultCode; } } @Test @SmallTest @Ignore("b/256282780") public void testSendSmsByCarrierApp() throws Exception { int resultCode = sendSmsWithCarrierAppResponse(CarrierMessagingService.SEND_STATUS_OK); assertTrue( "Unexpected result code: " + resultCode, resultCode == SmsManager.RESULT_ERROR_NONE || resultCode == Activity.RESULT_OK); verify(mSimulatedCommandsVerifier, times(0)).sendSMS(anyString(), anyString(), any(Message.class)); } @Test @SmallTest public void testSendSmsByCarrierApp_PermanentFailure() throws Exception { int resultCode = sendSmsWithCarrierAppResponse(CarrierMessagingService.SEND_STATUS_ERROR); assertTrue( "Unexpected result code: " + resultCode, resultCode == SmsManager.RESULT_RIL_GENERIC_ERROR); } @Test @SmallTest public void testSendSmsByCarrierApp_FailureWithReason() throws Exception { if (!Flags.temporaryFailuresInCarrierMessagingService()) { return; } doReturn(true).when(mFeatureFlags).temporaryFailuresInCarrierMessagingService(); int resultCode = sendSmsWithCarrierAppResponse( CarrierMessagingService.SEND_STATUS_RESULT_ERROR_NO_SERVICE); assertTrue( "Unexpected result code: " + resultCode, resultCode == SmsManager.RESULT_ERROR_NO_SERVICE); } @Test Loading