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

Commit e547592a authored by Hyunho's avatar Hyunho Committed by Hyunho Shin
Browse files

Add state for 413 response of PUBLISH

Upon receiving 413 response to PUBLISH, the device state set to re_try.
If the device state is retry, the PUBLISH requests should be blocked until the vendor called CapabilityExchangeEventListener#onPublishUpdated or CapabilityExchangeEventListener#onRequestPublishCapabilities.

Test: atest PublishControllerImplTest CapabilityRequestTest UceControllerTest
Bug: b/202199257
Change-Id: I7776ed98f0e1a661d14c743f1cde8abc13979cab
Merged-In: I54227c366d64c626fef8a00f63e4c0990a710d6c
parent cd61d36e
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
@@ -64,11 +64,18 @@ public class UceDeviceState {
     */
    private static final int DEVICE_STATE_BAD_EVENT = 3;

    /**
     * The device will be in the NO_RETRY error state when the PUBLISH request fails and the
     * SIP code is 413 REQUEST ENTITY TOO LARGE.
     */
    private static final int DEVICE_STATE_NO_RETRY = 4;

    @IntDef(value = {
            DEVICE_STATE_OK,
            DEVICE_STATE_FORBIDDEN,
            DEVICE_STATE_PROVISION_ERROR,
            DEVICE_STATE_BAD_EVENT,
            DEVICE_STATE_NO_RETRY,
    }, prefix="DEVICE_STATE_")
    @Retention(RetentionPolicy.SOURCE)
    public @interface DeviceStateType {}
@@ -79,6 +86,7 @@ public class UceDeviceState {
        DEVICE_STATE_DESCRIPTION.put(DEVICE_STATE_FORBIDDEN, "DEVICE_STATE_FORBIDDEN");
        DEVICE_STATE_DESCRIPTION.put(DEVICE_STATE_PROVISION_ERROR, "DEVICE_STATE_PROVISION_ERROR");
        DEVICE_STATE_DESCRIPTION.put(DEVICE_STATE_BAD_EVENT, "DEVICE_STATE_BAD_EVENT");
        DEVICE_STATE_DESCRIPTION.put(DEVICE_STATE_NO_RETRY, "DEVICE_STATE_NO_RETRY");
    }

    /**
@@ -112,6 +120,18 @@ public class UceDeviceState {
            }
        }

        /**
         * Check current state to see if only the PUBLISH request is allowed to be executed.
         */
        public boolean isPublishRequestBlocked() {
            switch(mDeviceState) {
                case DEVICE_STATE_NO_RETRY:
                    return true;
                default:
                    return false;
            }
        }

        public int getDeviceState() {
            return mDeviceState;
        }
@@ -276,6 +296,17 @@ public class UceDeviceState {
                // Reset the device state when the network response is OK.
                resetInternal();
                break;

            case NetworkSipCode.SIP_CODE_REQUEST_ENTITY_TOO_LARGE:   // sip 413
            case NetworkSipCode.SIP_CODE_BUSY_EVERYWHERE:   // sip 600
                if (requestType == UceController.REQUEST_TYPE_PUBLISH) {
                    setDeviceState(DEVICE_STATE_NO_RETRY);
                    // There is no request retry time for SIP code 413
                    removeRequestRetryTime();
                    // No timer to exit this state.
                    removeExitStateTimer();
                }
                break;
        }

        // Get the updated device state.
+2 −2
Original line number Diff line number Diff line
@@ -851,7 +851,7 @@ public class PublishControllerImpl implements PublishController {

        // Check whether the device state is not allowed to execute the PUBLISH request.
        DeviceStateResult deviceState = mUceCtrlCallback.getDeviceState();
        if (deviceState.isRequestForbidden()) {
        if (deviceState.isRequestForbidden() || deviceState.isPublishRequestBlocked()) {
            logd("isPublishRequestAllowed: The device state is disallowed. "
                    + deviceState.getDeviceState());
            return false;
@@ -1076,7 +1076,7 @@ public class PublishControllerImpl implements PublishController {
            }
            // Reset device state
            DeviceStateResult deviceState = mUceCtrlCallback.getDeviceState();
            if (deviceState.isRequestForbidden()) {
            if (deviceState.isRequestForbidden() || deviceState.isPublishRequestBlocked()) {
                mUceCtrlCallback.resetDeviceState();
            }
        }
+1 −0
Original line number Diff line number Diff line
@@ -32,6 +32,7 @@ public class NetworkSipCode {
    public static final int SIP_CODE_NOT_FOUND = 404;
    public static final int SIP_CODE_METHOD_NOT_ALLOWED = 405;
    public static final int SIP_CODE_REQUEST_TIMEOUT = 408;
    public static final int SIP_CODE_REQUEST_ENTITY_TOO_LARGE = 413;
    public static final int SIP_CODE_INTERVAL_TOO_BRIEF = 423;
    public static final int SIP_CODE_TEMPORARILY_UNAVAILABLE = 480;
    public static final int SIP_CODE_BAD_EVENT = 489;
+3 −0
Original line number Diff line number Diff line
@@ -174,6 +174,9 @@ public class UceControllerTest extends ImsTestBase {
        UceController uceController = createUceController();
        uceController.onRcsConnected(mFeatureManager);
        doReturn(false).when(mDeviceStateResult).isRequestForbidden();
        // This API should only be applied to PUBLISH.
        // Even if the return value is true, the capabilities request must be processed.
        doReturn(true).when(mDeviceStateResult).isPublishRequestBlocked();

        List<Uri> uriList = new ArrayList<>();
        uriList.add(Uri.fromParts("sip", "test", null));
+27 −0
Original line number Diff line number Diff line
@@ -86,6 +86,7 @@ public class PublishControllerImplTest extends ImsTestBase {
                eq(mSubId), any(), any(), any());
        doReturn(mDeviceStateResult).when(mUceCtrlCallback).getDeviceState();
        doReturn(false).when(mDeviceStateResult).isRequestForbidden();
        doReturn(false).when(mDeviceStateResult).isPublishRequestBlocked();
    }

    @After
@@ -353,6 +354,32 @@ public class PublishControllerImplTest extends ImsTestBase {
        verify(mPublishProcessor).doPublish(PublishController.PUBLISH_TRIGGER_SERVICE);
    }

    @Test
    @SmallTest
    public void testRequestPublishFromServiceWhenDeviceNoRetry() throws Exception {
        doReturn(true).when(mDeviceStateResult).isPublishRequestBlocked();

        PublishControllerImpl publishController = createPublishController();
        doReturn(Optional.of(0L)).when(mPublishProcessor).getPublishingDelayTime();

        // Set the PRESENCE is capable
        IImsCapabilityCallback RcsCapCallback = publishController.getRcsCapabilitiesCallback();
        RcsCapCallback.onCapabilitiesStatusChanged(RcsUceAdapter.CAPABILITY_TYPE_PRESENCE_UCE);

        // Trigger the PUBLISH request from the service.
        publishController.requestPublishCapabilitiesFromService(
                RcsUceAdapter.CAPABILITY_UPDATE_TRIGGER_MOVE_TO_IWLAN);

        Handler handler = publishController.getPublishHandler();
        waitForHandlerAction(handler, 1000);

        // Reset device state because isPublishRequestBlocked() is true when Ims Service
        // requests PUBLISH.
        verify(mUceCtrlCallback).resetDeviceState();
        // The PUBLISH request must be pending because the current device state is no_retry.
        verify(mPublishProcessor).setPendingRequest(anyInt());
    }

    @Test
    @SmallTest
    public void testFirstRequestPublishIsTriggeredFromService() throws Exception {