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

Commit 3dd7975a authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Do not send and receive datagrams at the same time." into udc-dev

parents 2795f8ab 00b0a8d0
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;