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

Commit e558eb5a authored by Hwangoo Park's avatar Hwangoo Park Committed by Android (Google) Code Review
Browse files

Merge "Apply emergency SMS domain selection for multipart-text/retry" into 24D1-dev

parents 7b1ddd40 cbb3a99f
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -203,7 +203,8 @@ public class ImsSmsDispatcher extends SMSDispatcher {
                        mTrackers.remove(token);
                        mPhone.notifySmsSent(tracker.mDestAddress);
                        mSmsDispatchersController.notifySmsSentToEmergencyStateTracker(
                                tracker.mDestAddress, tracker.mMessageId, true);
                                tracker.mDestAddress, tracker.mMessageId, true,
                                tracker.isSinglePartOrLastPart());
                        break;
                    case ImsSmsImplBase.SEND_STATUS_ERROR:
                        tracker.onFailed(mContext, reason, networkReasonCode);
+10 −1
Original line number Diff line number Diff line
@@ -1054,7 +1054,8 @@ public abstract class SMSDispatcher extends Handler {
            tracker.onSent(mContext);
            mPhone.notifySmsSent(tracker.mDestAddress);
            mSmsDispatchersController.notifySmsSentToEmergencyStateTracker(
                    tracker.mDestAddress, tracker.mMessageId, false);
                    tracker.mDestAddress, tracker.mMessageId, false,
                    tracker.isSinglePartOrLastPart());

            mPhone.getSmsStats().onOutgoingSms(
                    tracker.mImsRetry > 0 /* isOverIms */,
@@ -2612,6 +2613,14 @@ public abstract class SMSDispatcher extends Handler {
            return SystemClock.elapsedRealtime() - mTimestamp;
        }

        /**
         * Returns the flag specifying whether this {@link SmsTracker} is a single part or
         * the last part of multipart message.
         */
        protected boolean isSinglePartOrLastPart() {
            return mUnsentPartCount != null ? (mUnsentPartCount.get() == 0) : true;
        }

        /**
         * Persist a sent SMS if required:
         * 1. It is a text message
+40 −11
Original line number Diff line number Diff line
@@ -112,6 +112,9 @@ public class SmsDispatchersController extends Handler {
    /** Called when MT SMS is received via IMS. */
    private static final int EVENT_SMS_RECEIVED_VIA_IMS = 21;

    /** Called when the domain selection should be performed. */
    private static final int EVENT_REQUEST_DOMAIN_SELECTION = 22;

    /** Delete any partial message segments after being IN_SERVICE for 1 day. */
    private static final long PARTIAL_SEGMENT_WAIT_DURATION = (long) (60 * 60 * 1000) * 24;
    /** Constant for invalid time */
@@ -491,9 +494,10 @@ public class SmsDispatchersController extends Handler {
                Long messageId = (Long) args.arg2;
                Boolean success = (Boolean) args.arg3;
                Boolean isOverIms = (Boolean) args.arg4;
                Boolean isLastSmsPart = (Boolean) args.arg5;
                try {
                    handleSmsSentCompletedUsingDomainSelection(
                            destAddr, messageId, success, isOverIms);
                            destAddr, messageId, success, isOverIms, isLastSmsPart);
                } finally {
                    args.recycle();
                }
@@ -508,6 +512,19 @@ public class SmsDispatchersController extends Handler {
                handleSmsReceivedViaIms((String) msg.obj);
                break;
            }
            case EVENT_REQUEST_DOMAIN_SELECTION: {
                SomeArgs args = (SomeArgs) msg.obj;
                DomainSelectionConnectionHolder holder =
                        (DomainSelectionConnectionHolder) args.arg1;
                PendingRequest request = (PendingRequest) args.arg2;
                String logTag = (String) args.arg3;
                try {
                    requestDomainSelection(holder, request, logTag);
                } finally {
                    args.recycle();
                }
                break;
            }
            default:
                if (isCdmaMo()) {
                    mCdmaDispatcher.handleMessage(msg);
@@ -762,16 +779,22 @@ public class SmsDispatchersController extends Handler {

        if (!tracker.mUsesImsServiceForIms) {
            if (isSmsDomainSelectionEnabled()) {
                DomainSelectionConnectionHolder holder = getDomainSelectionConnection(false);
                TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
                boolean isEmergency = tm.isEmergencyNumber(tracker.mDestAddress);
                DomainSelectionConnectionHolder holder = getDomainSelectionConnection(isEmergency);

                // If the DomainSelectionConnection is not available,
                // fallback to the legacy implementation.
                if (holder != null && holder.getConnection() != null) {
                    sendSmsUsingDomainSelection(holder,
                            new PendingRequest(PendingRequest.TYPE_RETRY_SMS, tracker,
                    // This may be invoked by another thread, so this operation is posted and
                    // handled through the execution flow of SmsDispatchersController.
                    SomeArgs args = SomeArgs.obtain();
                    args.arg1 = holder;
                    args.arg2 = new PendingRequest(PendingRequest.TYPE_RETRY_SMS, tracker,
                            null, null, null, null, null, false, null, 0, null, null, false,
                                    0, false, 0, 0L, false),
                            "sendRetrySms");
                            0, false, 0, 0L, false);
                    args.arg3 = "sendRetrySms";
                    sendMessage(obtainMessage(EVENT_REQUEST_DOMAIN_SELECTION, args));
                    return;
                }
            }
@@ -1157,15 +1180,17 @@ public class SmsDispatchersController extends Handler {
     * @param messageId The message id for SMS.
     * @param success A flag specifying whether MO SMS is successfully sent or not.
     * @param isOverIms A flag specifying whether MO SMS is sent over IMS or not.
     * @param isLastSmsPart A flag specifying whether this result is for the last SMS part or not.
     */
    private void handleSmsSentCompletedUsingDomainSelection(@NonNull String destAddr,
            long messageId, boolean success, boolean isOverIms) {
            long messageId, boolean success, boolean isOverIms, boolean isLastSmsPart) {
        if (mEmergencyStateTracker != null) {
            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
            if (tm.isEmergencyNumber(destAddr)) {
                mEmergencyStateTracker.endSms(String.valueOf(messageId), success,
                        isOverIms ? NetworkRegistrationInfo.DOMAIN_PS
                                  : NetworkRegistrationInfo.DOMAIN_CS);
                                  : NetworkRegistrationInfo.DOMAIN_CS,
                        isLastSmsPart);
            }
        }
    }
@@ -1174,7 +1199,7 @@ public class SmsDispatchersController extends Handler {
     * Called when MO SMS is successfully sent.
     */
    protected void notifySmsSentToEmergencyStateTracker(@NonNull String destAddr, long messageId,
            boolean isOverIms) {
            boolean isOverIms, boolean isLastSmsPart) {
        if (isSmsDomainSelectionEnabled()) {
            // Run on main thread for interworking with EmergencyStateTracker.
            SomeArgs args = SomeArgs.obtain();
@@ -1182,6 +1207,7 @@ public class SmsDispatchersController extends Handler {
            args.arg2 = Long.valueOf(messageId);
            args.arg3 = Boolean.TRUE;
            args.arg4 = Boolean.valueOf(isOverIms);
            args.arg5 = Boolean.valueOf(isLastSmsPart);
            sendMessage(obtainMessage(EVENT_SMS_SENT_COMPLETED_USING_DOMAIN_SELECTION, args));
        }
    }
@@ -1198,6 +1224,7 @@ public class SmsDispatchersController extends Handler {
            args.arg2 = Long.valueOf(messageId);
            args.arg3 = Boolean.FALSE;
            args.arg4 = Boolean.valueOf(isOverIms);
            args.arg5 = Boolean.TRUE; // Ignored when sending SMS is failed.
            sendMessage(obtainMessage(EVENT_SMS_SENT_COMPLETED_USING_DOMAIN_SELECTION, args));
        }
    }
@@ -1932,7 +1959,9 @@ public class SmsDispatchersController extends Handler {
        }

        if (isSmsDomainSelectionEnabled()) {
            DomainSelectionConnectionHolder holder = getDomainSelectionConnection(false);
            TelephonyManager tm = mContext.getSystemService(TelephonyManager.class);
            boolean isEmergency = tm.isEmergencyNumber(destAddr);
            DomainSelectionConnectionHolder holder = getDomainSelectionConnection(isEmergency);

            // If the DomainSelectionConnection is not available,
            // fallback to the legacy implementation.
+15 −3
Original line number Diff line number Diff line
@@ -1091,6 +1091,9 @@ public class EmergencyStateTracker {
     */
    @VisibleForTesting
    public boolean isEmergencyCallbackModeSupported(Phone phone) {
        if (phone == null) {
            return false;
        }
        int subId = phone.getSubId();
        int phoneId = phone.getPhoneId();
        if (!isSimReady(phoneId, subId)) {
@@ -1363,10 +1366,17 @@ public class EmergencyStateTracker {
     * @param success the flag specifying whether an emergency SMS is successfully sent or not.
     *                {@code true} if SMS is successfully sent, {@code false} otherwise.
     * @param domain the domain that MO SMS was sent.
     * @param isLastSmsPart the flag specifying whether this result is for the last SMS part or not.
     */
    public void endSms(@NonNull String smsId, boolean success,
            @NetworkRegistrationInfo.Domain int domain) {
            @NetworkRegistrationInfo.Domain int domain, boolean isLastSmsPart) {
        if (success && !isLastSmsPart) {
            // Waits until all SMS parts are sent successfully.
            // Ensures that all SMS parts are sent while in the emergency mode.
            Rlog.i(TAG, "endSms: wait for additional SMS parts to be sent.");
        } else {
            mOngoingEmergencySmsIds.remove(smsId);
        }

        // If the outgoing emergency SMSs are empty, we can try to exit the emergency mode.
        if (mOngoingEmergencySmsIds.isEmpty()) {
@@ -1389,7 +1399,9 @@ public class EmergencyStateTracker {
                // Sets the emergency mode to CALLBACK without re-initiating SCBM timer.
                setEmergencyCallbackMode(mSmsPhone, EMERGENCY_TYPE_SMS);
            } else {
                if (mSmsPhone != null) {
                    exitEmergencyMode(mSmsPhone, EMERGENCY_TYPE_SMS);
                }
                clearEmergencySmsInfo();
            }
        }
+90 −15
Original line number Diff line number Diff line
@@ -111,8 +111,8 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
        }

        public void testNotifySmsSentToEmergencyStateTracker(String destAddr, long messageId,
                boolean isOverIms) {
            notifySmsSentToEmergencyStateTracker(destAddr, messageId, isOverIms);
                boolean isOverIms, boolean isLastSmsPart) {
            notifySmsSentToEmergencyStateTracker(destAddr, messageId, isOverIms, isLastSmsPart);
        }

        public void testNotifySmsSentFailedToEmergencyStateTracker(String destAddr,
@@ -456,7 +456,7 @@ public class SmsDispatchersControllerTest extends TelephonyTest {

    @Test
    @SmallTest
    public void testSendEmergencyTextWhenDomainPs() throws Exception {
    public void testSendTextForEmergencyWhenDomainPs() throws Exception {
        setUpDomainSelectionConnection();
        setUpSmsDispatchers();
        setUpEmergencyStateTracker(DisconnectCause.NOT_DISCONNECTED);
@@ -488,7 +488,7 @@ public class SmsDispatchersControllerTest extends TelephonyTest {

    @Test
    @SmallTest
    public void testSendEmergencyTextWhenEmergencyStateTrackerReturnsFailure() throws Exception {
    public void testSendTextForEmergencyWhenEmergencyStateTrackerReturnsFailure() throws Exception {
        setUpDomainSelectionConnection();
        setUpSmsDispatchers();
        setUpEmergencyStateTracker(DisconnectCause.OUT_OF_SERVICE);
@@ -501,18 +501,90 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
        verify(mEmergencySmsDsc).requestDomainSelection(any(), any());
    }

    @Test
    @SmallTest
    public void testSendMultipartTextForEmergencyWhenDomainPs() throws Exception {
        setUpDomainSelectionConnection();
        setUpSmsDispatchers();
        setUpEmergencyStateTracker(DisconnectCause.NOT_DISCONNECTED);

        ArrayList<String> parts = new ArrayList<>();
        ArrayList<PendingIntent> sentIntents = new ArrayList<>();
        ArrayList<PendingIntent> deliveryIntents = new ArrayList<>();
        mSmsDispatchersController.testSendMultipartText("911", "2222", parts, sentIntents,
                deliveryIntents, null, "test-app", false, 0, false, 10, 1L);
        processAllMessages();

        SmsDispatchersController.DomainSelectionConnectionHolder holder =
                mSmsDispatchersController.testGetDomainSelectionConnectionHolder(true);
        verify(mEmergencySmsDsc).requestDomainSelection(any(), any());
        assertNotNull(holder);
        assertNotNull(holder.getConnection());
        assertTrue(holder.isEmergency());
        assertTrue(holder.isDomainSelectionRequested());
        assertEquals(1, holder.getPendingRequests().size());

        mDscFuture.complete(NetworkRegistrationInfo.DOMAIN_PS);
        processAllMessages();

        verify(mEmergencySmsDsc).finishSelection();
        verify(mImsSmsDispatcher).sendMultipartText(eq("911"), eq("2222"), eq(parts),
                eq(sentIntents), eq(deliveryIntents), any(), eq("test-app"), eq(false), eq(0),
                eq(false), eq(10), eq(1L));
        assertNull(holder.getConnection());
        assertFalse(holder.isDomainSelectionRequested());
        assertEquals(0, holder.getPendingRequests().size());
    }

    @Test
    @SmallTest
    public void testSendRetrySmsForEmergencyWhenDomainPs() throws Exception {
        setUpDomainSelectionConnection();
        setUpSmsDispatchers();
        setUpEmergencyStateTracker(DisconnectCause.NOT_DISCONNECTED);

        when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
        when(mImsSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP);
        when(mCdmaSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP2);
        when(mGsmSmsDispatcher.getFormat()).thenReturn(SmsConstants.FORMAT_3GPP);
        replaceInstance(SMSDispatcher.SmsTracker.class,
                "mFormat", mTracker, SmsConstants.FORMAT_3GPP);
        replaceInstance(SMSDispatcher.SmsTracker.class, "mDestAddress", mTracker, "911");

        mSmsDispatchersController.sendRetrySms(mTracker);
        processAllMessages();

        SmsDispatchersController.DomainSelectionConnectionHolder holder =
                mSmsDispatchersController.testGetDomainSelectionConnectionHolder(true);
        verify(mEmergencySmsDsc).requestDomainSelection(any(), any());
        assertNotNull(holder);
        assertNotNull(holder.getConnection());
        assertTrue(holder.isEmergency());
        assertTrue(holder.isDomainSelectionRequested());
        assertEquals(1, holder.getPendingRequests().size());

        mDscFuture.complete(NetworkRegistrationInfo.DOMAIN_PS);
        processAllMessages();

        verify(mEmergencySmsDsc).finishSelection();
        verify(mImsSmsDispatcher).sendSms(eq(mTracker));
        assertNull(holder.getConnection());
        assertFalse(holder.isDomainSelectionRequested());
        assertEquals(0, holder.getPendingRequests().size());
    }

    @Test
    @SmallTest
    public void testNotifySmsSentToEmergencyStateTrackerOnDomainCs() throws Exception {
        setUpDomainSelectionEnabled(true);
        setUpEmergencyStateTracker(DisconnectCause.NOT_DISCONNECTED);

        mSmsDispatchersController.testNotifySmsSentToEmergencyStateTracker("911", 1L, false);
        mSmsDispatchersController.testNotifySmsSentToEmergencyStateTracker("911", 1L, false, true);
        processAllMessages();

        verify(mTelephonyManager).isEmergencyNumber(eq("911"));
        verify(mEmergencyStateTracker)
                .endSms(eq("1"), eq(true), eq(NetworkRegistrationInfo.DOMAIN_CS));
                .endSms(eq("1"), eq(true), eq(NetworkRegistrationInfo.DOMAIN_CS), eq(true));
    }

    @Test
@@ -521,12 +593,12 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
        setUpDomainSelectionEnabled(true);
        setUpEmergencyStateTracker(DisconnectCause.NOT_DISCONNECTED);

        mSmsDispatchersController.testNotifySmsSentToEmergencyStateTracker("911", 1L, true);
        mSmsDispatchersController.testNotifySmsSentToEmergencyStateTracker("911", 1L, true, true);
        processAllMessages();

        verify(mTelephonyManager).isEmergencyNumber(eq("911"));
        verify(mEmergencyStateTracker)
                .endSms(eq("1"), eq(true), eq(NetworkRegistrationInfo.DOMAIN_PS));
                .endSms(eq("1"), eq(true), eq(NetworkRegistrationInfo.DOMAIN_PS), eq(true));
    }

    @Test
@@ -535,11 +607,12 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
        setUpDomainSelectionEnabled(true);
        setUpEmergencyStateTracker(DisconnectCause.NOT_DISCONNECTED);

        mSmsDispatchersController.testNotifySmsSentToEmergencyStateTracker("1234", 1L, true);
        mSmsDispatchersController.testNotifySmsSentToEmergencyStateTracker("1234", 1L, true, true);
        processAllMessages();

        verify(mTelephonyManager).isEmergencyNumber(eq("1234"));
        verify(mEmergencyStateTracker, never()).endSms(anyString(), anyBoolean(), anyInt());
        verify(mEmergencyStateTracker, never())
                .endSms(anyString(), anyBoolean(), anyInt(), anyBoolean());
    }

    @Test
@@ -547,7 +620,7 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
    public void testNotifySmsSentToEmergencyStateTrackerWithoutEmergencyStateTracker()
            throws Exception {
        setUpDomainSelectionEnabled(true);
        mSmsDispatchersController.testNotifySmsSentToEmergencyStateTracker("911", 1L, true);
        mSmsDispatchersController.testNotifySmsSentToEmergencyStateTracker("911", 1L, true, true);

        verify(mTelephonyManager, never()).isEmergencyNumber(anyString());
    }
@@ -563,7 +636,7 @@ public class SmsDispatchersControllerTest extends TelephonyTest {

        verify(mTelephonyManager).isEmergencyNumber(eq("911"));
        verify(mEmergencyStateTracker)
                .endSms(eq("1"), eq(false), eq(NetworkRegistrationInfo.DOMAIN_CS));
                .endSms(eq("1"), eq(false), eq(NetworkRegistrationInfo.DOMAIN_CS), eq(true));
    }

    @Test
@@ -577,7 +650,7 @@ public class SmsDispatchersControllerTest extends TelephonyTest {

        verify(mTelephonyManager).isEmergencyNumber(eq("911"));
        verify(mEmergencyStateTracker)
                .endSms(eq("1"), eq(false), eq(NetworkRegistrationInfo.DOMAIN_PS));
                .endSms(eq("1"), eq(false), eq(NetworkRegistrationInfo.DOMAIN_PS), eq(true));
    }

    @Test
@@ -591,7 +664,8 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
        processAllMessages();

        verify(mTelephonyManager).isEmergencyNumber(eq("1234"));
        verify(mEmergencyStateTracker, never()).endSms(anyString(), anyBoolean(), anyInt());
        verify(mEmergencyStateTracker, never())
                .endSms(anyString(), anyBoolean(), anyInt(), anyBoolean());
    }

    @Test
@@ -843,7 +917,8 @@ public class SmsDispatchersControllerTest extends TelephonyTest {
                mSmsDispatchersController, mEmergencyStateTracker);
        when(mEmergencyStateTracker.startEmergencySms(any(Phone.class), anyString(), anyBoolean()))
                .thenReturn(mEmergencySmsFuture);
        doNothing().when(mEmergencyStateTracker).endSms(anyString(), anyBoolean(), anyInt());
        doNothing().when(mEmergencyStateTracker)
                .endSms(anyString(), anyBoolean(), anyInt(), anyBoolean());
        mEmergencySmsFuture.complete(result);
        when(mTelephonyManager.isEmergencyNumber(eq("911"))).thenReturn(true);
    }
Loading