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

Commit 00b0a8d0 authored by Aishwarya Mallampati's avatar Aishwarya Mallampati
Browse files

Do not send and receive datagrams at the same time.

The following changes are made in this CL:
- DatagramDispatcher:
-- send datagram only if modem is not receiving datagrams.

- DatagramReceiver:
-- Poll for pending datagrams only if modem is not sending datagrams.

Bug: 275670811
Test: atest com.android.internal.telephony.satellite
      atest CtsTelephonyTestCases:android.telephony.satellite.cts
      Flashed build on raven-userdebug: calls and sms are working

Change-Id: I6fcf6709453daa75b69731fb19decd6fe90f4c6d
parent b7ff375b
Loading
Loading
Loading
Loading
+67 −30
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;

import java.util.concurrent.TimeUnit;
@@ -49,17 +50,27 @@ public class DatagramController {
    private static final boolean DEBUG = !"user".equals(Build.TYPE);

    /** Variables used to update onSendDatagramStateChanged(). */
    private final Object mLock = new Object();
    @GuardedBy("mLock")
    private int mSendSubId;
    private int mSendDatagramTransferState =
            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN;
    @GuardedBy("mLock")
    private @SatelliteManager.SatelliteDatagramTransferState int mSendDatagramTransferState =
            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
    @GuardedBy("mLock")
    private int mSendPendingCount = 0;
    @GuardedBy("mLock")
    private int mSendErrorCode = SatelliteManager.SATELLITE_ERROR_NONE;
    /** Variables used to update onReceiveDatagramStateChanged(). */
    @GuardedBy("mLock")
    private int mReceiveSubId;
    private int mReceiveDatagramTransferState =
            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN;
    @GuardedBy("mLock")
    private @SatelliteManager.SatelliteDatagramTransferState int mReceiveDatagramTransferState =
            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
    @GuardedBy("mLock")
    private int mReceivePendingCount = 0;
    @GuardedBy("mLock")
    private int mReceiveErrorCode = SatelliteManager.SATELLITE_ERROR_NONE;

    private SatelliteDatagram mDemoModeDatagram;
    private boolean mIsDemoMode = false;
    private long mAlignTimeoutDuration = SATELLITE_ALIGN_TIMEOUT;
@@ -192,6 +203,7 @@ public class DatagramController {
    public void updateSendStatus(int subId,
            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
            int sendPendingCount, int errorCode) {
        synchronized (mLock) {
            logd("updateSendStatus"
                    + " subId: " + subId
                    + " datagramTransferState: " + datagramTransferState
@@ -201,9 +213,11 @@ public class DatagramController {
            mSendDatagramTransferState = datagramTransferState;
            mSendPendingCount = sendPendingCount;
            mSendErrorCode = errorCode;

            notifyDatagramTransferStateChangedToSessionController();
        mPointingAppController.updateSendDatagramTransferState(subId, datagramTransferState,
                sendPendingCount, errorCode);
            mPointingAppController.updateSendDatagramTransferState(mSendSubId,
                    mSendDatagramTransferState, mSendPendingCount, mSendErrorCode);
        }
    }

    /**
@@ -217,6 +231,7 @@ public class DatagramController {
    public void updateReceiveStatus(int subId,
            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
            int receivePendingCount, int errorCode) {
        synchronized (mLock) {
            logd("updateReceiveStatus"
                    + " subId: " + subId
                    + " datagramTransferState: " + datagramTransferState
@@ -226,9 +241,15 @@ public class DatagramController {
            mReceiveDatagramTransferState = datagramTransferState;
            mReceivePendingCount = receivePendingCount;
            mReceiveErrorCode = errorCode;

            notifyDatagramTransferStateChangedToSessionController();
        mPointingAppController.updateReceiveDatagramTransferState(subId, datagramTransferState,
                receivePendingCount, errorCode);
            mPointingAppController.updateReceiveDatagramTransferState(mReceiveSubId,
                    mReceiveDatagramTransferState, mReceivePendingCount, mReceiveErrorCode);
        }

        if (isPollingInIdleState()) {
            mDatagramDispatcher.retrySendingDatagrams();
        }
    }

    /**
@@ -256,9 +277,25 @@ public class DatagramController {
    }

    boolean isReceivingDatagrams() {
        synchronized (mLock) {
            return (mReceiveDatagramTransferState
                    == SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING);
        }
    }

    public boolean isSendingInIdleState() {
        synchronized (mLock) {
            return mSendDatagramTransferState ==
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
        }
    }

    public boolean isPollingInIdleState() {
        synchronized (mLock) {
            return mReceiveDatagramTransferState ==
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE;
        }
    }

    /**
     * Set variables for {@link DatagramDispatcher} and {@link DatagramReceiver} to run demo mode
+45 −23
Original line number Diff line number Diff line
@@ -343,13 +343,15 @@ public class DatagramDispatcher extends Handler {
                        needFullScreenPointingUI, callback);

        synchronized (mLock) {
            // Add datagram to pending datagram map
            if (datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
                mPendingEmergencyDatagramsMap.put(datagramId, datagramArgs);
            } else {
                mPendingNonEmergencyDatagramsMap.put(datagramId, datagramArgs);
            }

            if (!mSendingDatagramInProgress) {
            // Modem can be busy receiving datagrams, so send datagram only when modem is not busy.
            if (!mSendingDatagramInProgress && mDatagramController.isPollingInIdleState()) {
                mSendingDatagramInProgress = true;
                datagramArgs.setDatagramStartTime();
                mDatagramController.updateSendStatus(subId,
@@ -360,6 +362,12 @@ public class DatagramDispatcher extends Handler {
        }
    }

    public void retrySendingDatagrams() {
        synchronized (mLock) {
            sendPendingDatagrams();
        }
    }

    /** Set demo mode
     *
     * @param isDemoMode {@code true} means demo mode is on, {@code false} otherwise.
@@ -439,6 +447,17 @@ public class DatagramDispatcher extends Handler {
    @GuardedBy("mLock")
    private void sendPendingDatagrams() {
        logd("sendPendingDatagrams()");
        if (!mDatagramController.isPollingInIdleState()) {
            // Datagram should be sent to satellite modem when modem is free.
            logd("sendPendingDatagrams: modem is receiving datagrams");
            return;
        }

        if (getPendingDatagramCount() <= 0) {
            logd("sendPendingDatagrams: no pending datagrams to send");
            return;
        }

        Phone phone = SatelliteServiceUtils.getPhone();
        Set<Entry<Long, SendSatelliteDatagramArgument>> pendingDatagram = null;
        if (!mSendingDatagramInProgress && !mPendingEmergencyDatagramsMap.isEmpty()) {
@@ -552,15 +571,19 @@ public class DatagramDispatcher extends Handler {
     * @param state Current satellite modem state.
     */
    public void onSatelliteModemStateChanged(@SatelliteManager.SatelliteModemState int state) {
        synchronized (mLock) {
            if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF
                    || state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE) {
                logd("onSatelliteModemStateChanged: cleaning up resources");
                cleanUpResources();
            } else if (state == SatelliteManager.SATELLITE_MODEM_STATE_IDLE) {
                sendPendingDatagrams();
            }
        }
    }

    @GuardedBy("mLock")
    private void cleanUpResources() {
        synchronized (mLock) {
        mSendingDatagramInProgress = false;
        if (getPendingDatagramCount() > 0) {
            mDatagramController.updateSendStatus(
@@ -579,7 +602,6 @@ public class DatagramDispatcher extends Handler {
        mSendSatelliteDatagramRequest = null;
        mIsAligned = false;
    }
    }

    private static void logd(@NonNull String log) {
        Rlog.d(TAG, log);
+39 −17
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import android.telephony.satellite.SatelliteManager;
import android.util.Pair;

import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.IIntegerConsumer;
import com.android.internal.telephony.IVoidConsumer;
@@ -79,6 +80,7 @@ public class DatagramReceiver extends Handler {

    private long mDatagramTransferStartTime = 0;
    private boolean mIsDemoMode = false;
    @GuardedBy("mLock")
    private boolean mIsAligned = false;
    private DatagramReceiverHandlerRequest mPollPendingSatelliteDatagramsRequest = null;
    private final Object mLock = new Object();
@@ -97,7 +99,6 @@ public class DatagramReceiver extends Handler {
    private final ConcurrentHashMap<Long, Integer>
            mPendingAckCountHashMap = new ConcurrentHashMap<>();


    /**
     * Create the DatagramReceiver singleton instance.
     * @param context The Context to use to create the DatagramReceiver.
@@ -331,7 +332,7 @@ public class DatagramReceiver extends Handler {
                    logd("Received EVENT_SATELLITE_DATAGRAM_RECEIVED for subId=" + mSubId
                            + " pendingCount:" + pendingCount);

                    if (pendingCount == 0 && satelliteDatagram == null) {
                    if (pendingCount <= 0 && satelliteDatagram == null) {
                        sInstance.mDatagramController.updateReceiveStatus(mSubId,
                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_NONE,
                                pendingCount, SatelliteManager.SATELLITE_ERROR_NONE);
@@ -372,7 +373,7 @@ public class DatagramReceiver extends Handler {
                        };
                        Consumer<Integer> callback = FunctionalUtils.ignoreRemoteException(
                                internalCallback::accept);
                        sInstance.pollPendingSatelliteDatagrams(mSubId, callback);
                        sInstance.pollPendingSatelliteDatagramsInternal(mSubId, callback);
                    }

                    // Send the captured data about incoming datagram to metric
@@ -583,6 +584,25 @@ public class DatagramReceiver extends Handler {
     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
     */
    public void pollPendingSatelliteDatagrams(int subId, @NonNull Consumer<Integer> callback) {
        if (!mDatagramController.isPollingInIdleState()) {
            // Poll request should be sent to satellite modem only when it is free.
            logd("pollPendingSatelliteDatagrams: satellite modem is busy receiving datagrams.");
            callback.accept(SatelliteManager.SATELLITE_MODEM_BUSY);
            return;
        }

        pollPendingSatelliteDatagramsInternal(subId, callback);
    }

    private void pollPendingSatelliteDatagramsInternal(int subId,
            @NonNull Consumer<Integer> callback) {
        if (!mDatagramController.isSendingInIdleState()) {
            // Poll request should be sent to satellite modem only when it is free.
            logd("pollPendingSatelliteDatagrams: satellite modem is busy sending datagrams.");
            callback.accept(SatelliteManager.SATELLITE_MODEM_BUSY);
            return;
        }

        mDatagramController.updateReceiveStatus(subId,
                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING,
                mDatagramController.getReceivePendingCount(),
@@ -615,13 +635,16 @@ public class DatagramReceiver extends Handler {
     * @param state Current satellite modem state.
     */
    public void onSatelliteModemStateChanged(@SatelliteManager.SatelliteModemState int state) {
        synchronized (mLock) {
            if (state == SatelliteManager.SATELLITE_MODEM_STATE_OFF
                    || state == SatelliteManager.SATELLITE_MODEM_STATE_UNAVAILABLE) {
                logd("onSatelliteModemStateChanged: cleaning up resources");
                cleanUpResources();
            }
        }
    }

    @GuardedBy("mLock")
    private void cleanupDemoModeResources() {
        if (isSatelliteAlignedTimerStarted()) {
            stopSatelliteAlignedTimer();
@@ -639,8 +662,8 @@ public class DatagramReceiver extends Handler {
        mIsAligned = false;
    }

    @GuardedBy("mLock")
    private void cleanUpResources() {
        synchronized (mLock) {
        if (mDatagramController.isReceivingDatagrams()) {
            mDatagramController.updateReceiveStatus(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVE_FAILED,
@@ -652,7 +675,6 @@ public class DatagramReceiver extends Handler {
                SatelliteManager.SATELLITE_ERROR_NONE);
        cleanupDemoModeResources();
    }
    }

    /**
     * Posts the specified command to be executed on the main thread and returns immediately.
+19 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.inOrder;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;

import android.annotation.NonNull;
import android.content.Context;
@@ -101,6 +102,7 @@ public class DatagramDispatcherTest extends TelephonyTest {
        mResultListener = new LinkedBlockingQueue<>(1);
        mDatagram = new SatelliteDatagram(TEST_MESSAGE.getBytes());
        mInOrder = inOrder(mMockDatagramController);
        when(mMockDatagramController.isPollingInIdleState()).thenReturn(true);
    }

    @After
@@ -133,6 +135,7 @@ public class DatagramDispatcherTest extends TelephonyTest {

        processAllMessages();

        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
        mInOrder.verify(mMockDatagramController)
                .updateSendStatus(eq(SUB_ID),
                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
@@ -170,6 +173,7 @@ public class DatagramDispatcherTest extends TelephonyTest {

        processAllMessages();

        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
        mInOrder.verify(mMockDatagramController)
                .updateSendStatus(eq(SUB_ID),
                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
@@ -197,6 +201,7 @@ public class DatagramDispatcherTest extends TelephonyTest {

        processAllMessages();

        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
        mInOrder.verify(mMockDatagramController)
                .updateSendStatus(eq(SUB_ID),
                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
@@ -234,6 +239,7 @@ public class DatagramDispatcherTest extends TelephonyTest {

        processAllMessages();

        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
        mInOrder.verify(mMockDatagramController)
                .updateSendStatus(eq(SUB_ID),
                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
@@ -272,6 +278,7 @@ public class DatagramDispatcherTest extends TelephonyTest {

        processAllMessages();

        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
        mInOrder.verify(mMockDatagramController)
                .updateSendStatus(eq(SUB_ID),
                        eq(SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING), eq(1),
@@ -409,6 +416,18 @@ public class DatagramDispatcherTest extends TelephonyTest {
        mTestDemoModeDatagramDispatcher.onDeviceAlignedWithSatellite(false);
    }

    @Test
    public void testSatelliteModemBusy_modemPollingDatagram_sendingDelayed() {
        when(mMockDatagramController.isPollingInIdleState()).thenReturn(false);

        mDatagramDispatcherUT.sendSatelliteDatagram(SUB_ID, DATAGRAM_TYPE1, mDatagram,
                true, mResultListener::offer);
        processAllMessages();
        // As modem is busy receiving datagrams, sending datagram did not proceed further.
        mInOrder.verify(mMockDatagramController).isPollingInIdleState();
        verifyNoMoreInteractions(mMockDatagramController);
    }

    private static class TestDatagramDispatcher extends DatagramDispatcher {
        private long mLong = SATELLITE_ALIGN_TIMEOUT;

+21 −1
Original line number Diff line number Diff line
@@ -38,7 +38,6 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;


import android.os.AsyncResult;
import android.os.Looper;
import android.os.Message;
@@ -116,6 +115,8 @@ public class DatagramReceiverTest extends TelephonyTest {
        mDatagram = new SatelliteDatagram(TEST_MESSAGE.getBytes());
        mInOrder = inOrder(mMockDatagramController);

        when(mMockDatagramController.isSendingInIdleState()).thenReturn(true);
        when(mMockDatagramController.isPollingInIdleState()).thenReturn(true);
        processAllMessages();
    }

@@ -386,6 +387,25 @@ public class DatagramReceiverTest extends TelephonyTest {
        mTestDemoModeDatagramReceiver.setDuration(previousTimer);
    }

    @Test
    public void testSatelliteModemBusy_modemSendingDatagram_pollingFailure() {
        when(mMockDatagramController.isSendingInIdleState()).thenReturn(false);

        mDatagramReceiverUT.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
        processAllMessages();
        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_MODEM_BUSY);
    }

    @Test
    public void testSatelliteModemBusy_modemPollingDatagrams_pollingFailure() {
        when(mMockDatagramController.isSendingInIdleState()).thenReturn(false);
        when(mMockDatagramController.isPollingInIdleState()).thenReturn(true);

        mDatagramReceiverUT.pollPendingSatelliteDatagrams(SUB_ID, mResultListener::offer);
        processAllMessages();
        assertThat(mResultListener.peek()).isEqualTo(SatelliteManager.SATELLITE_MODEM_BUSY);
    }

    private static class TestDatagramReceiver extends DatagramReceiver {
        private long mLong =  SATELLITE_ALIGN_TIMEOUT;