Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 64b3ebb7 authored by Jesse Melhuish's avatar Jesse Melhuish
Browse files

CarrierMessagingService: Add gated support for granular errors for SMS

flow

When enabled, result codes from CarrierMessagingService are attached to the SmsTracker so they can be propagated through to final result processing. Those codes are converted to SmsManager codes to return to the caller.

Bug: 326610112
Test: atest GsmSmsDispatcherTest
Flag:
com.android.internal.telephony.flags.temporary_failures_in_carrier_messaging_service

Change-Id: Iee0c5a150c335c4a3deb4a0b67c204b8c54a5df0
parent 35168cf0
Loading
Loading
Loading
Loading
+98 −7
Original line number Diff line number Diff line
@@ -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:
@@ -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,
@@ -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.
     */
@@ -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
@@ -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;
@@ -2533,6 +2622,7 @@ public abstract class SMSDispatcher extends Handler {
            mCarrierId = carrierId;
            mSkipShortCodeDestAddrCheck = skipShortCodeDestAddrCheck;
            mUniqueMessageId = uniqueMessageId;
            mResultCodeFromCarrierMessagingService = CarrierMessagingService.SEND_STATUS_OK;
        }

        @VisibleForTesting
@@ -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() {
+62 −16
Original line number Diff line number Diff line
@@ -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;

@@ -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) {
@@ -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