diff --git a/src/com/android/phone/PhoneGlobals.java b/src/com/android/phone/PhoneGlobals.java
index 6e8971e..7a61dd1 100644
--- a/src/com/android/phone/PhoneGlobals.java
+++ b/src/com/android/phone/PhoneGlobals.java
@@ -74,7 +74,7 @@
 import com.android.internal.telephony.ims.ImsResolver;
 import com.android.internal.telephony.imsphone.ImsPhone;
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
-import com.android.internal.telephony.satellite.SatelliteServiceController;
+import com.android.internal.telephony.satellite.SatelliteController;
 import com.android.internal.telephony.uicc.UiccPort;
 import com.android.internal.telephony.uicc.UiccProfile;
 import com.android.internal.util.IndentingPrintWriter;
@@ -511,9 +511,9 @@
             // status bar icons and control other status bar behavior.
             notificationMgr = NotificationMgr.init(this);
 
-            // Create the SatelliteServiceController singleton, which is used to manage connections
-            // to the satellite service.
-            SatelliteServiceController.make(this);
+            // Create the SatelliteController singleton, which acts as a backend service for
+            // {@link android.telephony.satellite.SatelliteManager}.
+            SatelliteController.make(this);
 
             // Create an instance of CdmaPhoneCallState and initialize it to IDLE
             cdmaPhoneCallState = new CdmaPhoneCallState();
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 821b094..b49ff4e 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -216,7 +216,7 @@
 import com.android.internal.telephony.imsphone.ImsPhoneCallTracker;
 import com.android.internal.telephony.metrics.RcsStats;
 import com.android.internal.telephony.metrics.TelephonyMetrics;
-import com.android.internal.telephony.satellite.SatelliteServiceController;
+import com.android.internal.telephony.satellite.SatelliteController;
 import com.android.internal.telephony.subscription.SubscriptionInfoInternal;
 import com.android.internal.telephony.subscription.SubscriptionManagerService;
 import com.android.internal.telephony.uicc.IccCardApplicationStatus.AppType;
@@ -392,32 +392,7 @@
     private static final int EVENT_IS_VONR_ENABLED_DONE = 116;
     private static final int CMD_PURCHASE_PREMIUM_CAPABILITY = 117;
     private static final int EVENT_PURCHASE_PREMIUM_CAPABILITY_DONE = 118;
-    private static final int CMD_START_SATELLITE_POSITION_UPDATES = 119;
-    private static final int EVENT_START_SATELLITE_POSITION_UPDATES_DONE = 120;
-    private static final int CMD_STOP_SATELLITE_POSITION_UPDATES = 121;
-    private static final int EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE = 122;
-    private static final int CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG = 123;
-    private static final int EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE = 124;
-    private static final int CMD_PROVISION_SATELLITE_SERVICE = 125;
-    private static final int EVENT_PROVISION_SATELLITE_SERVICE_DONE = 126;
-    private static final int CMD_DEPROVISION_SATELLITE_SERVICE = 127;
-    private static final int EVENT_DEPROVISION_SATELLITE_SERVICE_DONE = 128;
-    private static final int CMD_SET_SATELLITE_ENABLED = 129;
-    private static final int EVENT_SET_SATELLITE_ENABLED_DONE = 130;
-    private static final int CMD_IS_SATELLITE_ENABLED = 131;
-    private static final int EVENT_IS_SATELLITE_ENABLED_DONE = 132;
-    private static final int CMD_IS_SATELLITE_SUPPORTED = 133;
-    private static final int EVENT_IS_SATELLITE_SUPPORTED_DONE = 134;
-    private static final int CMD_GET_SATELLITE_CAPABILITIES = 135;
-    private static final int EVENT_GET_SATELLITE_CAPABILITIES_DONE = 136;
-    private static final int CMD_POLL_PENDING_SATELLITE_DATAGRAMS = 137;
-    private static final int EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE = 138;
-    private static final int CMD_SEND_SATELLITE_DATAGRAM = 139;
-    private static final int EVENT_SEND_SATELLITE_DATAGRAM_DONE = 140;
-    private static final int CMD_IS_SATELLITE_COMMUNICATION_ALLOWED = 141;
-    private static final int EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE = 142;
-    private static final int CMD_GET_TIME_SATELLITE_NEXT_VISIBLE = 143;
-    private static final int EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE = 144;
+
     // Parameters of select command.
     private static final int SELECT_COMMAND = 0xA4;
     private static final int SELECT_P1 = 0x04;
@@ -434,7 +409,8 @@
     private final PhoneGlobals mApp;
     private final CallManager mCM;
     private final ImsResolver mImsResolver;
-    private final SatelliteServiceController mSatelliteServiceController;
+
+    private final SatelliteController mSatelliteController;
     private final UserManager mUserManager;
     private final AppOpsManager mAppOps;
     private final MainThreadHandler mMainThreadHandler;
@@ -449,42 +425,6 @@
 
     private final Set<Integer> mCarrierPrivilegeTestOverrideSubIds = new ArraySet<>();
 
-    /**
-     * Map key: subId, value: callback to get error code of the provision request.
-     */
-    private final ConcurrentHashMap<Integer, Consumer<Integer>> mSatelliteProvisionCallbacks =
-            new ConcurrentHashMap<>();
-    /**
-     * Map key: subId, value: SatellitePositionUpdateHandler to notify registrants.
-     */
-    private final ConcurrentHashMap<Integer, SatellitePositionUpdateHandler>
-            mSatellitePositionUpdateHandlers = new ConcurrentHashMap<>();
-    /**
-     * Map key: subId, value: SatelliteProvisionStateChangedHandler to notify registrants.
-     */
-    private final ConcurrentHashMap<Integer, SatelliteProvisionStateChangedHandler>
-            mSatelliteProvisionStateChangedHandlers = new ConcurrentHashMap<>();
-
-    private Boolean mIsSatelliteSupported = null;
-    private final Object mIsSatelliteSupportedLock = new Object();
-    private final ResultReceiver mSatelliteSupportedReceiver;
-    /**
-     * {@code true} to use the vendor satellite service and {@code false} to use the HAL.
-     */
-    private final boolean mIsSatelliteServiceSupported = false;
-
-    /**
-     * Map key: subId, value: SatelliteStateChangeHandler to notify registrants.
-     */
-    private ConcurrentHashMap<Integer, SatelliteStateListenerHandler>
-            mSatelliteStateListenerHandlers = new ConcurrentHashMap<>();
-
-    /**
-     * Map key: subId, value: SatelliteDatagramListenerHandler to notify registrants.
-     */
-    private ConcurrentHashMap<Integer, SatelliteDatagramListenerHandler>
-            mSatelliteDatagramListenerHandlers = new ConcurrentHashMap<>();
-
     private static final String PREF_CARRIERS_ALPHATAG_PREFIX = "carrier_alphtag_";
     private static final String PREF_CARRIERS_NUMBER_PREFIX = "carrier_number_";
     private static final String PREF_CARRIERS_SUBSCRIBER_PREFIX = "carrier_subscriber_";
@@ -579,306 +519,6 @@
         }
     }
 
-    private static final class ProvisionSatelliteServiceArgument {
-        public @NonNull String token;
-        public @NonNull Consumer<Integer> callback;
-        public int subId;
-
-        ProvisionSatelliteServiceArgument(String token, Consumer<Integer> callback, int subId) {
-            this.token = token;
-            this.callback = callback;
-            this.subId = subId;
-        }
-    }
-
-    private static final class SendSatelliteDatagramArgument {
-        public long datagramId;
-
-        public @SatelliteManager.DatagramType int datagramType;
-        public @NonNull SatelliteDatagram datagram;
-
-        public boolean needFullScreenPointingUI;
-        public @NonNull ResultReceiver result;
-
-        SendSatelliteDatagramArgument(long datagramId,
-                @SatelliteManager.DatagramType int datagramType,
-                SatelliteDatagram datagram, boolean needFullScreenPointingUI,
-                ResultReceiver result) {
-            this.datagramId = datagramId;
-            this.datagramType = datagramType;
-            this.datagram = datagram;
-            this.needFullScreenPointingUI = needFullScreenPointingUI;
-            this.result = result;
-        }
-    }
-
-    private static final class SatellitePositionUpdateArgument {
-        public @NonNull Consumer<Integer> errorCallback;
-        public @NonNull ISatellitePositionUpdateCallback callback;
-        public int subId;
-
-        SatellitePositionUpdateArgument(Consumer<Integer> errorCallback,
-                ISatellitePositionUpdateCallback callback, int subId) {
-            this.errorCallback = errorCallback;
-            this.callback = callback;
-            this.subId = subId;
-        }
-    }
-
-    private static final class SatellitePositionUpdateHandler extends Handler {
-        public static final int EVENT_POSITION_INFO_CHANGED = 1;
-        public static final int EVENT_DATAGRAM_TRANSFER_STATE_CHANGED = 2;
-
-        private final ConcurrentHashMap<IBinder, ISatellitePositionUpdateCallback> mListeners;
-        SatellitePositionUpdateHandler(Looper looper) {
-            super(looper);
-            mListeners = new ConcurrentHashMap<>();
-        }
-
-        public void addListener(ISatellitePositionUpdateCallback listener) {
-            mListeners.put(listener.asBinder(), listener);
-        }
-
-        public void removeListener(ISatellitePositionUpdateCallback listener) {
-            mListeners.remove(listener.asBinder());
-        }
-
-        public boolean hasListeners() {
-            return !mListeners.isEmpty();
-        }
-
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            switch (msg.what) {
-                case EVENT_POSITION_INFO_CHANGED: {
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    PointingInfo pointingInfo = (PointingInfo) ar.result;
-                    mListeners.values().forEach(listener -> {
-                        try {
-                            listener.onSatellitePositionChanged(pointingInfo);
-                        } catch (RemoteException e) {
-                            log("EVENT_POSITION_INFO_CHANGED RemoteException: " + e);
-                        }
-                    });
-                    break;
-                }
-                case EVENT_DATAGRAM_TRANSFER_STATE_CHANGED: {
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    int result = (int) ar.result;
-                    mListeners.values().forEach(listener -> {
-                        try {
-                            // TODO: process and return the rest of the values correctly
-                            listener.onDatagramTransferStateChanged(result, 0, 0, 0);
-                        } catch (RemoteException e) {
-                            log("EVENT_DATAGRAM_TRANSFER_STATE_CHANGED RemoteException: " + e);
-                        }
-                    });
-                    break;
-                }
-                default:
-                    loge("SatellitePositionUpdateHandler unknown event: " + msg.what);
-            }
-        }
-    }
-
-    private static final class SatelliteProvisionStateChangedHandler extends Handler {
-        public static final int EVENT_PROVISION_STATE_CHANGED = 1;
-
-        private final ConcurrentHashMap<IBinder, ISatelliteProvisionStateCallback> mListeners;
-        private final int mSubId;
-
-        SatelliteProvisionStateChangedHandler(Looper looper, int subId) {
-            super(looper);
-            mListeners = new ConcurrentHashMap<>();
-            mSubId = subId;
-        }
-
-        public void addListener(ISatelliteProvisionStateCallback listener) {
-            mListeners.put(listener.asBinder(), listener);
-        }
-
-        public void removeListener(ISatelliteProvisionStateCallback listener) {
-            mListeners.remove(listener.asBinder());
-        }
-
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            switch (msg.what) {
-                case EVENT_PROVISION_STATE_CHANGED: {
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    boolean provisioned = (boolean) ar.userObj;
-                    log("Received EVENT_PROVISION_STATE_CHANGED for subId=" + mSubId
-                            + ", provisioned=" + provisioned);
-                    mListeners.values().forEach(listener -> {
-                        try {
-                            listener.onSatelliteProvisionStateChanged(provisioned);
-                        } catch (RemoteException e) {
-                            log("EVENT_PROVISION_STATE_CHANGED RemoteException: " + e);
-                        }
-                    });
-
-                    setSatelliteProvisioned(provisioned);
-                    /**
-                     * TODO: Take bugreport if provisioned is true and user did not initiate the
-                     * provision procedure for the corresponding subscription.
-                     */
-                    break;
-                }
-                default:
-                    loge("SatelliteProvisionStateChangedHandler unknown event: " + msg.what);
-            }
-        }
-
-        private void setSatelliteProvisioned(boolean isProvisioned) {
-            if (mSubId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-                SubscriptionManager.setSubscriptionProperty(
-                        mSubId, SubscriptionManager.SATELLITE_ENABLED, isProvisioned ? "1" : "0");
-            } else {
-                //TODO (b/267826133): set via SatelliteController.
-            }
-        }
-    }
-
-    private static final class SatelliteStateListenerHandler extends Handler {
-        public static final int EVENT_SATELLITE_MODEM_STATE_CHANGE = 1;
-        public static final int EVENT_PENDING_DATAGRAM_COUNT = 2;
-
-        private final ConcurrentHashMap<IBinder, ISatelliteStateCallback> mListeners;
-        private final int mSubId;
-
-        SatelliteStateListenerHandler(Looper looper, int subId) {
-            super(looper);
-            mSubId = subId;
-            mListeners = new ConcurrentHashMap<>();
-        }
-
-        public void addListener(ISatelliteStateCallback listener) {
-            mListeners.put(listener.asBinder(), listener);
-        }
-
-        public void removeListener(ISatelliteStateCallback listener) {
-            mListeners.remove(listener.asBinder());
-        }
-
-        public boolean hasListeners() {
-            return !mListeners.isEmpty();
-        }
-
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            switch (msg.what) {
-                case EVENT_SATELLITE_MODEM_STATE_CHANGE : {
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    int state = (int) ar.result;
-                    log("Received EVENT_SATELLITE_MODEM_STATE_CHANGE for subId=" + mSubId
-                            + ", state=" + state);
-                    mListeners.values().forEach(listener -> {
-                        try {
-                            listener.onSatelliteModemStateChanged(state);
-                        } catch (RemoteException e) {
-                            log("EVENT_SATELLITE_MODEM_STATE_CHANGE RemoteException: " + e);
-                        }
-                    });
-                    break;
-                }
-                case EVENT_PENDING_DATAGRAM_COUNT: {
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    int count = (int) ar.result;
-                    log("Received EVENT_PENDING_DATAGRAM_COUNT for subId=" + mSubId
-                            + ", count=" + count);
-                    mListeners.values().forEach(listener -> {
-                        try {
-                            listener.onPendingDatagramCount(count);
-                        } catch (RemoteException e) {
-                            log("EVENT_PENDING_DATAGRAM_COUNT RemoteException: " + e);
-                        }
-                    });
-                    break;
-                }
-                default:
-                    loge("SatelliteStateListenerHandler unknown event: " + msg.what);
-            }
-        }
-    }
-
-    /** Callback used by datagram receiver app to send ack back to Telephony. */
-    private static final ISatelliteDatagramReceiverAck.Stub mDatagramReceiverAck =
-            new ISatelliteDatagramReceiverAck.Stub() {
-                /**
-                 * This callback will be used by datagram receiver app to send ack back to
-                 * Telephony. If the callback is not received within five minutes,
-                 * then Telephony will resend the datagram again.
-                 *
-                 * @param datagramId An id that uniquely identifies datagram
-                 *                   received by satellite datagram receiver app.
-                 *                   This should match with datagramId passed in
-                 *                   {@link SatelliteDatagramCallback#onSatelliteDatagramReceived(
-                 *                   long, SatelliteDatagram, int, ISatelliteDatagramReceiverAck)}.
-                 *                   Upon receiving the ack, Telephony will remove the datagram from
-                 *                   the persistent memory.
-                 */
-                public void acknowledgeSatelliteDatagramReceived(long datagramId) {
-
-                }
-    };
-
-    private static final class SatelliteDatagramListenerHandler extends Handler {
-        public static final int EVENT_SATELLITE_DATAGRAMS_RECEIVED = 1;
-
-        private final ConcurrentHashMap<IBinder, ISatelliteDatagramCallback> mListeners;
-        private final int mSubId;
-
-        SatelliteDatagramListenerHandler(Looper looper, int subId) {
-            super(looper);
-            mSubId = subId;
-            mListeners = new ConcurrentHashMap<>();
-        }
-
-        public void addListener(ISatelliteDatagramCallback listener) {
-            mListeners.put(listener.asBinder(), listener);
-        }
-
-        public void removeListener(ISatelliteDatagramCallback listener) {
-            mListeners.remove(listener.asBinder());
-        }
-
-        public boolean hasListeners() {
-            return !mListeners.isEmpty();
-        }
-
-        @Override
-        public void handleMessage(@NonNull Message msg) {
-            switch (msg.what) {
-                case EVENT_SATELLITE_DATAGRAMS_RECEIVED: {
-                    AsyncResult ar = (AsyncResult) msg.obj;
-                    Pair<SatelliteDatagram[], Integer> result =
-                            (Pair<SatelliteDatagram[], Integer>) ar.result;
-                    SatelliteDatagram[] satelliteDatagrams = result.first;
-                    int pendingCount = result.second;
-
-                    log("Received EVENT_SATELLITE_DATAGRAMS_RECEIVED for subId=" + mSubId);
-                    mListeners.values().forEach(listener -> {
-                        try {
-                            for (int i = 0; i < satelliteDatagrams.length; i++) {
-                                // TODO (b/269637555): wait for ack and retry after 5mins
-                                listener.onSatelliteDatagramReceived(
-                                        // TODO: create a new datagramId every time
-                                        i, satelliteDatagrams[i], pendingCount,
-                                        // TODO: create a new instance of ack that will resend
-                                        mDatagramReceiverAck);
-                            }
-                        } catch (RemoteException e) {
-                            log("EVENT_SATELLITE_DATAGRAMS_RECEIVED RemoteException: " + e);
-                        }
-                    });
-                    break;
-                }
-                default:
-                    loge("SatelliteDatagramListenerHandler unknown event: " + msg.what);
-            }
-        }
-    }
-
     /**
      * A request object for use with {@link MainThreadHandler}. Requesters should wait() on the
      * request after sending. The main thread will notify the request when it is complete.
@@ -2627,444 +2267,6 @@
                     notifyRequester(request);
                     break;
 
-                case CMD_START_SATELLITE_POSITION_UPDATES: {
-                    request = (MainThreadRequest) msg.obj;
-                    onCompleted =
-                            obtainMessage(EVENT_START_SATELLITE_POSITION_UPDATES_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController.startSendingSatellitePointingInfo(onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.startSatellitePositionUpdates(onCompleted);
-                    } else {
-                        loge("startSatellitePositionUpdates: No phone object");
-                        SatellitePositionUpdateArgument arg =
-                                (SatellitePositionUpdateArgument) request.argument;
-                        arg.errorCallback.accept(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-                    }
-                    break;
-                }
-
-                case EVENT_START_SATELLITE_POSITION_UPDATES_DONE: {
-                    handleStartSatellitePositionUpdatesDone((AsyncResult) msg.obj);
-                    break;
-                }
-
-                case CMD_STOP_SATELLITE_POSITION_UPDATES: {
-                    request = (MainThreadRequest) msg.obj;
-                    onCompleted =
-                            obtainMessage(EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController.stopSendingSatellitePointingInfo(onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.stopSatellitePositionUpdates(onCompleted);
-                    } else {
-                        loge("stopSatellitePositionUpdates: No phone object");
-                        ((Consumer<Integer>) request.argument).accept(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-                    }
-                    break;
-                }
-
-                case EVENT_STOP_SATELLITE_POSITION_UPDATES_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int error = getSatelliteError(ar, "stopSatellitePositionUpdates", false);
-                    ((Consumer<Integer>) request.argument).accept(error);
-                    break;
-                }
-
-                case CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG: {
-                    request = (MainThreadRequest) msg.obj;
-                    onCompleted =
-                            obtainMessage(EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController
-                                .requestMaxCharactersPerMOTextMessage(onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.getMaxCharactersPerSatelliteTextMessage(onCompleted);
-                    } else {
-                        loge("getMaxCharactersPerSatelliteTextMessage: No phone object");
-                        ((ResultReceiver) request.argument).send(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-                    }
-                    break;
-                }
-
-                case EVENT_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int error =
-                            getSatelliteError(ar, "getMaxCharactersPerSatelliteTextMessage", true);
-                    Bundle bundle = new Bundle();
-                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
-                        int maxCharLimit = ((int[]) ar.result)[0];
-                        if (DBG) log("getMaxCharactersPerSatelliteTextMessage: " + maxCharLimit);
-                        bundle.putInt(SatelliteManager.KEY_MAX_CHARACTERS_PER_SATELLITE_TEXT,
-                                maxCharLimit);
-                    }
-                    ((ResultReceiver) request.argument).send(error, bundle);
-                    break;
-                }
-
-                case CMD_PROVISION_SATELLITE_SERVICE: {
-                    request = (MainThreadRequest) msg.obj;
-                    ProvisionSatelliteServiceArgument argument =
-                            (ProvisionSatelliteServiceArgument) request.argument;
-                    if (mSatelliteProvisionCallbacks.containsKey(argument.subId)) {
-                        argument.callback.accept(
-                                SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS);
-                        notifyRequester(request);
-                        break;
-                    }
-                    mSatelliteProvisionCallbacks.put(argument.subId, argument.callback);
-                    onCompleted = obtainMessage(EVENT_PROVISION_SATELLITE_SERVICE_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController
-                                .provisionSatelliteService(argument.token, onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.provisionSatelliteService(onCompleted, argument.token);
-                    } else {
-                        loge("provisionSatelliteService: No phone object");
-                        argument.callback.accept(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-                        notifyRequester(request);
-                    }
-                    break;
-                }
-
-                case EVENT_PROVISION_SATELLITE_SERVICE_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int errorCode = getSatelliteError(ar, "provisionSatelliteService", false);
-                    handleEventProvisionSatelliteServiceDone(
-                            (ProvisionSatelliteServiceArgument) request.argument, errorCode);
-                    notifyRequester(request);
-                    break;
-                }
-
-                case CMD_DEPROVISION_SATELLITE_SERVICE: {
-                    request = (MainThreadRequest) msg.obj;
-                    ProvisionSatelliteServiceArgument argument =
-                            (ProvisionSatelliteServiceArgument) request.argument;
-                    onCompleted = obtainMessage(EVENT_DEPROVISION_SATELLITE_SERVICE_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController
-                                .deprovisionSatelliteService(argument.token, onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.deprovisionSatelliteService(onCompleted, argument.token);
-                    } else {
-                        loge("deprovisionSatelliteService: No phone object");
-                        if (argument.callback != null) {
-                            argument.callback.accept(
-                                    SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-                        }
-                    }
-                    break;
-                }
-
-                case EVENT_DEPROVISION_SATELLITE_SERVICE_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int errorCode = getSatelliteError(ar, "deprovisionSatelliteService", false);
-                    handleEventDeprovisionSatelliteServiceDone(
-                            (ProvisionSatelliteServiceArgument) request.argument, errorCode);
-                    break;
-                }
-
-                case CMD_SET_SATELLITE_ENABLED: {
-                    request = (MainThreadRequest) msg.obj;
-                    Pair<Boolean, Consumer<Integer>> argument =
-                            (Pair<Boolean, Consumer<Integer>>) request.argument;
-                    onCompleted = obtainMessage(EVENT_SET_SATELLITE_ENABLED_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController
-                                .requestSatelliteEnabled(argument.first, onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.setSatellitePower(onCompleted, argument.first);
-                    } else {
-                        loge("requestSatelliteEnabled: No phone object");
-                        argument.second.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-                    }
-                    break;
-                }
-
-                case EVENT_SET_SATELLITE_ENABLED_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    Pair<Boolean, Consumer<Integer>> argument =
-                            (Pair<Boolean, Consumer<Integer>>) request.argument;
-                    int error = getSatelliteError(ar, "setSatelliteEnabled", false);
-                    argument.second.accept(error);
-                    break;
-                }
-
-                case CMD_IS_SATELLITE_ENABLED: {
-                    request = (MainThreadRequest) msg.obj;
-                    onCompleted = obtainMessage(EVENT_IS_SATELLITE_ENABLED_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController.requestIsSatelliteEnabled(onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.isSatellitePowerOn(onCompleted);
-                    } else {
-                        loge("isSatelliteEnabled: No phone object");
-                        ((ResultReceiver) request.argument).send(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-                    }
-                    break;
-                }
-
-                case EVENT_IS_SATELLITE_ENABLED_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int error = getSatelliteError(ar, "isSatelliteEnabled", true);
-                    Bundle bundle = new Bundle();
-                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
-                        boolean enabled = ((int[]) ar.result)[0] == 1;
-                        if (DBG) log("isSatelliteEnabled: " + enabled);
-                        bundle.putBoolean(SatelliteManager.KEY_SATELLITE_ENABLED, enabled);
-                    }
-                    ((ResultReceiver) request.argument).send(error, bundle);
-                    break;
-                }
-
-                case CMD_IS_SATELLITE_SUPPORTED: {
-                    request = (MainThreadRequest) msg.obj;
-                    onCompleted = obtainMessage(EVENT_IS_SATELLITE_SUPPORTED_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController.requestIsSatelliteSupported(onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.isSatelliteSupported(onCompleted);
-                    } else {
-                        loge("isSatelliteSupported: No phone object");
-                        ((ResultReceiver) request.argument).send(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-                    }
-                    break;
-                }
-
-                case EVENT_IS_SATELLITE_SUPPORTED_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int error = getSatelliteError(ar, "isSatelliteSupported", true);
-                    Bundle bundle = new Bundle();
-                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
-                        boolean supported = (boolean) ar.result;
-                        if (DBG) log("isSatelliteSupported: " + supported);
-                        bundle.putBoolean(SatelliteManager.KEY_SATELLITE_SUPPORTED, supported);
-                        synchronized (mIsSatelliteSupportedLock) {
-                            mIsSatelliteSupported = supported;
-                        }
-                    } else {
-                        synchronized (mIsSatelliteSupportedLock) {
-                            mIsSatelliteSupported = null;
-                        }
-                    }
-                    ((ResultReceiver) request.argument).send(error, bundle);
-                    break;
-                }
-
-                case CMD_GET_SATELLITE_CAPABILITIES: {
-                    request = (MainThreadRequest) msg.obj;
-                    onCompleted = obtainMessage(EVENT_GET_SATELLITE_CAPABILITIES_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController.requestSatelliteCapabilities(onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.getSatelliteCapabilities(onCompleted);
-                    } else {
-                        loge("getSatelliteCapabilities: No phone object");
-                        ((ResultReceiver) request.argument).send(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-                    }
-                    break;
-                }
-
-                case EVENT_GET_SATELLITE_CAPABILITIES_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int error = getSatelliteError(ar, "getSatelliteCapabilities", true);
-                    Bundle bundle = new Bundle();
-                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
-                        SatelliteCapabilities capabilities = (SatelliteCapabilities) ar.result;
-                        if (DBG) log("getSatelliteCapabilities: " + capabilities);
-                        bundle.putParcelable(SatelliteManager.KEY_SATELLITE_CAPABILITIES,
-                                capabilities);
-                    }
-                    ((ResultReceiver) request.argument).send(error, bundle);
-                    break;
-                }
-
-                case CMD_POLL_PENDING_SATELLITE_DATAGRAMS: {
-                    request = (MainThreadRequest) msg.obj;
-                    onCompleted =
-                            obtainMessage(EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController.pollPendingSatelliteDatagrams(onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.pollPendingSatelliteDatagrams(onCompleted);
-                    } else {
-                        loge("pollPendingSatelliteDatagrams: No phone object");
-                        ((Consumer<Integer>) request.argument).accept(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-                    }
-                    break;
-                }
-
-                case EVENT_POLL_PENDING_SATELLITE_DATAGRAMS_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int error = getSatelliteError(ar, "pollPendingSatelliteDatagrams", false);
-                    ((Consumer<Integer>) request.argument).accept(error);
-                    break;
-                }
-
-                case CMD_SEND_SATELLITE_DATAGRAM: {
-                    request = (MainThreadRequest) msg.obj;
-                    SendSatelliteDatagramArgument argument =
-                            (SendSatelliteDatagramArgument) request.argument;
-                    onCompleted = obtainMessage(EVENT_SEND_SATELLITE_DATAGRAM_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController.sendSatelliteDatagram(
-                                argument.datagram,
-                                argument.datagramType == SatelliteManager.DATAGRAM_TYPE_SOS_MESSAGE,
-                                argument.needFullScreenPointingUI, onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.sendSatelliteDatagram(onCompleted, argument.datagram,
-                                argument.needFullScreenPointingUI);
-                    } else {
-                        loge("sendSatelliteDatagram: No phone object");
-                        argument.result.send(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-                    }
-                    break;
-                }
-
-                case EVENT_SEND_SATELLITE_DATAGRAM_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int error = getSatelliteError(ar, "sendSatelliteDatagram", false);
-                    SendSatelliteDatagramArgument argument =
-                            (SendSatelliteDatagramArgument) request.argument;
-                    Bundle bundle = new Bundle();
-                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
-                        bundle.putLong(SatelliteManager.KEY_SEND_SATELLITE_DATAGRAM,
-                                argument.datagramId);
-                    }
-                    argument.result.send(error, bundle);
-                    break;
-                }
-
-                case CMD_IS_SATELLITE_COMMUNICATION_ALLOWED: {
-                    request = (MainThreadRequest) msg.obj;
-                    onCompleted =
-                            obtainMessage(EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE, request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController
-                                .requestIsSatelliteCommunicationAllowedForCurrentLocation(
-                                        onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.isSatelliteCommunicationAllowedForCurrentLocation(onCompleted);
-                    } else {
-                        loge("isSatelliteCommunicationAllowedForCurrentLocation: No phone object");
-                        ((ResultReceiver) request.argument).send(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-                    }
-                    break;
-                }
-
-                case EVENT_IS_SATELLITE_COMMUNICATION_ALLOWED_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int error = getSatelliteError(
-                            ar, "isSatelliteCommunicationAllowedForCurrentLocation", true);
-                    Bundle bundle = new Bundle();
-                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
-                        boolean communicationAllowed = (boolean) ar.result;
-                        if (DBG) {
-                            log("isSatelliteCommunicationAllowedForCurrentLocation: "
-                                    + communicationAllowed);
-                        }
-                        bundle.putBoolean(SatelliteManager.KEY_SATELLITE_COMMUNICATION_ALLOWED,
-                                communicationAllowed);
-                    }
-                    ((ResultReceiver) request.argument).send(error, bundle);
-                    break;
-                }
-
-                case CMD_GET_TIME_SATELLITE_NEXT_VISIBLE: {
-                    request = (MainThreadRequest) msg.obj;
-                    onCompleted = obtainMessage(EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE,
-                            request);
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController
-                                .requestTimeForNextSatelliteVisibility(onCompleted);
-                        break;
-                    }
-                    Phone phone = getPhoneFromRequest(request);
-                    if (phone != null) {
-                        phone.requestTimeForNextSatelliteVisibility(onCompleted);
-                    } else {
-                        loge("requestTimeForNextSatelliteVisibility: No phone object");
-                        ((ResultReceiver) request.argument).send(
-                                SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-                    }
-                    break;
-                }
-
-                case EVENT_GET_TIME_SATELLITE_NEXT_VISIBLE_DONE: {
-                    ar = (AsyncResult) msg.obj;
-                    request = (MainThreadRequest) ar.userObj;
-                    int error =
-                            getSatelliteError(ar, "requestTimeForNextSatelliteVisibility", true);
-                    Bundle bundle = new Bundle();
-                    if (error == SatelliteManager.SATELLITE_ERROR_NONE) {
-                        int nextVisibilityDuration = ((int[]) ar.result)[0];
-                        if (DBG) {
-                            log("requestTimeForNextSatelliteVisibility: " + nextVisibilityDuration);
-                        }
-                        bundle.putInt(SatelliteManager.KEY_SATELLITE_NEXT_VISIBILITY,
-                                nextVisibilityDuration);
-                    }
-                    ((ResultReceiver) request.argument).send(error, bundle);
-                    break;
-                }
-
                 default:
                     Log.w(LOG_TAG, "MainThreadHandler: unexpected message code: " + msg.what);
                     break;
@@ -3259,7 +2461,7 @@
         mApp = app;
         mCM = PhoneGlobals.getInstance().mCM;
         mImsResolver = ImsResolver.getInstance();
-        mSatelliteServiceController = SatelliteServiceController.getInstance();
+        mSatelliteController = SatelliteController.getInstance();
         mUserManager = (UserManager) app.getSystemService(Context.USER_SERVICE);
         mAppOps = (AppOpsManager)app.getSystemService(Context.APP_OPS_SERVICE);
         mMainThreadHandler = new MainThreadHandler();
@@ -3276,24 +2478,6 @@
         PropertyInvalidatedCache.invalidateCache(TelephonyManager.CACHE_KEY_PHONE_ACCOUNT_TO_SUBID);
         publish();
         CarrierAllowListInfo.loadInstance(mApp);
-        mSatelliteSupportedReceiver = new ResultReceiver(mMainThreadHandler) {
-            @Override
-            protected void onReceiveResult(int resultCode, Bundle resultData) {
-                if (resultCode == SatelliteManager.SATELLITE_ERROR_NONE
-                        && resultData.containsKey(SatelliteManager.KEY_SATELLITE_SUPPORTED)) {
-                    synchronized (mIsSatelliteSupportedLock) {
-                        mIsSatelliteSupported = resultData.getBoolean(
-                                SatelliteManager.KEY_SATELLITE_SUPPORTED);
-                    }
-                } else {
-                    synchronized (mIsSatelliteSupportedLock) {
-                        mIsSatelliteSupported = null;
-                    }
-                }
-            }
-        };
-        requestIsSatelliteSupported(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                mSatelliteSupportedReceiver);
     }
 
     @VisibleForTesting
@@ -12907,26 +12091,7 @@
     public void requestSatelliteEnabled(
             int subId, boolean enable, @NonNull IIntegerConsumer callback) {
         enforceSatelliteCommunicationPermission("requestSatelliteEnabled");
-        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
-        if (!isSatelliteSupported()) {
-            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "requestSatelliteEnabled");
-        if (phone == null) {
-            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-            return;
-        }
-
-        Pair<Boolean, Consumer<Integer>> arg = new Pair<>(enable, result);
-        sendRequestAsync(CMD_SET_SATELLITE_ENABLED, arg, phone, null);
+        mSatelliteController.requestSatelliteEnabled(subId, enable, callback);
     }
 
     /**
@@ -12941,24 +12106,7 @@
     @Override
     public void requestIsSatelliteEnabled(int subId, @NonNull ResultReceiver result) {
         enforceSatelliteCommunicationPermission("requestIsSatelliteEnabled");
-        if (!isSatelliteSupported()) {
-            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "requestIsSatelliteEnabled");
-        if (phone == null) {
-            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-            return;
-        }
-
-        sendRequest(CMD_IS_SATELLITE_ENABLED, result, subId);
+        mSatelliteController.requestIsSatelliteEnabled(subId, result);
     }
 
     /**
@@ -12974,29 +12122,7 @@
     public void requestSatelliteDemoModeEnabled(
             int subId, boolean enable, @NonNull IIntegerConsumer callback) {
         enforceSatelliteCommunicationPermission("requestSatelliteDemoModeEnabled");
-        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
-        if (!isSatelliteSupported()) {
-            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "requestSatelliteDemoModeEnabled");
-        if (phone == null) {
-            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-            return;
-        }
-
-        if (mIsSatelliteServiceSupported) {
-            result.accept(mSatelliteServiceController.requestSatelliteDemoModeEnabled(enable));
-        } else {
-            result.accept(SatelliteManager.SATELLITE_SERVICE_ERROR);
-        }
+        mSatelliteController.requestSatelliteDemoModeEnabled(subId, enable, callback);
     }
 
     /**
@@ -13012,36 +12138,7 @@
     @Override
     public void requestIsSatelliteDemoModeEnabled(int subId, @NonNull ResultReceiver result) {
         enforceSatelliteCommunicationPermission("requestIsSatelliteDemoModeEnabled");
-        if (!isSatelliteSupported()) {
-            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "requestIsSatelliteDemoModeEnabled");
-        if (phone == null) {
-            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-            return;
-        }
-
-        if (mIsSatelliteServiceSupported) {
-            final Bundle bundle = new Bundle();
-            int error = mSatelliteServiceController.requestIsSatelliteDemoModeEnabled(
-                    new Consumer<Boolean>() {
-                        @Override
-                        public void accept(Boolean enabled) {
-                            bundle.putBoolean(SatelliteManager.KEY_DEMO_MODE_ENABLED, enabled);
-                        }
-                    });
-            result.send(error, bundle);
-        } else {
-            result.send(SatelliteManager.SATELLITE_SERVICE_ERROR, null);
-        }
+        mSatelliteController.requestIsSatelliteDemoModeEnabled(subId, result);
     }
 
     /**
@@ -13053,24 +12150,7 @@
      */
     @Override
     public void requestIsSatelliteSupported(int subId, @NonNull ResultReceiver result) {
-        synchronized (mIsSatelliteSupportedLock) {
-            if (mIsSatelliteSupported != null) {
-                /* We have already successfully queried the satellite modem. */
-                Bundle bundle = new Bundle();
-                bundle.putBoolean(SatelliteManager.KEY_SATELLITE_SUPPORTED, mIsSatelliteSupported);
-                result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, bundle);
-                return;
-            }
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        Phone phone = getPhoneOrDefault(validSubId, "requestIsSatelliteSupported");
-        if (phone == null) {
-            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-            return;
-        }
-
-        sendRequestAsync(CMD_IS_SATELLITE_SUPPORTED, result, phone, null);
+        mSatelliteController.requestIsSatelliteSupported(subId, result);
     }
 
     /**
@@ -13085,19 +12165,7 @@
     @Override
     public void requestSatelliteCapabilities(int subId, @NonNull ResultReceiver result) {
         enforceSatelliteCommunicationPermission("requestSatelliteCapabilities");
-        if (!isSatelliteSupported()) {
-            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        Phone phone = getPhoneOrDefault(validSubId, "requestSatelliteCapabilities");
-        if (phone == null) {
-            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-            return;
-        }
-
-        sendRequestAsync(CMD_GET_SATELLITE_CAPABILITIES, result, phone, null);
+        mSatelliteController.requestSatelliteCapabilities(subId, result);
     }
 
     /**
@@ -13115,46 +12183,7 @@
     public void startSatellitePositionUpdates(int subId, @NonNull IIntegerConsumer errorCallback,
             @NonNull ISatellitePositionUpdateCallback callback) {
         enforceSatelliteCommunicationPermission("startSatellitePositionUpdates");
-        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(errorCallback::accept);
-        if (!isSatelliteSupported()) {
-            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "startSatellitePositionUpdates");
-        if (phone == null) {
-            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-            return;
-        }
-
-        SatellitePositionUpdateHandler handler = mSatellitePositionUpdateHandlers.get(validSubId);
-        if (handler != null) {
-            handler.addListener(callback);
-            return;
-        } else {
-            handler = new SatellitePositionUpdateHandler(Looper.getMainLooper());
-            handler.addListener(callback);
-            mSatellitePositionUpdateHandlers.put(validSubId, handler);
-            if (mIsSatelliteServiceSupported) {
-                mSatelliteServiceController.registerForSatellitePositionInfoChanged(handler,
-                        SatellitePositionUpdateHandler.EVENT_POSITION_INFO_CHANGED, null);
-                mSatelliteServiceController.registerForDatagramTransferStateChanged(handler,
-                        SatellitePositionUpdateHandler.EVENT_DATAGRAM_TRANSFER_STATE_CHANGED, null);
-            } else {
-                phone.registerForSatellitePositionInfoChanged(handler,
-                        SatellitePositionUpdateHandler.EVENT_POSITION_INFO_CHANGED, null);
-                // TODO: registerForDatagramTransferStateChanged through SatelliteController
-            }
-        }
-
-        sendRequestAsync(CMD_START_SATELLITE_POSITION_UPDATES,
-                new SatellitePositionUpdateArgument(result, callback, validSubId), phone, null);
+        mSatelliteController.startSatellitePositionUpdates(subId, errorCallback, callback);
     }
 
     /**
@@ -13172,55 +12201,7 @@
     public void stopSatellitePositionUpdates(int subId, @NonNull IIntegerConsumer errorCallback,
             @NonNull ISatellitePositionUpdateCallback callback) {
         enforceSatelliteCommunicationPermission("stopSatellitePositionUpdates");
-        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(errorCallback::accept);
-        if (!isSatelliteSupported()) {
-            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "stopSatellitePositionUpdates");
-        SatellitePositionUpdateHandler handler = mSatellitePositionUpdateHandlers.get(validSubId);
-        if (handler != null) {
-            handler.removeListener(callback);
-
-            if (handler.hasListeners()) {
-                /**
-                 * TODO (b/269194948): If the calling apps crash, the handler will always have some
-                 * listener. That is, we will not request modem to stop position update and
-                 * cleaning our resources. We need to monitor the calling apps and clean up the
-                 * resources when the apps die. We need to this for other satellite callbacks
-                 * as well.
-                 */
-                result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
-                return;
-            }
-
-            mSatellitePositionUpdateHandlers.remove(validSubId);
-            if (mIsSatelliteServiceSupported) {
-                mSatelliteServiceController.unregisterForSatellitePositionInfoChanged(handler);
-                mSatelliteServiceController.unregisterForDatagramTransferStateChanged(handler);
-            } else {
-                if (phone == null) {
-                    result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-                    return;
-                }
-                phone.unregisterForSatellitePositionInfoChanged(handler);
-                // TODO: unregisterForDatagramTransferStateChanged through SatelliteController
-            }
-        }
-
-        /**
-         * Even if handler is null - which means there are not any listeners, the command to stop
-         * satellite position updates sent to the modem might have failed. The callers might want to
-         * retry sending the command. Thus, we always need to send this command to the modem.
-         */
-        sendRequestAsync(CMD_STOP_SATELLITE_POSITION_UPDATES, result, phone, null);
+        mSatelliteController.stopSatellitePositionUpdates(subId, errorCallback, callback);
     }
 
     /**
@@ -13237,24 +12218,7 @@
     public void requestMaxSizePerSendingDatagram(int subId,
             @NonNull ResultReceiver result) {
         enforceSatelliteCommunicationPermission("requestMaxSizePerSendingDatagram");
-        if (!isSatelliteSupported()) {
-            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "requestMaxSizePerSendingDatagram");
-        if (phone == null) {
-            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-            return;
-        }
-
-        sendRequestAsync(CMD_GET_MAX_CHAR_PER_SATELLITE_TEXT_MSG, result, phone, null);
+        mSatelliteController.requestMaxSizePerSendingDatagram(subId, result);
     }
 
     /**
@@ -13275,39 +12239,7 @@
     @Nullable public ICancellationSignal provisionSatelliteService(int subId,
             @NonNull String token, @NonNull IIntegerConsumer callback) {
         enforceSatelliteCommunicationPermission("provisionSatelliteService");
-        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
-        if (!isSatelliteSupported()) {
-            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
-            return null;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        Phone phone = getPhoneOrDefault(validSubId, "provisionSatelliteService");
-        if (phone == null) {
-            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-            return null;
-        }
-
-        if (mSatelliteProvisionCallbacks.containsKey(validSubId)) {
-            result.accept(SatelliteManager.SATELLITE_SERVICE_PROVISION_IN_PROGRESS);
-            return null;
-        }
-
-        if (isSatelliteProvisioned(validSubId)) {
-            result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
-            return null;
-        }
-
-        sendRequestAsync(CMD_PROVISION_SATELLITE_SERVICE,
-                new ProvisionSatelliteServiceArgument(token, result, validSubId), phone, null);
-
-        ICancellationSignal cancelTransport = CancellationSignal.createTransport();
-        CancellationSignal.fromTransport(cancelTransport).setOnCancelListener(() -> {
-            sendRequestAsync(CMD_DEPROVISION_SATELLITE_SERVICE,
-                    new ProvisionSatelliteServiceArgument(token, null, validSubId),
-                    phone, null);
-        });
-        return cancelTransport;
+        return mSatelliteController.provisionSatelliteService(subId, token, callback);
     }
 
     /**
@@ -13326,26 +12258,7 @@
     public void deprovisionSatelliteService(int subId,
             @NonNull String token, @NonNull IIntegerConsumer callback) {
         enforceSatelliteCommunicationPermission("deprovisionSatelliteService");
-        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
-        if (!isSatelliteSupported()) {
-            result.accept(SatelliteManager.SATELLITE_NOT_SUPPORTED);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.accept(SatelliteManager.SATELLITE_ERROR_NONE);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "deprovisionSatelliteService");
-        if (phone == null) {
-            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-            return;
-        }
-
-        sendRequestAsync(CMD_DEPROVISION_SATELLITE_SERVICE,
-                new ProvisionSatelliteServiceArgument(token, result, validSubId), phone, null);
+        mSatelliteController.deprovisionSatelliteService(subId, token, callback);
     }
 
     /**
@@ -13362,7 +12275,7 @@
     @SatelliteManager.SatelliteError public int registerForSatelliteProvisionStateChanged(int subId,
             @NonNull ISatelliteProvisionStateCallback callback) {
         enforceSatelliteCommunicationPermission("registerForSatelliteProvisionStateChanged");
-        return registerForSatelliteProvisionStateChangedInternal(subId, callback);
+        return mSatelliteController.registerForSatelliteProvisionStateChanged(subId, callback);
     }
 
     /**
@@ -13379,13 +12292,7 @@
     public void unregisterForSatelliteProvisionStateChanged(
             int subId, @NonNull ISatelliteProvisionStateCallback callback) {
         enforceSatelliteCommunicationPermission("unregisterForSatelliteProvisionStateChanged");
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        SatelliteProvisionStateChangedHandler satelliteProvisionStateChangedHandler =
-                mSatelliteProvisionStateChangedHandlers.get(validSubId);
-        if (satelliteProvisionStateChangedHandler != null) {
-            satelliteProvisionStateChangedHandler.removeListener(callback);
-        }
+        mSatelliteController.unregisterForSatelliteProvisionStateChanged(subId, callback);
     }
 
     /**
@@ -13401,16 +12308,7 @@
     @Override
     public void requestIsSatelliteProvisioned(int subId, @NonNull ResultReceiver result) {
         enforceSatelliteCommunicationPermission("requestIsSatelliteProvisioned");
-        if (!isSatelliteSupported()) {
-            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        Bundle bundle = new Bundle();
-        bundle.putBoolean(SatelliteManager.KEY_SATELLITE_PROVISIONED,
-                isSatelliteProvisioned(validSubId));
-        result.send(SatelliteManager.SATELLITE_ERROR_NONE, bundle);
+        mSatelliteController.requestIsSatelliteProvisioned(subId, result);
     }
 
     /**
@@ -13427,37 +12325,7 @@
     @SatelliteManager.SatelliteError public int registerForSatelliteModemStateChanged(int subId,
             @NonNull ISatelliteStateCallback callback) {
         enforceSatelliteCommunicationPermission("registerForSatelliteModemStateChanged");
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        Phone phone = getPhoneOrDefault(
-                validSubId, "registerForSatelliteModemStateChanged");
-        if (phone == null) {
-            return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
-        }
-
-        SatelliteStateListenerHandler satelliteStateListenerHandler =
-                mSatelliteStateListenerHandlers.get(validSubId);
-        if (satelliteStateListenerHandler == null) {
-            satelliteStateListenerHandler = new SatelliteStateListenerHandler(
-                    Looper.getMainLooper(), validSubId);
-            if (mIsSatelliteServiceSupported) {
-                mSatelliteServiceController.registerForSatelliteModemStateChanged(
-                        satelliteStateListenerHandler,
-                        SatelliteStateListenerHandler.EVENT_SATELLITE_MODEM_STATE_CHANGE, null);
-                mSatelliteServiceController.registerForPendingDatagramCount(
-                        satelliteStateListenerHandler,
-                        SatelliteStateListenerHandler.EVENT_PENDING_DATAGRAM_COUNT, null);
-            } else {
-                phone.registerForSatelliteModemStateChanged(satelliteStateListenerHandler,
-                        SatelliteStateListenerHandler.EVENT_SATELLITE_MODEM_STATE_CHANGE, null);
-                phone.registerForPendingDatagramCount(satelliteStateListenerHandler,
-                        SatelliteStateListenerHandler.EVENT_PENDING_DATAGRAM_COUNT, null);
-            }
-        }
-
-        satelliteStateListenerHandler.addListener(callback);
-        mSatelliteStateListenerHandlers.put(validSubId, satelliteStateListenerHandler);
-        return SatelliteManager.SATELLITE_ERROR_NONE;
+        return mSatelliteController.registerForSatelliteModemStateChanged(subId, callback);
     }
 
     /**
@@ -13474,28 +12342,7 @@
     public void unregisterForSatelliteModemStateChanged(int subId,
             @NonNull ISatelliteStateCallback callback) {
         enforceSatelliteCommunicationPermission("unregisterForSatelliteModemStateChanged");
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        SatelliteStateListenerHandler handler = mSatelliteStateListenerHandlers.get(validSubId);
-        if (handler != null) {
-            handler.removeListener(callback);
-            if (!handler.hasListeners()) {
-                mSatelliteStateListenerHandlers.remove(validSubId);
-                if (mIsSatelliteServiceSupported) {
-                    mSatelliteServiceController.unregisterForSatelliteModemStateChanged(handler);
-                    mSatelliteServiceController.unregisterForPendingDatagramCount(handler);
-                } else {
-                    Phone phone = getPhoneOrDefault(
-                            validSubId, "unregisterForSatelliteModemStateChanged");
-                    if (phone == null) {
-                        loge("unregisterForSatelliteModemStateChanged: phone is null");
-                    } else {
-                        phone.unregisterForSatelliteModemStateChanged(handler);
-                        phone.unregisterForPendingDatagramCount(handler);
-                    }
-                }
-            }
-        }
+        mSatelliteController.unregisterForSatelliteModemStateChanged(subId, callback);
     }
 
     /**
@@ -13515,34 +12362,7 @@
             @SatelliteManager.DatagramType int datagramType,
             @NonNull ISatelliteDatagramCallback callback) {
         enforceSatelliteCommunicationPermission("registerForSatelliteDatagram");
-        if (!isSatelliteSupported()) {
-            return SatelliteManager.SATELLITE_NOT_SUPPORTED;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        Phone phone = getPhoneOrDefault(validSubId, "registerForSatelliteDatagram");
-        if (phone == null) {
-            return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
-        }
-
-        SatelliteDatagramListenerHandler satelliteDatagramListenerHandler =
-                mSatelliteDatagramListenerHandlers.get(validSubId);
-        if (satelliteDatagramListenerHandler == null) {
-            satelliteDatagramListenerHandler = new SatelliteDatagramListenerHandler(
-                    Looper.getMainLooper(), validSubId);
-            if (mIsSatelliteServiceSupported) {
-                mSatelliteServiceController.registerForSatelliteDatagramsReceived(
-                        satelliteDatagramListenerHandler,
-                        SatelliteDatagramListenerHandler.EVENT_SATELLITE_DATAGRAMS_RECEIVED, null);
-            } else {
-                phone.registerForSatelliteDatagramsReceived(satelliteDatagramListenerHandler,
-                        SatelliteDatagramListenerHandler.EVENT_SATELLITE_DATAGRAMS_RECEIVED, null);
-            }
-        }
-
-        satelliteDatagramListenerHandler.addListener(callback);
-        mSatelliteDatagramListenerHandlers.put(validSubId, satelliteDatagramListenerHandler);
-        return SatelliteManager.SATELLITE_ERROR_NONE;
+        return mSatelliteController.registerForSatelliteDatagram(subId, datagramType, callback);
     }
 
     /**
@@ -13559,27 +12379,7 @@
     public void unregisterForSatelliteDatagram(int subId,
             @NonNull ISatelliteDatagramCallback callback) {
         enforceSatelliteCommunicationPermission("unregisterForSatelliteDatagram");
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        SatelliteDatagramListenerHandler handler =
-                mSatelliteDatagramListenerHandlers.get(validSubId);
-        if (handler != null) {
-            handler.removeListener(callback);
-
-            if (!handler.hasListeners()) {
-                mSatelliteDatagramListenerHandlers.remove(validSubId);
-                if (mIsSatelliteServiceSupported) {
-                    mSatelliteServiceController.unregisterForSatelliteDatagramsReceived(handler);
-                } else {
-                    Phone phone = getPhoneOrDefault(validSubId, "unregisterForSatelliteDatagram");
-                    if (phone == null) {
-                        loge("unregisterForSatelliteDatagram: phone is null");
-                    } else {
-                        phone.unregisterForSatelliteDatagramsReceived(handler);
-                    }
-                }
-            }
-        }
+        mSatelliteController.unregisterForSatelliteDatagram(subId, callback);
     }
 
     /**
@@ -13598,21 +12398,7 @@
     @Override
     public void pollPendingSatelliteDatagrams(int subId, IIntegerConsumer callback) {
         enforceSatelliteCommunicationPermission("pollPendingSatelliteDatagrams");
-        Consumer<Integer> result = FunctionalUtils.ignoreRemoteException(callback::accept);
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.accept(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "pollPendingSatelliteDatagrams");
-        if (phone == null) {
-            result.accept(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE);
-            return;
-        }
-
-        sendRequestAsync(CMD_POLL_PENDING_SATELLITE_DATAGRAMS, result, phone, null);
+        mSatelliteController.pollPendingSatelliteDatagrams(subId, callback);
     }
 
     /**
@@ -13640,24 +12426,8 @@
             @SatelliteManager.DatagramType int datagramType, SatelliteDatagram datagram,
             boolean needFullScreenPointingUI, @NonNull ResultReceiver result) {
         enforceSatelliteCommunicationPermission("sendSatelliteDatagram");
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "sendSatelliteDatagram");
-        if (phone == null) {
-            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-            return;
-        }
-
-        // check if we need to start PointingUI.
-
-        sendRequestAsync(CMD_SEND_SATELLITE_DATAGRAM,
-                new SendSatelliteDatagramArgument(datagramId, datagramType, datagram,
-                        needFullScreenPointingUI, result), phone, null);
+        mSatelliteController.sendSatelliteDatagram(subId, datagramId, datagramType, datagram,
+                needFullScreenPointingUI, result);
     }
 
     /**
@@ -13676,25 +12446,8 @@
             @NonNull ResultReceiver result) {
         enforceSatelliteCommunicationPermission(
                 "requestIsSatelliteCommunicationAllowedForCurrentLocation");
-        if (!isSatelliteSupported()) {
-            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId,
-                "requestIsSatelliteCommunicationAllowedForCurrentLocation");
-        if (phone == null) {
-            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-            return;
-        }
-
-        sendRequest(CMD_IS_SATELLITE_COMMUNICATION_ALLOWED, result, subId);
+        mSatelliteController.requestIsSatelliteCommunicationAllowedForCurrentLocation(subId,
+                result);
     }
 
     /**
@@ -13709,69 +12462,7 @@
     @Override
     public void requestTimeForNextSatelliteVisibility(int subId, @NonNull ResultReceiver result) {
         enforceSatelliteCommunicationPermission("requestTimeForNextSatelliteVisibility");
-        if (!isSatelliteSupported()) {
-            result.send(SatelliteManager.SATELLITE_NOT_SUPPORTED, null);
-            return;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        if (!isSatelliteProvisioned(validSubId)) {
-            result.send(SatelliteManager.SATELLITE_SERVICE_NOT_PROVISIONED, null);
-            return;
-        }
-
-        Phone phone = getPhoneOrDefault(validSubId, "requestTimeForNextSatelliteVisibility");
-        if (phone == null) {
-            result.send(SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE, null);
-            return;
-        }
-
-        sendRequestAsync(CMD_GET_TIME_SATELLITE_NEXT_VISIBLE, result, phone, null);
-    }
-
-    private void handleEventProvisionSatelliteServiceDone(
-            @NonNull ProvisionSatelliteServiceArgument arg,
-            @SatelliteManager.SatelliteError int result) {
-        log("handleEventProvisionSatelliteServiceDone: result="
-                + result + ", subId=" + arg.subId);
-
-        Consumer<Integer> callback = mSatelliteProvisionCallbacks.remove(arg.subId);
-        if (callback == null) {
-            loge("handleEventProvisionSatelliteServiceDone: callback is null for subId="
-                    + arg.subId);
-            return;
-        }
-        callback.accept(result);
-
-        if (result == SatelliteManager.SATELLITE_ERROR_NONE) {
-            setSatelliteProvisioned(arg.subId, true);
-        }
-
-        /**
-         * We need to update satellite provision status in SubscriptionController
-         * or SatelliteController.
-         * TODO (b/267826133) we need to do this for all subscriptions on the device.
-         */
-        registerForSatelliteProvisionStateChangedInternal(arg.subId, null);
-    }
-
-    private void handleEventDeprovisionSatelliteServiceDone(
-            @NonNull ProvisionSatelliteServiceArgument arg,
-            @SatelliteManager.SatelliteError int result) {
-        if (arg == null) {
-            loge("handleEventDeprovisionSatelliteServiceDone: arg is null");
-            return;
-        }
-        log("handleEventDeprovisionSatelliteServiceDone: result="
-                + result + ", subId=" + arg.subId);
-
-        if (arg.callback != null) {
-            arg.callback.accept(result);
-        }
-
-        if (result == SatelliteManager.SATELLITE_ERROR_NONE) {
-            setSatelliteProvisioned(arg.subId, false);
-        }
+        mSatelliteController.requestTimeForNextSatelliteVisibility(subId, result);
     }
 
     private Phone getPhoneOrDefault(int subId, String caller) {
@@ -13788,211 +12479,6 @@
     }
 
     /**
-     * Check if satellite is provisioned for a subscription or the device.
-     *
-     * Note: this is the version without permission check for telephony internal use only. The
-     * caller need to take care of the permission check.
-     */
-    private boolean isSatelliteProvisioned(int subId) {
-        if (subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            if (mSubscriptionController == null) {
-                loge("isSatelliteProvisioned mSubscriptionController is null");
-                return false;
-            }
-
-            String strResult = mSubscriptionController.getSubscriptionProperty(
-                    subId, SubscriptionManager.SATELLITE_ENABLED);
-            if (strResult != null) {
-                int intResult = Integer.parseInt(strResult);
-                return (intResult == 1) ? true : false;
-            }
-        } else {
-            //TODO (b/267826133): check via SatelliteController
-        }
-        return false;
-    }
-
-    /**
-     * Set satellite provisioned for a subscription or the device.
-     *
-     * The permission {@link android.Manifest.permission#MODIFY_PHONE_STATE} will be enforced by
-     * {@link SubscriptionController} when setting satellite enabled for an active subscription.
-     * Otherwise, {@link android.Manifest.permission#SATELLITE_COMMUNICATION} will be enforced.
-     */
-    private synchronized void setSatelliteProvisioned(int subId, boolean isEnabled) {
-        if (subId != SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
-            if (mSubscriptionController == null) {
-                loge("setSatelliteProvisioned mSubscriptionController is null");
-                return;
-            }
-            mSubscriptionController.setSubscriptionProperty(
-                    subId, SubscriptionManager.SATELLITE_ENABLED, isEnabled ? "1" : "0");
-        } else {
-            //TODO (b/267826133): set via SatelliteController
-        }
-    }
-
-    private int getValidSatelliteSubId(int subId) {
-        if (mSubscriptionController == null) {
-            loge("getValidSatelliteSubId mSubscriptionController is null. "
-                    + "Use DEFAULT_SUBSCRIPTION_ID for subId=" + subId);
-            return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
-        }
-        final long identity = Binder.clearCallingIdentity();
-        try {
-            Context context = getDefaultPhone().getContext();
-            if (mSubscriptionController.isActiveSubId(
-                    subId, context.getOpPackageName(), context.getAttributionTag())) {
-                return subId;
-            }
-        } finally {
-            Binder.restoreCallingIdentity(identity);
-        }
-        if (DBG) log("getValidSatelliteSubId: use DEFAULT_SUBSCRIPTION_ID for subId=" + subId);
-        return SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
-    }
-
-    /**
-     * If we have not successfully queried the satellite modem for its satellite service support,
-     * we will retry the query one more time. Otherwise, we will return the queried result.
-     */
-    private boolean isSatelliteSupported() {
-        synchronized (mIsSatelliteSupportedLock) {
-            if (mIsSatelliteSupported != null) {
-                /* We have already successfully queried the satellite modem. */
-                return mIsSatelliteSupported;
-            }
-        }
-        /**
-         * We have not successfully checked whether the modem supports satellite service.
-         * Thus, we need to retry it now.
-         */
-        requestIsSatelliteSupported(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID,
-                mSatelliteSupportedReceiver);
-        return false;
-    }
-
-    /**
-     * Get the {@link SatelliteManager.SatelliteError} from the provided result.
-     *
-     * @param ar AsyncResult used to determine the error code.
-     * @param caller The satellite request.
-     * @param checkResult Whether to check if the result exists.
-     *
-     * @return The {@link SatelliteManager.SatelliteError} error code from the request.
-     */
-    @SatelliteManager.SatelliteError private int getSatelliteError(@NonNull AsyncResult ar,
-            @NonNull String caller, boolean checkResult) {
-        int errorCode;
-        if (ar.exception == null) {
-            errorCode = SatelliteManager.SATELLITE_ERROR_NONE;
-            if (checkResult && ar.result == null) {
-                loge(caller + ": result is null");
-                errorCode = SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
-            }
-        } else {
-            errorCode = SatelliteManager.SATELLITE_ERROR;
-            if (ar.exception instanceof CommandException) {
-                CommandException.Error error = ((CommandException) ar.exception).getCommandError();
-                errorCode = RILUtils.convertToSatelliteError(error);
-                loge(caller + " CommandException: " + ar.exception);
-            } else if (ar.exception instanceof SatelliteManager.SatelliteException) {
-                errorCode = ((SatelliteManager.SatelliteException) ar.exception).getErrorCode();
-                loge(caller + " SatelliteException: " + ar.exception);
-            } else {
-                loge(caller + " unknown exception: " + ar.exception);
-            }
-        }
-        log(caller + " error: " + errorCode);
-        return errorCode;
-    }
-
-    /**
-     * Registers for the satellite provision state changed.
-     *
-     * @param subId The subId of the subscription associated with the satellite service.
-     * @param callback The callback to handle the satellite provision state changed event.
-     *
-     * @return The {@link SatelliteManager.SatelliteError} result of the operation.
-     */
-    @SatelliteManager.SatelliteError private int registerForSatelliteProvisionStateChangedInternal(
-            int subId, @Nullable ISatelliteProvisionStateCallback callback) {
-        if (!isSatelliteSupported()) {
-            return SatelliteManager.SATELLITE_NOT_SUPPORTED;
-        }
-
-        final int validSubId = getValidSatelliteSubId(subId);
-        Phone phone = getPhoneOrDefault(validSubId, "registerForSatelliteProvisionStateChanged");
-        if (phone == null) {
-            return SatelliteManager.SATELLITE_INVALID_TELEPHONY_STATE;
-        }
-
-        SatelliteProvisionStateChangedHandler satelliteProvisionStateChangedHandler =
-                mSatelliteProvisionStateChangedHandlers.get(validSubId);
-        if (satelliteProvisionStateChangedHandler == null) {
-            satelliteProvisionStateChangedHandler = new SatelliteProvisionStateChangedHandler(
-                    Looper.getMainLooper(), validSubId);
-            if (mIsSatelliteServiceSupported) {
-                mSatelliteServiceController.registerForSatelliteProvisionStateChanged(
-                        satelliteProvisionStateChangedHandler,
-                        SatelliteProvisionStateChangedHandler.EVENT_PROVISION_STATE_CHANGED, null);
-            } else {
-                phone.registerForSatelliteProvisionStateChanged(
-                        satelliteProvisionStateChangedHandler,
-                        SatelliteProvisionStateChangedHandler.EVENT_PROVISION_STATE_CHANGED, null);
-            }
-        }
-
-        if (callback != null) {
-            satelliteProvisionStateChangedHandler.addListener(callback);
-        }
-        mSatelliteProvisionStateChangedHandlers.put(
-                validSubId, satelliteProvisionStateChangedHandler);
-        return SatelliteManager.SATELLITE_ERROR_NONE;
-    }
-
-    private void handleStartSatellitePositionUpdatesDone(@NonNull AsyncResult ar) {
-        MainThreadRequest request = (MainThreadRequest) ar.userObj;
-        SatellitePositionUpdateArgument arg = (SatellitePositionUpdateArgument) request.argument;
-        int errorCode = getSatelliteError(
-                ar, "handleStartSatellitePositionUpdatesDone", false);
-        arg.errorCallback.accept(errorCode);
-
-        if (errorCode != SatelliteManager.SATELLITE_ERROR_NONE) {
-            /**
-             * We need to remove the callback from our listener list since the caller might not call
-             * {@link #stopSatellitePositionUpdates(int, IIntegerConsumer, ISatellitePositionUpdateCallback)}
-             * to unregister the callback in case of failure.
-             */
-            SatellitePositionUpdateHandler handler =
-                    mSatellitePositionUpdateHandlers.get(arg.subId);
-            if (handler != null) {
-                handler.removeListener(arg.callback);
-
-                if (!handler.hasListeners()) {
-                    mSatellitePositionUpdateHandlers.remove(arg.subId);
-
-                    if (mIsSatelliteServiceSupported) {
-                        mSatelliteServiceController.unregisterForSatellitePositionInfoChanged(
-                                handler);
-                        mSatelliteServiceController.unregisterForDatagramTransferStateChanged(
-                                handler);
-                    } else {
-                        Phone phone = getPhoneFromRequest(request);
-                        if (phone == null) {
-                            loge("handleStartSatellitePositionUpdatesDone: phone is null");
-                        } else {
-                            phone.unregisterForSatellitePositionInfoChanged(handler);
-                            // TODO: unregisterForDatagramTransferStateChanged through
-                            //  SatelliteController
-                        }
-                    }
-                }
-            }
-        }
-    }
-
-    /**
      * Check whether the caller (or self, if not processing an IPC) can read device identifiers.
      *
      * <p>This method behaves in one of the following ways:
