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

Commit 7358e7f8 authored by Thomas Nguyen's avatar Thomas Nguyen Committed by Android (Google) Code Review
Browse files

Merge "Add timeout in enabling satellite and sending datagram" into main

parents bdb00c5b d3e50782
Loading
Loading
Loading
Loading
+58 −11
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@ package com.android.internal.telephony.satellite;

import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_DATAGRAM_TRANSFERRING;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_IDLE;
import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_OFF;

import android.annotation.NonNull;
import android.content.Context;
@@ -29,6 +31,7 @@ import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;

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

@@ -50,8 +53,12 @@ public class DatagramController {
    public static final long MAX_DATAGRAM_ID = (long) Math.pow(2, 16);
    public static final int ROUNDING_UNIT = 10;
    public static final long SATELLITE_ALIGN_TIMEOUT = TimeUnit.SECONDS.toMillis(30);
    public static final long DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMEOUT =
            TimeUnit.SECONDS.toMillis(60);
    /** This type is used by CTS to override the satellite align timeout */
    public static final int TIMEOUT_TYPE_ALIGN = 1;
    /** This type is used by CTS to override the time to wait for connected state */
    public static final int TIMEOUT_TYPE_DATAGRAM_WAIT_FOR_CONNECTED_STATE = 2;
    /** This type is used by CTS to override the time to wait for response of the send request */
    public static final int TIMEOUT_TYPE_WAIT_FOR_DATAGRAM_SENDING_RESPONSE = 3;
    private static final String ALLOW_MOCK_MODEM_PROPERTY = "persist.radio.allow_mock_modem";
    private static final boolean DEBUG = !"user".equals(Build.TYPE);

@@ -80,7 +87,8 @@ public class DatagramController {
    private SatelliteDatagram mDemoModeDatagram;
    private boolean mIsDemoMode = false;
    private long mAlignTimeoutDuration = SATELLITE_ALIGN_TIMEOUT;
    private long mDatagramWaitTimeForConnectedState = DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMEOUT;
    private long mDatagramWaitTimeForConnectedState;
    private long mModemImageSwitchingDuration;
    @GuardedBy("mLock")
    @SatelliteManager.SatelliteModemState
    private int mSatelltieModemState = SatelliteManager.SATELLITE_MODEM_STATE_UNKNOWN;
@@ -132,6 +140,9 @@ public class DatagramController {
        // Create the DatagramReceiver singleton,
        // which is used to receive satellite datagrams.
        mDatagramReceiver = DatagramReceiver.make(mContext, looper, this);

        mDatagramWaitTimeForConnectedState = getDatagramWaitForConnectedStateTimeoutMillis();
        mModemImageSwitchingDuration = getSatelliteModemImageSwitchingDurationMillis();
    }

    /**
@@ -367,25 +378,51 @@ public class DatagramController {

    @VisibleForTesting(visibility = VisibleForTesting.Visibility.PACKAGE)
    public long getDatagramWaitTimeForConnectedState() {
        synchronized (mLock) {
            if (mSatelltieModemState == SATELLITE_MODEM_STATE_OFF
                    || mSatelltieModemState == SATELLITE_MODEM_STATE_IDLE) {
                return (mDatagramWaitTimeForConnectedState + mModemImageSwitchingDuration);
            }
            return mDatagramWaitTimeForConnectedState;
        }
    }

    /**
     * This API can be used by only CTS to update the timeout duration in milliseconds whether
     * the device is aligned with the satellite for demo mode
     * This API can be used by only CTS to timeout durations used by DatagramController module.
     *
     * @param timeoutMillis The timeout duration in millisecond.
     * @return {@code true} if the timeout duration is set successfully, {@code false} otherwise.
     */
    boolean setSatelliteDeviceAlignedTimeoutDuration(long timeoutMillis) {
    boolean setDatagramControllerTimeoutDuration(
            boolean reset, int timeoutType, long timeoutMillis) {
        if (!isMockModemAllowed()) {
            loge("Updating align timeout duration is not allowed");
            loge("Updating timeout duration is not allowed");
            return false;
        }

        logd("setSatelliteDeviceAlignedTimeoutDuration: timeoutMillis=" + timeoutMillis);
        logd("setDatagramControllerTimeoutDuration: timeoutMillis=" + timeoutMillis
                + ", reset=" + reset + ", timeoutType=" + timeoutType);
        if (timeoutType == TIMEOUT_TYPE_ALIGN) {
            if (reset) {
                mAlignTimeoutDuration = SATELLITE_ALIGN_TIMEOUT;
            } else {
                mAlignTimeoutDuration = timeoutMillis;
            }
        } else if (timeoutType == TIMEOUT_TYPE_DATAGRAM_WAIT_FOR_CONNECTED_STATE) {
            if (reset) {
                mDatagramWaitTimeForConnectedState =
                        getDatagramWaitForConnectedStateTimeoutMillis();
                mModemImageSwitchingDuration = getSatelliteModemImageSwitchingDurationMillis();
            } else {
                mDatagramWaitTimeForConnectedState = timeoutMillis;
                mModemImageSwitchingDuration = 0;
            }
        } else if (timeoutType == TIMEOUT_TYPE_WAIT_FOR_DATAGRAM_SENDING_RESPONSE) {
            mDatagramDispatcher.setWaitTimeForDatagramSendingResponse(reset, timeoutMillis);
        } else {
            loge("Invalid timeout type " + timeoutType);
            return false;
        }
        return true;
    }

@@ -404,6 +441,16 @@ public class DatagramController {
        }
    }

    private long getDatagramWaitForConnectedStateTimeoutMillis() {
        return mContext.getResources().getInteger(
                R.integer.config_datagram_wait_for_connected_state_timeout_millis);
    }

    private long getSatelliteModemImageSwitchingDurationMillis() {
        return mContext.getResources().getInteger(
                R.integer.config_satellite_modem_image_switching_duration_millis);
    }

    /**
     * This API can be used by only CTS to override the cached value for the device overlay config
     * value : config_send_satellite_datagram_to_modem_in_demo_mode, which determines whether
+119 −10
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
package com.android.internal.telephony.satellite;

import static android.telephony.satellite.SatelliteManager.SATELLITE_MODEM_STATE_CONNECTED;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_MODEM_TIMEOUT;
import static android.telephony.satellite.SatelliteManager.SATELLITE_RESULT_SUCCESS;

import static com.android.internal.telephony.satellite.DatagramController.ROUNDING_UNIT;
@@ -58,6 +59,8 @@ public class DatagramDispatcher extends Handler {
    private static final int EVENT_SEND_SATELLITE_DATAGRAM_DONE = 2;
    private static final int EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT = 3;
    private static final int EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT = 4;
    private static final int EVENT_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_TIMED_OUT = 5;
    private static final int EVENT_ABORT_SENDING_SATELLITE_DATAGRAMS_DONE = 6;

    @NonNull private static DatagramDispatcher sInstance;
    @NonNull private final Context mContext;
@@ -93,6 +96,8 @@ public class DatagramDispatcher extends Handler {
    private final LinkedHashMap<Long, SendSatelliteDatagramArgument>
            mPendingNonEmergencyDatagramsMap = new LinkedHashMap<>();

    private long mWaitTimeForDatagramSendingResponse;

    /**
     * Create the DatagramDispatcher singleton instance.
     * @param context The Context to use to create the DatagramDispatcher.
@@ -126,6 +131,7 @@ public class DatagramDispatcher extends Handler {
        synchronized (mLock) {
            mSendingDatagramInProgress = false;
        }
        mWaitTimeForDatagramSendingResponse = getWaitForDatagramSendingResponseTimeoutMillis();
    }

    private static final class DatagramDispatcherHandlerRequest {
@@ -196,13 +202,17 @@ public class DatagramDispatcher extends Handler {
                        (SendSatelliteDatagramArgument) request.argument;
                onCompleted = obtainMessage(EVENT_SEND_SATELLITE_DATAGRAM_DONE, request);

                synchronized (mLock) {
                    if (mIsDemoMode && !shouldSendDatagramToModemInDemoMode()) {
                        AsyncResult.forMessage(onCompleted, SATELLITE_RESULT_SUCCESS, null);
                        onCompleted.sendToTarget();
                    } else {
                    SatelliteModemInterface.getInstance().sendSatelliteDatagram(argument.datagram,
                        SatelliteModemInterface.getInstance().sendSatelliteDatagram(
                                argument.datagram,
                                argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
                                argument.needFullScreenPointingUI, onCompleted);
                        startWaitForDatagramSendingResponseTimer(argument);
                    }
                }
                break;
            }
@@ -223,13 +233,25 @@ public class DatagramDispatcher extends Handler {
                            break;
                        }
                    }

                    logd("EVENT_SEND_SATELLITE_DATAGRAM_DONE error: " + error);
                    // log metrics about the outgoing datagram
                    reportSendDatagramCompleted(argument, error);

                    /*
                     * The response should be ignored if either of the following hold
                     * 1) Framework has already received this response from the vendor service.
                     * 2) Framework has timed out to wait for the response from vendor service for
                     *    the send request.
                     * 3) All pending send requests have been aborted due to some error.
                     */
                    if (!shouldProcessEventSendSatelliteDatagramDone(argument)) {
                        logw("The message " + argument.datagramId + " was already processed");
                        break;
                    }

                    stopWaitForDatagramSendingResponseTimer();
                    mSendingDatagramInProgress = false;

                    // Log metrics about the outgoing datagram
                    reportSendDatagramCompleted(argument, error);
                    // Remove current datagram from pending map.
                    if (argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
                        mPendingEmergencyDatagramsMap.remove(argument.datagramId);
@@ -278,6 +300,11 @@ public class DatagramDispatcher extends Handler {
                break;
            }

            case EVENT_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_TIMED_OUT:
                handleEventWaitForDatagramSendingResponseTimedOut(
                        (SendSatelliteDatagramArgument) msg.obj);
                break;

            case EVENT_WAIT_FOR_DEVICE_ALIGNMENT_IN_DEMO_MODE_TIMED_OUT: {
                handleEventSatelliteAlignedTimeout((DatagramDispatcherHandlerRequest) msg.obj);
                break;
@@ -596,6 +623,7 @@ public class DatagramDispatcher extends Handler {

        stopSatelliteAlignedTimer();
        stopDatagramWaitForConnectedStateTimer();
        stopWaitForDatagramSendingResponseTimer();
        mIsDemoMode = false;
        mSendSatelliteDatagramRequest = null;
        mIsAligned = false;
@@ -620,6 +648,32 @@ public class DatagramDispatcher extends Handler {
        return hasMessages(EVENT_DATAGRAM_WAIT_FOR_CONNECTED_STATE_TIMED_OUT);
    }

    /**
     * This API is used by CTS tests to override the mWaitTimeForDatagramSendingResponse.
     */
    void setWaitTimeForDatagramSendingResponse(boolean reset, long timeoutMillis) {
        if (reset) {
            mWaitTimeForDatagramSendingResponse = getWaitForDatagramSendingResponseTimeoutMillis();
        } else {
            mWaitTimeForDatagramSendingResponse = timeoutMillis;
        }
    }

    private void startWaitForDatagramSendingResponseTimer(
            @NonNull SendSatelliteDatagramArgument argument) {
        if (hasMessages(EVENT_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_TIMED_OUT)) {
            logd("WaitForDatagramSendingResponseTimer was already started");
            return;
        }
        sendMessageDelayed(obtainMessage(
                EVENT_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_TIMED_OUT, argument),
                mWaitTimeForDatagramSendingResponse);
    }

    private void stopWaitForDatagramSendingResponseTimer() {
        removeMessages(EVENT_WAIT_FOR_DATAGRAM_SENDING_RESPONSE_TIMED_OUT);
    }

    private void handleEventDatagramWaitForConnectedStateTimedOut() {
        logw("Timed out to wait for satellite connected before sending datagrams");
        synchronized (mLock) {
@@ -654,6 +708,61 @@ public class DatagramDispatcher extends Handler {
        }
    }

    private long getWaitForDatagramSendingResponseTimeoutMillis() {
        return mContext.getResources().getInteger(
                R.integer.config_wait_for_datagram_sending_response_timeout_millis);
    }

    private boolean shouldProcessEventSendSatelliteDatagramDone(
            @NonNull SendSatelliteDatagramArgument argument) {
        synchronized (mLock) {
            if (argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
                return mPendingEmergencyDatagramsMap.containsKey(argument.datagramId);
            } else {
                return mPendingNonEmergencyDatagramsMap.containsKey(argument.datagramId);
            }
        }
    }

    private void handleEventWaitForDatagramSendingResponseTimedOut(
            @NonNull SendSatelliteDatagramArgument argument) {
        synchronized (mLock) {
            logw("Timed out to wait for the response of the request to send the datagram "
                    + argument.datagramId);

            // Ask vendor service to abort all datagram-sending requests
            SatelliteModemInterface.getInstance().abortSendingSatelliteDatagrams(
                    obtainMessage(EVENT_ABORT_SENDING_SATELLITE_DATAGRAMS_DONE, argument));
            mSendingDatagramInProgress = false;

            // Update send status
            mDatagramController.updateSendStatus(argument.subId,
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED,
                    getPendingDatagramCount(), SATELLITE_RESULT_MODEM_TIMEOUT);
            mDatagramController.updateSendStatus(argument.subId,
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
                    0, SatelliteManager.SATELLITE_RESULT_SUCCESS);

            // Send response for current datagram after updating datagram transfer state
            // internally.
            argument.callback.accept(SATELLITE_RESULT_MODEM_TIMEOUT);

            // Log metrics about the outgoing datagram
            reportSendDatagramCompleted(argument, SATELLITE_RESULT_MODEM_TIMEOUT);
            mControllerMetricsStats.reportOutgoingDatagramFailCount(argument.datagramType);
            // Remove current datagram from pending map.
            if (argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
                mPendingEmergencyDatagramsMap.remove(argument.datagramId);
            } else {
                mPendingNonEmergencyDatagramsMap.remove(argument.datagramId);
            }

            // Abort sending all the pending datagrams
            abortSendingPendingDatagrams(argument.subId,
                    SatelliteManager.SATELLITE_RESULT_REQUEST_ABORTED);
        }
    }

    /**
     * This API can be used by only CTS to override the cached value for the device overlay config
     * value : config_send_satellite_datagram_to_modem_in_demo_mode, which determines whether
+181 −5

File changed.

Preview size limit exceeded, changes collapsed.

+29 −0
Original line number Diff line number Diff line
@@ -1317,6 +1317,35 @@ public class SatelliteModemInterface {
        }
    }

    /**
     * The satellite service should abort all datagram-sending requests.
     *
     * @param message The Message to send to result of the operation to.
     */
    public void abortSendingSatelliteDatagrams(@NonNull Message message) {
        if (mSatelliteService != null) {
            try {
                mSatelliteService.abortSendingSatelliteDatagrams(new IIntegerConsumer.Stub() {
                    @Override
                    public void accept(int result) {
                        int error = SatelliteServiceUtils.fromSatelliteError(result);
                        logd("abortSendingSatelliteDatagrams: " + error);
                        Binder.withCleanCallingIdentity(() ->
                                sendMessageWithResult(message, null, error));
                    }
                });
            } catch (RemoteException e) {
                loge("abortSendingSatelliteDatagrams: RemoteException " + e);
                sendMessageWithResult(message, null,
                        SatelliteManager.SATELLITE_RESULT_SERVICE_ERROR);
            }
        } else {
            loge("abortSendingSatelliteDatagrams: Satellite service is unavailable.");
            sendMessageWithResult(message, null,
                    SatelliteManager.SATELLITE_RESULT_RADIO_NOT_AVAILABLE);
        }
    }

    public boolean isSatelliteServiceSupported() {
        return mIsSatelliteServiceSupported;
    }
+1 −0
Original line number Diff line number Diff line
@@ -358,6 +358,7 @@ public class SatelliteSessionController extends StateMachine {
        }
        return true;
    }

    /**
     * Adjusts listening timeout duration when demo mode is on
     *
Loading