Merge "CarrierMessagingService: Add gated support for granular errors for SMS flow" into main
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 871cabc..b209d1d 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -825,6 +825,9 @@
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:
@@ -836,10 +839,34 @@
smsResponse,
null /* exception*/)));
break;
- case CarrierMessagingService.SEND_STATUS_ERROR:
- Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService"
- + " failed. "
- + SmsController.formatCrossStackMessageId(tracker.mMessageId));
+ 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,
new AsyncResult(tracker, smsResponse,
new CommandException(CommandException.Error.GENERIC_FAILURE))));
@@ -858,6 +885,55 @@
}
}
+ 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.
*/
@@ -1084,10 +1160,20 @@
+ SmsController.formatCrossStackMessageId(tracker.mMessageId));
}
- int ss = mPhone.getServiceState().getState();
- int error = rilErrorToSmsManagerResult(
- ((CommandException) (ar.exception)).getCommandError(), tracker);
+ 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
@@ -2489,6 +2575,9 @@
public final long mMessageId;
+ // A CarrierMessagingService result code to be returned to the caller.
+ public int mResultCodeFromCarrierMessagingService;
+
private Boolean mIsFromDefaultSmsApplication;
private int mCarrierId;
@@ -2533,6 +2622,7 @@
mCarrierId = carrierId;
mSkipShortCodeDestAddrCheck = skipShortCodeDestAddrCheck;
mUniqueMessageId = uniqueMessageId;
+ mResultCodeFromCarrierMessagingService = CarrierMessagingService.SEND_STATUS_OK;
}
@VisibleForTesting
@@ -2552,6 +2642,7 @@
mCarrierId = 0;
mSkipShortCodeDestAddrCheck = false;
mUniqueMessageId = 0;
+ mResultCodeFromCarrierMessagingService = CarrierMessagingService.SEND_STATUS_OK;
}
public HashMap<String, Object> getData() {
diff --git a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
index 639a2a3..a29de0f 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/gsm/GsmSmsDispatcherTest.java
@@ -70,6 +70,7 @@
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;
@@ -377,23 +378,35 @@
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,
- new Intent(TEST_INTENT)
- .setPackage(TestApplication.getAppContext().getPackageName()),
- PendingIntent.FLAG_MUTABLE);
+ 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) {
@@ -402,15 +415,48 @@
}
assertEquals(true, mReceivedTestIntent);
int resultCode = mTestReceiver.getResultCode();
- assertTrue("Unexpected result code: " + resultCode,
- resultCode == SmsManager.RESULT_ERROR_NONE || resultCode == Activity.RESULT_OK);
- verify(mSimulatedCommandsVerifier, times(0)).sendSMS(anyString(), anyString(),
- any(Message.class));
+ 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);
+ }
+
+ @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
+ @SmallTest
public void testSendSmsByCarrierAppNoResponse() throws Exception {
mockCarrierApp();
// do not mock result, instead reduce the timeout for test