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

Commit 06bdaec9 authored by Aishwarya Mallampati's avatar Aishwarya Mallampati
Browse files

Update datagram transfer state.

The following changes are made in this CL:
DatagramDispatcher: updates DatagramController about datagram send status.
- Datagram transfer state is initially set to SENDING when sendSatelliteDatagram() is called, then:
-- State changes to SEND_FAILED on error
-- State changes to SEND_SUCCESS if one datagram is sent successfully
-- State Changes to IDLE if pendingDatagramCount is 0

DatagramReceiver: updates DatagramController about datagram receive status.
- Datagram transfer state is initially set to RECEIVING when pollPendngSatelliteDatagrams() is called, then:
-- State changes to RECEIVE_NONE if pendingCount is 0 and received datagram is null
-- State changes to RECEIVE_SUCCESS if received datagram is not null
-- State changes to IDLE if pending count is 0

DatagramController:
- Stores all the variables needed to update onSendDatagramStateChanged(), onReceiveDatagramStateChanged() and calls PointingAppController where there is change in datagram transfer state.

Bug: 269637555
Test: atest SatelliteManagerTest, Flashed build on raven-userdebug: calls and SMS are working.
Change-Id: Iabb4c805380b0303c922b154817824758fad9dba
parent d638c8c8
Loading
Loading
Loading
Loading
+91 −16
Original line number Diff line number Diff line
@@ -17,17 +17,13 @@
package com.android.internal.telephony.satellite;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.Context;
import android.os.Looper;
import android.os.Message;
import android.telephony.Rlog;
import android.telephony.satellite.ISatelliteDatagramCallback;
import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;

import com.android.internal.telephony.Phone;

import java.util.function.Consumer;

/**
@@ -38,10 +34,24 @@ public class DatagramController {

    @NonNull private static DatagramController sInstance;
    @NonNull private final Context mContext;
    @NonNull private final PointingAppController mPointingAppController;
    @NonNull private final DatagramDispatcher mDatagramDispatcher;
    @NonNull private final DatagramReceiver mDatagramReceiver;
    public static final long MAX_DATAGRAM_ID = (long) Math.pow(2, 16);

    /** Variables used to update onSendDatagramStateChanged(). */
    private int mSendSubId;
    private int mSendDatagramTransferState =
            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN;
    private int mSendPendingCount = 0;
    private int mSendErrorCode = SatelliteManager.SATELLITE_ERROR_NONE;
    /** Variables used to update onReceiveDatagramStateChanged(). */
    private int mReceiveSubId;
    private int mReceiveDatagramTransferState =
            SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_UNKNOWN;
    private int mReceivePendingCount = 0;
    private int mReceiveErrorCode = SatelliteManager.SATELLITE_ERROR_NONE;

    /**
     * @return The singleton instance of DatagramController.
     */
@@ -56,11 +66,14 @@ public class DatagramController {
     * Create the DatagramController singleton instance.
     * @param context The Context to use to create the DatagramController.
     * @param looper The looper for the handler.
     * @param pointingAppController PointingAppController is used to update
     *                              PointingApp about datagram transfer state changes.
     * @return The singleton instance of DatagramController.
     */
    public static DatagramController make(@NonNull Context context, @NonNull Looper looper) {
    public static DatagramController make(@NonNull Context context, @NonNull Looper looper,
            @NonNull PointingAppController pointingAppController) {
        if (sInstance == null) {
            sInstance = new DatagramController(context, looper);
            sInstance = new DatagramController(context, looper, pointingAppController);
        }
        return sInstance;
    }
@@ -69,17 +82,22 @@ public class DatagramController {
     * Create a DatagramController to send and receive satellite datagrams.
     *
     * @param context The Context for the DatagramController.
     * @param looper The looper for the handler.
     * @param looper The looper for the handler
     * @param pointingAppController PointingAppController is used to update PointingApp
     *                              about datagram transfer state changes.
     */
    private DatagramController(@NonNull Context context, @NonNull Looper  looper) {
    private DatagramController(@NonNull Context context, @NonNull Looper  looper,
            @NonNull PointingAppController pointingAppController) {
        mContext = context;
        mPointingAppController = pointingAppController;

        // Create the DatagramDispatcher singleton,
        // which is used to send satellite datagrams.
        mDatagramDispatcher = DatagramDispatcher.make(mContext, looper);
        mDatagramDispatcher = DatagramDispatcher.make(mContext, looper, this);

        // Create the DatagramReceiver singleton,
        // which is used to receive satellite datagrams.
        mDatagramReceiver = DatagramReceiver.make(mContext, looper);
        mDatagramReceiver = DatagramReceiver.make(mContext, looper, this);
    }

    /**
@@ -116,10 +134,11 @@ public class DatagramController {
     * {@link android.telephony.satellite.SatelliteDatagramCallback
     * #onSatelliteDatagramReceived(long, SatelliteDatagram, int, ILongConsumer)}
     *
     * @param subId The subId of the subscription used for receiving datagrams.
     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
     */
    public void pollPendingSatelliteDatagrams(@NonNull Message message, @Nullable Phone phone) {
        // TODO: set modemTransferState = SATELLITE_DATAGRAM_TRANSFER_STATE_RECEIVING
        mDatagramReceiver.pollPendingSatelliteDatagrams(message, phone);
    public void pollPendingSatelliteDatagrams(int subId, @NonNull Consumer<Integer> callback) {
        mDatagramReceiver.pollPendingSatelliteDatagrams(subId, callback);
    }

    /**
@@ -129,6 +148,7 @@ public class DatagramController {
     * input to this method. Datagram received here will be passed down to modem without any
     * encoding or encryption.
     *
     * @param subId The subId of the subscription to send satellite datagrams for.
     * @param datagramType datagram type indicating whether the datagram is of type
     *                     SOS_SMS or LOCATION_SHARING.
     * @param datagram encoded gateway datagram which is encrypted by the caller.
@@ -137,14 +157,69 @@ public class DatagramController {
     *                                 full screen mode.
     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
     */
    public void sendSatelliteDatagram(@SatelliteManager.DatagramType int datagramType,
    public void sendSatelliteDatagram(int subId, @SatelliteManager.DatagramType int datagramType,
            @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
            @NonNull Consumer<Integer> callback) {
        // TODO: set modemTransferState = SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING
        mDatagramDispatcher.sendSatelliteDatagram(datagramType, datagram,
        mDatagramDispatcher.sendSatelliteDatagram(subId, datagramType, datagram,
                needFullScreenPointingUI, callback);
    }

    /**
     * Update send status to {@link PointingAppController}.
     *
     * @param subId The subId of the subscription to send satellite datagrams for
     * @param datagramTransferState The new send datagram transfer state.
     * @param sendPendingCount number of datagrams that are currently being sent
     * @param errorCode If datagram transfer failed, the reason for failure.
     */
    public void updateSendStatus(int subId,
            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
            int sendPendingCount, int errorCode) {
        logd("updateSendStatus"
                + " subId: " + subId
                + " datagramTransferState: " + datagramTransferState
                + " sendPendingCount: " + sendPendingCount + " errorCode: " + errorCode);

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

    /**
     * Update receive status to {@link PointingAppController}.
     *
     * @param subId The subId of the subscription used to receive datagrams
     * @param datagramTransferState The new receive datagram transfer state.
     * @param receivePendingCount The number of datagrams that are currently pending to be received.
     * @param errorCode If datagram transfer failed, the reason for failure.
     */
    public void updateReceiveStatus(int subId,
            @SatelliteManager.SatelliteDatagramTransferState int datagramTransferState,
            int receivePendingCount, int errorCode) {
        logd("updateReceiveStatus"
                + " subId: " + subId
                + " datagramTransferState: " + datagramTransferState
                + " receivePendingCount: " + receivePendingCount + " errorCode: " + errorCode);

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

    /**
     * Return receive pending datagram count
     * @return receive pending datagram count.
     */
    public int getReceivePendingCount() {
        return mReceivePendingCount;
    }

    private static void logd(@NonNull String log) {
        Rlog.d(TAG, log);
    }
+128 −41
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.telephony.satellite.SatelliteDatagram;
import android.telephony.satellite.SatelliteManager;

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

import java.util.LinkedHashMap;
@@ -47,6 +48,7 @@ public class DatagramDispatcher extends Handler {

    @NonNull private static DatagramDispatcher sInstance;
    @NonNull private final Context mContext;
    @NonNull private final DatagramController mDatagramController;

    private static AtomicLong mNextDatagramId = new AtomicLong(0);

@@ -75,11 +77,13 @@ public class DatagramDispatcher extends Handler {
     * Create the DatagramDispatcher singleton instance.
     * @param context The Context to use to create the DatagramDispatcher.
     * @param looper The looper for the handler.
     * @param datagramController DatagramController which is used to update datagram transfer state.
     * @return The singleton instance of DatagramDispatcher.
     */
    public static DatagramDispatcher make(@NonNull Context context, @NonNull Looper looper) {
    public static DatagramDispatcher make(@NonNull Context context, @NonNull Looper looper,
            @NonNull DatagramController datagramController) {
        if (sInstance == null) {
            sInstance = new DatagramDispatcher(context, looper);
            sInstance = new DatagramDispatcher(context, looper, datagramController);
        }
        return sInstance;
    }
@@ -89,10 +93,14 @@ public class DatagramDispatcher extends Handler {
     *
     * @param context The Context for the DatagramDispatcher.
     * @param looper The looper for the handler.
     * @param datagramController DatagramController which is used to update datagram transfer state.
     */
    private DatagramDispatcher(@NonNull Context context, @NonNull Looper looper) {
    private DatagramDispatcher(@NonNull Context context, @NonNull Looper looper,
            @NonNull DatagramController datagramController) {
        super(looper);
        mContext = context;
        mDatagramController = datagramController;

        synchronized (mLock) {
            mSendingDatagramInProgress = false;
        }
@@ -113,16 +121,18 @@ public class DatagramDispatcher extends Handler {
    }

    private static final class SendSatelliteDatagramArgument {
        public int subId;
        public long datagramId;
        public @SatelliteManager.DatagramType int datagramType;
        public @NonNull SatelliteDatagram datagram;
        public boolean needFullScreenPointingUI;
        public @NonNull Consumer<Integer> callback;

        SendSatelliteDatagramArgument(long datagramId,
        SendSatelliteDatagramArgument(int subId, long datagramId,
                @SatelliteManager.DatagramType int datagramType,
                @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
                @NonNull Consumer<Integer> callback) {
            this.subId = subId;
            this.datagramId = datagramId;
            this.datagramType = datagramType;
            this.datagram = datagram;
@@ -139,16 +149,19 @@ public class DatagramDispatcher extends Handler {

        switch(msg.what) {
            case CMD_SEND_SATELLITE_DATAGRAM: {
                logd("CMD_SEND_SATELLITE_DATAGRAM");
                request = (DatagramDispatcherHandlerRequest) msg.obj;
                SendSatelliteDatagramArgument argument =
                        (SendSatelliteDatagramArgument) request.argument;
                onCompleted = obtainMessage(EVENT_SEND_SATELLITE_DATAGRAM_DONE, request);

                if (SatelliteModemInterface.getInstance().isSatelliteServiceSupported()) {
                    SatelliteModemInterface.getInstance().sendSatelliteDatagram(argument.datagram,
                            argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
                            argument.needFullScreenPointingUI, onCompleted);
                    break;
                }

                Phone phone = request.phone;
                if (phone != null) {
                    phone.sendSatelliteDatagram(onCompleted, argument.datagram,
@@ -156,6 +169,19 @@ public class DatagramDispatcher extends Handler {
                } else {
                    loge("sendSatelliteDatagram: No phone object");
                    argument.callback.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);

                    synchronized (mLock) {
                        // 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_INVALID_TELEPHONY_STATE);
                    }
                }
                break;
            }
@@ -166,30 +192,38 @@ public class DatagramDispatcher extends Handler {
                int error = SatelliteServiceUtils.getSatelliteError(ar, "sendSatelliteDatagram");
                SendSatelliteDatagramArgument argument =
                        (SendSatelliteDatagramArgument) request.argument;
                logd("EVENT_SEND_SATELLITE_DATAGRAM_DONE error: " + error);

                synchronized (mLock) {
                    mSendingDatagramInProgress = false;
                }

                // Send response for current datagram
                    // Send response for current datagram and remove it from pending map.
                    argument.callback.accept(error);
                synchronized (mLock) {
                    if (argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
                        mPendingEmergencyDatagramsMap.remove(argument.datagramId);
                    } else {
                        mPendingNonEmergencyDatagramsMap.remove(argument.datagramId);
                    }
                }

                // Handle pending datagrams
                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
                        // Update send status for current datagram
                        mDatagramController.updateSendStatus(argument.subId,
                                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_SUCCESS,
                                getPendingDatagramCount(), error);

                        if (getPendingDatagramCount() != 0) {
                            // Send pending datagrams
                            sendPendingDatagrams();
                        } else {
                    // TODO: set modemTransferState = SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED.
                    sendErrorCodeAndCleanupPendingDatagrams(mPendingEmergencyDatagramsMap,
                            SatelliteManager.SATELLITE_REQUEST_ABORTED);
                    sendErrorCodeAndCleanupPendingDatagrams(mPendingNonEmergencyDatagramsMap,
                            SatelliteManager.SATELLITE_REQUEST_ABORTED);
                            mDatagramController.updateSendStatus(argument.subId,
                                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
                                    getPendingDatagramCount(),
                                    SatelliteManager.SATELLITE_ERROR_NONE);
                        }
                    } else {
                        // Abort sending all the pending datagrams
                        abortSendingPendingDatagrams(argument.subId, error);
                    }
                }
                break;
            }
@@ -207,6 +241,7 @@ public class DatagramDispatcher extends Handler {
     * input to this method. Datagram received here will be passed down to modem without any
     * encoding or encryption.
     *
     * @param subId The subId of the subscription to send satellite datagrams for.
     * @param datagramType datagram type indicating whether the datagram is of type
     *                     SOS_SMS or LOCATION_SHARING.
     * @param datagram encoded gateway datagram which is encrypted by the caller.
@@ -215,15 +250,16 @@ public class DatagramDispatcher extends Handler {
     *                                 full screen mode.
     * @param callback The callback to get {@link SatelliteManager.SatelliteError} of the request.
     */
    public void sendSatelliteDatagram(@SatelliteManager.DatagramType int datagramType,
    public void sendSatelliteDatagram(int subId, @SatelliteManager.DatagramType int datagramType,
            @NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
            @NonNull Consumer<Integer> callback) {
        Phone phone = SatelliteServiceUtils.getPhone();

        long datagramId = mNextDatagramId.getAndUpdate(
                n -> ((n + 1) % DatagramController.MAX_DATAGRAM_ID));
        SendSatelliteDatagramArgument datagramArgs = new SendSatelliteDatagramArgument(datagramId,
                datagramType, datagram, needFullScreenPointingUI, callback);

        SendSatelliteDatagramArgument datagramArgs = new SendSatelliteDatagramArgument(subId,
                datagramId, datagramType, datagram, needFullScreenPointingUI, callback);

        synchronized (mLock) {
            if (datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE) {
@@ -235,6 +271,9 @@ public class DatagramDispatcher extends Handler {
            if (!mSendingDatagramInProgress) {
                mSendingDatagramInProgress = true;
                sendRequestAsync(CMD_SEND_SATELLITE_DATAGRAM, datagramArgs, phone);
                mDatagramController.updateSendStatus(subId,
                        SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
                        getPendingDatagramCount(), SatelliteManager.SATELLITE_ERROR_NONE);
            }
        }
    }
@@ -243,10 +282,11 @@ public class DatagramDispatcher extends Handler {
     * Send pending satellite datagrams. Emergency datagrams are given priority over
     * non-emergency datagrams.
     */
    @GuardedBy("mLock")
    private void sendPendingDatagrams() {
        logd("sendPendingDatagrams()");
        Phone phone = SatelliteServiceUtils.getPhone();
        Set<Entry<Long, SendSatelliteDatagramArgument>> pendingDatagram = null;
        synchronized (mLock) {
        if (!mSendingDatagramInProgress && !mPendingEmergencyDatagramsMap.isEmpty()) {
            pendingDatagram = mPendingEmergencyDatagramsMap.entrySet();
        } else if (!mSendingDatagramInProgress && !mPendingNonEmergencyDatagramsMap.isEmpty()) {
@@ -255,9 +295,12 @@ public class DatagramDispatcher extends Handler {

        if ((pendingDatagram != null) && pendingDatagram.iterator().hasNext()) {
            mSendingDatagramInProgress = true;
                sendRequestAsync(CMD_SEND_SATELLITE_DATAGRAM,
                        pendingDatagram.iterator().next().getValue(), phone);
            }
            SendSatelliteDatagramArgument datagramArg =
                    pendingDatagram.iterator().next().getValue();
            sendRequestAsync(CMD_SEND_SATELLITE_DATAGRAM, datagramArg, phone);
            mDatagramController.updateSendStatus(datagramArg.subId,
                    SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SENDING,
                    getPendingDatagramCount(), SatelliteManager.SATELLITE_ERROR_NONE);
        }
    }

@@ -265,10 +308,14 @@ public class DatagramDispatcher extends Handler {
     * Send error code to all the pending datagrams
     * @param errorCode error code to be returned.
     */
    @GuardedBy("mLock")
    private void sendErrorCodeAndCleanupPendingDatagrams(
            LinkedHashMap<Long, SendSatelliteDatagramArgument> pendingDatagramsMap,
            @SatelliteManager.SatelliteError int errorCode) {
        synchronized (mLock) {
        if (pendingDatagramsMap.size() == 0) {
            return;
        }

        // Send error code to all the pending datagrams
        for (Entry<Long, SendSatelliteDatagramArgument> entry :
                pendingDatagramsMap.entrySet()) {
@@ -279,6 +326,38 @@ public class DatagramDispatcher extends Handler {
        // Clear pending datagram maps
        pendingDatagramsMap.clear();
    }

    /**
     * Abort sending all the pending datagrams.
     *
     * @param subId the subId of the subscription used to send datagram
     * @param error error that resulted in abort.
     */
    @GuardedBy("mLock")
    private void abortSendingPendingDatagrams(int subId,
            @SatelliteManager.SatelliteError int error) {
        logd("abortSendingPendingDatagrams()");
        sendErrorCodeAndCleanupPendingDatagrams(mPendingEmergencyDatagramsMap,
                SatelliteManager.SATELLITE_REQUEST_ABORTED);
        sendErrorCodeAndCleanupPendingDatagrams(mPendingNonEmergencyDatagramsMap,
                SatelliteManager.SATELLITE_REQUEST_ABORTED);

        // Update send status
        mDatagramController.updateSendStatus(subId,
                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_SEND_FAILED,
                getPendingDatagramCount(), error);
        mDatagramController.updateSendStatus(subId,
                SatelliteManager.SATELLITE_DATAGRAM_TRANSFER_STATE_IDLE,
                getPendingDatagramCount(), SatelliteManager.SATELLITE_ERROR_NONE);
    }

    /**
     * Return pending datagram count
     * @return pending datagram count
     */
    @GuardedBy("mLock")
    private int getPendingDatagramCount() {
        return mPendingEmergencyDatagramsMap.size() + mPendingNonEmergencyDatagramsMap.size();
    }

    /**
@@ -295,6 +374,14 @@ public class DatagramDispatcher extends Handler {
        msg.sendToTarget();
    }

    /**
     * Destroys this DatagramDispatcher. Used for tearing down static resources during testing.
     */
    @VisibleForTesting
    public void destroy() {
        sInstance = null;
    }

    private static void logd(@NonNull String log) {
        Rlog.d(TAG, log);
    }
+159 −33

File changed.

Preview size limit exceeded, changes collapsed.

+75 −9

File changed.

Preview size limit exceeded, changes collapsed.

+17 −31
Original line number Diff line number Diff line
@@ -85,13 +85,11 @@ public class SatelliteController extends Handler {
    private static final int EVENT_IS_SATELLITE_SUPPORTED_DONE = 16;
    private static final int CMD_GET_SATELLITE_CAPABILITIES = 17;
    private static final int EVENT_GET_SATELLITE_CAPABILITIES_DONE = 18;
    private static final int CMD_POLL_PENDING_SATELLITE_DATAGRAMS = 19;
    private static final int EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE = 20;
    private static final int CMD_IS_SATELLITE_COMMUNICATION_ALLOWED = 21;
    private static final int EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE = 22;
    private static final int CMD_GET_TIME_SATELLITE_NEXT_VISIBLE = 23;
    private static final int EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE = 24;
    private static final int EVENT_RADIO_STATE_CHANGED = 25;
    private static final int CMD_IS_SATELLITE_COMMUNICATION_ALLOWED = 19;
    private static final int EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE = 20;
    private static final int CMD_GET_TIME_SATELLITE_NEXT_VISIBLE = 21;
    private static final int EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE = 22;
    private static final int EVENT_RADIO_STATE_CHANGED = 23;

    @NonNull private static SatelliteController sInstance;
    @NonNull private final Context mContext;
@@ -179,7 +177,7 @@ public class SatelliteController extends Handler {

        // Create the DatagramController singleton,
        // which is used to send and receive satellite datagrams.
        mDatagramController = DatagramController.make(mContext, looper);
        mDatagramController = DatagramController.make(mContext, looper, mPointingAppController);

        mSatelliteSupportedReceiver = new ResultReceiver(this) {
            @Override
@@ -367,7 +365,13 @@ public class SatelliteController extends Handler {
                }
                case EVENT_PENDING_DATAGRAMS: {
                    logd("Received EVENT_PENDING_DATAGRAMS for subId=" + mSubId);
                    // TODO: call pollPendingSatelliteDatagrams
                    IIntegerConsumer internalCallback = new IIntegerConsumer.Stub() {
                        @Override
                        public void accept(int result) {
                            logd("pollPendingSatelliteDatagram result: " + result);
                        }
                    };
                    sInstance.pollPendingSatelliteDatagrams(mSubId, internalCallback);
                    break;
                }
                default:
@@ -675,23 +679,6 @@ public class SatelliteController extends Handler {
                break;
            }

            case CMD_POLL_PENDING_SATELLITE_DATAGRAMS: {
                request = (SatelliteControllerHandlerRequest) msg.obj;
                onCompleted =
                        obtainMessage(EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE, request);
                mDatagramController.pollPendingSatelliteDatagrams(onCompleted, request.phone);
                break;
            }

            case EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE: {
                ar = (AsyncResult) msg.obj;
                request = (SatelliteControllerHandlerRequest) ar.userObj;
                int error = SatelliteServiceUtils.getSatelliteError(ar,
                        "pollPendingSatelliteDatagrams");
                ((Consumer<Integer>) request.argument).accept(error);
                break;
            }

            case CMD_IS_SATELLITE_COMMUNICATION_ALLOWED: {
                request = (SatelliteControllerHandlerRequest) msg.obj;
                onCompleted =
@@ -1267,9 +1254,7 @@ public class SatelliteController extends Handler {
            return;
        }

        Phone phone = SatelliteServiceUtils.getPhone();
        sendRequestAsync(CMD_POLL_PENDING_SATELLITE_DATAGRAMS, result, phone);
        // TODO: return pending datagram count
        mDatagramController.pollPendingSatelliteDatagrams(subId, result);
    }

    /**
@@ -1306,8 +1291,9 @@ public class SatelliteController extends Handler {
        if (mNeedsSatellitePointing) {
            mPointingAppController.startPointingUI(needFullScreenPointingUI);
        }
        mDatagramController.sendSatelliteDatagram(datagramType, datagram, needFullScreenPointingUI,
                result);

        mDatagramController.sendSatelliteDatagram(validSubId, datagramType, datagram,
                needFullScreenPointingUI, result);
    }

    /**
Loading