Loading src/java/com/android/internal/telephony/SMSDispatcher.java +10 −10 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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; } } /** /** Loading src/java/com/android/internal/telephony/SmsDispatchersController.java +21 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java +186 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } } Loading @@ -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; } } } /** /** Loading Loading @@ -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); Loading Loading @@ -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); Loading Loading
src/java/com/android/internal/telephony/SMSDispatcher.java +10 −10 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; Loading @@ -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 { Loading Loading @@ -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; } } /** /** Loading
src/java/com/android/internal/telephony/SmsDispatchersController.java +21 −0 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading
tests/telephonytests/src/com/android/internal/telephony/SmsDispatchersControllerTest.java +186 −1 Original line number Original line Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading @@ -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; Loading Loading @@ -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); } } Loading @@ -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; } } } /** /** Loading Loading @@ -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); Loading Loading @@ -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); Loading