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

Commit 5f505ad7 authored by Shashank Kumar's avatar Shashank Kumar Committed by Android (Google) Code Review
Browse files

Merge "[SMSoIP] Moved TP-MR to a SmsDispatchersController" into main

parents 2a3b6308 c1eba386
Loading
Loading
Loading
Loading
+10 −10
Original line number Original line Diff line number Diff line
@@ -235,9 +235,6 @@ public abstract class SMSDispatcher extends Handler {
    @VisibleForTesting
    @VisibleForTesting
    public int mCarrierMessagingTimeout = 10 * 60 * 1000; //10 minutes
    public int mCarrierMessagingTimeout = 10 * 60 * 1000; //10 minutes


    /** Used for storing last TP - Message Reference used*/
    private int mMessageRef = -1;

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    protected static int getNextConcatenatedRef() {
    protected static int getNextConcatenatedRef() {
        sConcatenatedRef += 1;
        sConcatenatedRef += 1;
@@ -450,12 +447,13 @@ public abstract class SMSDispatcher extends Handler {
                   if sim was used on another device and inserted in a new device,
                   if sim was used on another device and inserted in a new device,
                   that device will start sending the next TPMR after reading from the SIM.
                   that device will start sending the next TPMR after reading from the SIM.
                 */
                 */
                mMessageRef = getTpmrValueFromSIM();
                mSmsDispatchersController.setMessageReference(getTpmrValueFromSIM());
                if (mMessageRef == -1) {
                if (mSmsDispatchersController.getMessageReference() == -1) {
                    SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
                    SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance()
                            .getSubscriptionInfoInternal(msg.arg1);
                            .getSubscriptionInfoInternal(msg.arg1);
                    if (subInfo != null) {
                    if (subInfo != null) {
                        mMessageRef = subInfo.getLastUsedTPMessageReference();
                        mSmsDispatchersController.setMessageReference(
                                subInfo.getLastUsedTPMessageReference());
                    }
                    }
                }
                }
                break;
                break;
@@ -475,11 +473,12 @@ public abstract class SMSDispatcher extends Handler {
    }
    }


    private void updateTPMessageReference() {
    private void updateTPMessageReference() {
        updateSIMLastTPMRValue(mMessageRef);
        updateSIMLastTPMRValue(mSmsDispatchersController.getMessageReference());
        final long identity = Binder.clearCallingIdentity();
        final long identity = Binder.clearCallingIdentity();
        try {
        try {
            SubscriptionManagerService.getInstance()
            SubscriptionManagerService.getInstance()
                    .setLastUsedTPMessageReference(getSubId(), mMessageRef);
                    .setLastUsedTPMessageReference(getSubId(),
                    mSmsDispatchersController.getMessageReference());
        } catch (SecurityException e) {
        } catch (SecurityException e) {
            Rlog.e(TAG, "Security Exception caused on messageRef updation to DB " + e.getMessage());
            Rlog.e(TAG, "Security Exception caused on messageRef updation to DB " + e.getMessage());
        } finally {
        } finally {
@@ -521,9 +520,10 @@ public abstract class SMSDispatcher extends Handler {
            return 0;
            return 0;
        }
        }


        mMessageRef = (mMessageRef + 1) % 256;
        int messageRef = mSmsDispatchersController.incrementMessageReference();
        Rlog.d(TAG, "nextMessageRef: " + messageRef);
        updateTPMessageReference();
        updateTPMessageReference();
        return mMessageRef;
        return messageRef;
    }
    }


    /**
    /**
+21 −0
Original line number Original line Diff line number Diff line
@@ -144,6 +144,9 @@ public class SmsDispatchersController extends Handler {
    private SMSDispatcher mGsmDispatcher;
    private SMSDispatcher mGsmDispatcher;
    private ImsSmsDispatcher mImsSmsDispatcher;
    private ImsSmsDispatcher mImsSmsDispatcher;


    /** Used for storing last TP - Message Reference used.*/
    private int mMessageRef = -1;

    private GsmInboundSmsHandler mGsmInboundSmsHandler;
    private GsmInboundSmsHandler mGsmInboundSmsHandler;
    private CdmaInboundSmsHandler mCdmaInboundSmsHandler = null;
    private CdmaInboundSmsHandler mCdmaInboundSmsHandler = null;


@@ -2297,6 +2300,24 @@ public class SmsDispatchersController extends Handler {
        }
        }
    }
    }


    public int getMessageReference() {
        return mMessageRef;
    }

    public void setMessageReference(int messageReference) {
        mMessageRef = messageReference;
    }

    /**
     * Increment the value of the message reference by 1.
     *
     * @return The new value of the message reference.
     */
    public int incrementMessageReference() {
        mMessageRef = (mMessageRef + 1) % 256;
        return mMessageRef;
    }

    public interface SmsInjectionCallback {
    public interface SmsInjectionCallback {
        void onSmsInjectedResult(int result);
        void onSmsInjectedResult(int result);
    }
    }
+186 −1
Original line number Original line Diff line number Diff line
@@ -31,10 +31,13 @@ import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.ArgumentMatchers.isNull;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.anyInt;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.clearInvocations;
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import static org.mockito.Mockito.when;
@@ -53,6 +56,7 @@ import android.telephony.DomainSelectionService;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneNumberUtils;
import android.telephony.SmsManager;
import android.telephony.SmsManager;
import android.telephony.ims.stub.ImsSmsImplBase;
import android.test.FlakyTest;
import android.test.FlakyTest;
import android.testing.AndroidTestingRunner;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper;
@@ -60,7 +64,9 @@ import android.util.Singleton;


import androidx.test.filters.SmallTest;
import androidx.test.filters.SmallTest;


import com.android.ims.FeatureConnector;
import com.android.ims.ImsManager;
import com.android.ims.ImsManager;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
import com.android.internal.telephony.domainselection.DomainSelectionConnection;
import com.android.internal.telephony.domainselection.DomainSelectionConnection;
import com.android.internal.telephony.domainselection.EmergencySmsDomainSelectionConnection;
import com.android.internal.telephony.domainselection.EmergencySmsDomainSelectionConnection;
import com.android.internal.telephony.domainselection.SmsDomainSelectionConnection;
import com.android.internal.telephony.domainselection.SmsDomainSelectionConnection;
@@ -138,7 +144,7 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
    /**
    /**
     * Inherits the SMSDispatcher to verify the abstract or protected methods.
     * Inherits the SMSDispatcher to verify the abstract or protected methods.
     */
     */
    protected abstract static class TestSmsDispatcher extends SMSDispatcher {
    protected static class TestSmsDispatcher extends SMSDispatcher {
        public TestSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) {
        public TestSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) {
            super(phone, smsDispatchersController);
            super(phone, smsDispatchersController);
        }
        }
@@ -159,6 +165,45 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
        public String getFormat() {
        public String getFormat() {
            return SmsConstants.FORMAT_3GPP;
            return SmsConstants.FORMAT_3GPP;
        }
        }

        @Override
        protected boolean shouldBlockSmsForEcbm() {
            return false;
        }

        @Override
        protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAdd, String destAdd,
                String message, boolean statusReportRequested, SmsHeader smsHeader,
                int priority,
                int validityPeriod) {
            return null;
        }

        @Override
        protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAdd, String destAdd,
                int destPort, byte[] message, boolean statusReportRequested) {
            return null;
        }

        @Override
        protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAdd, String destAdd,
                String message, boolean statusReportRequested, SmsHeader smsHeader,
                int priority,
                int validityPeriod, int messageRef) {
            return null;
        }

        @Override
        protected SmsMessageBase.SubmitPduBase getSubmitPdu(String scAdd, String destAdd,
                int destPort, byte[] message, boolean statusReportRequested, int messageRef) {
            return null;
        }

        @Override
        protected TextEncodingDetails calculateLength(CharSequence messageBody,
                boolean use7bitOnly) {
            return null;
        }
    }
    }


    /**
    /**
@@ -276,6 +321,124 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
                any(Message.class));
                any(Message.class));
    }
    }


    @Test
    @SmallTest
    public void testSendTextMessageRefSequence() throws Exception {
        setUpSpySmsDispatchers();
        doReturn(true).when(mImsSmsDispatcher).isMessageRefIncrementViaTelephony();
        doReturn(true).when(mGsmSmsDispatcher).isMessageRefIncrementViaTelephony();
        int messageRef = mSmsDispatchersController.getMessageReference();

        doReturn(true).when(mImsSmsDispatcher).isAvailable();
        mSmsDispatchersController.sendText("1111", "2222", "text", mSentIntent, null, null,
                "test-app", mCallingUserId, false, 0, false, 10, false, 1L, false);
        assertEquals(messageRef + 1, mSmsDispatchersController.getMessageReference());
        verify(mImsSmsDispatcher).sendText(eq("1111"), eq("2222"), eq("text"), eq(mSentIntent),
                any(), any(), eq("test-app"), eq(mCallingUserId), eq(false),
                eq(0), eq(false), eq(10), eq(false), eq(1L), eq(false), anyLong());
        // PS->PS
        mSmsDispatchersController.sendText("1112", "2222", "text", mSentIntent, null, null,
                "test-app", mCallingUserId, false, 0, false, 10, false, 1L, false);
        assertEquals(messageRef + 2, mSmsDispatchersController.getMessageReference());
        verify(mImsSmsDispatcher).sendText(eq("1112"), eq("2222"), eq("text"), eq(mSentIntent),
                any(), any(), eq("test-app"), eq(mCallingUserId), eq(false),
                eq(0), eq(false), eq(10), eq(false), eq(1L), eq(false), anyLong());
        // PS->CS
        doReturn(false).when(mImsSmsDispatcher).isAvailable();
        mSmsDispatchersController.sendText("1113", "2222", "text", mSentIntent, null, null,
                "test-app", mCallingUserId, false, 0, false, 10, false, 1L, false);
        assertEquals(messageRef + 3, mSmsDispatchersController.getMessageReference());
        verify(mGsmSmsDispatcher).sendText(eq("1113"), eq("2222"), eq("text"), eq(mSentIntent),
                any(), any(), eq("test-app"), eq(mCallingUserId), eq(false),
                eq(0), eq(false), eq(10), eq(false), eq(1L), eq(false), anyLong());
        // CS->CS
        mSmsDispatchersController.sendText("1114", "2222", "text", mSentIntent, null, null,
                "test-app", mCallingUserId, false, 0, false, 10, false, 1L, false);
        assertEquals(messageRef + 4, mSmsDispatchersController.getMessageReference());
        verify(mGsmSmsDispatcher).sendText(eq("1114"), eq("2222"), eq("text"), eq(mSentIntent),
                any(), any(), eq("test-app"), eq(mCallingUserId), eq(false),
                eq(0), eq(false), eq(10), eq(false), eq(1L), eq(false), anyLong());
        // CS->PS
        doReturn(true).when(mImsSmsDispatcher).isAvailable();
        mSmsDispatchersController.sendText("1115", "2222", "text", mSentIntent, null, null,
                "test-app", mCallingUserId, false, 0, false, 10, false, 1L, false);
        assertEquals(messageRef + 5, mSmsDispatchersController.getMessageReference());
        verify(mImsSmsDispatcher).sendText(eq("1115"), eq("2222"), eq("text"), eq(mSentIntent),
                any(), any(), eq("test-app"), eq(mCallingUserId), eq(false),
                eq(0), eq(false), eq(10), eq(false), eq(1L), eq(false), anyLong());
    }

    @Test
    @SmallTest
    public void testMessageReferenceIncrementDuringFallback() throws Exception {
        setUpSpySmsDispatchers();
        doReturn(true).when(mImsSmsDispatcher).isAvailable();
        doReturn(true).when(mImsSmsDispatcher).isMessageRefIncrementViaTelephony();
        doReturn(true).when(mGsmSmsDispatcher).isMessageRefIncrementViaTelephony();
        int messageRef = mSmsDispatchersController.getMessageReference();

        doAnswer(invocation -> {
            mTracker = (SMSDispatcher.SmsTracker) invocation.getArgument(0);
            int token = mImsSmsDispatcher.mNextToken.get();
            mImsSmsDispatcher.mTrackers.put(token, mTracker);
            // Verify TP-MR increment only by 1
            assertEquals(messageRef + 1, mSmsDispatchersController.getMessageReference());
            // Limit retries to 1
            if (mTracker.mRetryCount < 1) {
                doReturn(false).when(mImsSmsDispatcher).isAvailable();
                mImsSmsDispatcher.getSmsListener().onSendSmsResult(token, 0,
                        ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK, 0, SmsResponse.NO_ERROR_CODE);
            }
            return 0;
        }).when(mImsSmsDispatcher).sendSms(any(SMSDispatcher.SmsTracker.class));

        // Send SMS
        mSmsDispatchersController.sendText("1113", "2222", "text", mSentIntent, null, null,
                "test-app", mCallingUserId, false, 0, false, 10, false, 1L, false);

        ArgumentCaptor<SMSDispatcher.SmsTracker> captor =
                ArgumentCaptor.forClass(SMSDispatcher.SmsTracker.class);
        verify(mImsSmsDispatcher).sendSms(captor.capture());
        mTracker = captor.getValue();

        verify(mGsmSmsDispatcher).sendSms(eq(mTracker));
        // Verify TP-MR value is same as that was over IMS
        assertEquals(messageRef + 1, mSmsDispatchersController.getMessageReference());
    }

    @Test
    @SmallTest
    public void testMessageReferenceIncrementDuringImsRetry() throws Exception {
        setUpSpySmsDispatchers();
        doReturn(true).when(mImsSmsDispatcher).isAvailable();
        doReturn(true).when(mImsSmsDispatcher).isMessageRefIncrementViaTelephony();
        doReturn(true).when(mGsmSmsDispatcher).isMessageRefIncrementViaTelephony();
        int messageRef = mSmsDispatchersController.getMessageReference();

        doAnswer(invocation -> {
            mTracker = (SMSDispatcher.SmsTracker) invocation.getArgument(0);
            int token = mImsSmsDispatcher.mNextToken.get();
            mImsSmsDispatcher.mTrackers.put(token, mTracker);
            // Verify TP-MR increment by 1 only
            assertEquals(messageRef + 1, mSmsDispatchersController.getMessageReference());

            // Limit retries to 1
            if (mTracker.mRetryCount < 1) {
                mImsSmsDispatcher.getSmsListener().onSendSmsResult(token, 0,
                        ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK, 0, SmsResponse.NO_ERROR_CODE);
            }
            return 0;
        }).when(mImsSmsDispatcher).sendSms(any(SMSDispatcher.SmsTracker.class));

        // Send SMS
        mSmsDispatchersController.sendText("1113", "2222", "text", mSentIntent, null, null,
                "test-app", mCallingUserId, false, 0, false, 10, false, 1L, false);

        // Verify SMS is sent over IMS twice
        verify(mImsSmsDispatcher, times(2)).sendSms(any(SMSDispatcher.SmsTracker.class));
        verify(mGsmSmsDispatcher, times(0)).sendSms(any(SMSDispatcher.SmsTracker.class));
    }

    @Test @SmallTest
    @Test @SmallTest
    public void testSendImsGmsTestWithOutDesAddr() throws Exception {
    public void testSendImsGmsTestWithOutDesAddr() throws Exception {
        switchImsSmsFormat(PhoneConstants.PHONE_TYPE_GSM);
        switchImsSmsFormat(PhoneConstants.PHONE_TYPE_GSM);
@@ -1126,6 +1289,28 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
                        | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT);
                        | PendingIntent.FLAG_ALLOW_UNSAFE_IMPLICIT_INTENT);
    }
    }


    private void setUpSpySmsDispatchers() throws Exception {
        ImsSmsDispatcher.FeatureConnectorFactory mConnectorFactory = mock(
                ImsSmsDispatcher.FeatureConnectorFactory.class);
        FeatureConnector mMockConnector = mock(FeatureConnector.class);
        when(mConnectorFactory.create(any(), anyInt(), anyString(), any(), any())).thenReturn(
                mMockConnector);
        mImsSmsDispatcher =
            spy(new TestImsSmsDispatcher(mPhone, mSmsDispatchersController, mConnectorFactory));

        mGsmSmsDispatcher = spy(new TestSmsDispatcher(mPhone, mSmsDispatchersController));

        mCdmaSmsDispatcher = Mockito.mock(TestSmsDispatcher.class);
        when(mCdmaSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP2);

        replaceInstance(SmsDispatchersController.class, "mImsSmsDispatcher",
                mSmsDispatchersController, mImsSmsDispatcher);
        replaceInstance(SmsDispatchersController.class, "mGsmDispatcher",
                mSmsDispatchersController, mGsmSmsDispatcher);
        replaceInstance(SmsDispatchersController.class, "mCdmaDispatcher",
                mSmsDispatchersController, mCdmaSmsDispatcher);
    }

    private void setUpEmergencyStateTracker(int result) throws Exception {
    private void setUpEmergencyStateTracker(int result) throws Exception {
        mEmergencySmsFuture = new CompletableFuture<Integer>();
        mEmergencySmsFuture = new CompletableFuture<Integer>();
        mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class);
        mEmergencyStateTracker = Mockito.mock(EmergencyStateTracker.class);