Merge "Add satellite provision APIs"
diff --git a/telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl b/telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl
similarity index 82%
rename from telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl
rename to telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl
index 5c3fa32..6fb0979 100644
--- a/telephony/java/android/telephony/satellite/ISatellitePositionUpdateCallback.aidl
+++ b/telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl
@@ -19,10 +19,11 @@
 import android.telephony.satellite.PointingInfo;
 
 /**
- * Callback for position updates from the satellite service.
+ * Interface for satellite state listener.
  * @hide
  */
-oneway interface ISatellitePositionUpdateCallback {
+oneway interface ISatelliteStateListener {
+    void onSatelliteProvisionStateChanged(in int[] features, in boolean provisioned);
     void onSatellitePositionUpdate(in PointingInfo pointingInfo);
     void onMessageTransferStateUpdate(in int state);
 }
diff --git a/telephony/java/android/telephony/satellite/SatelliteCallback.java b/telephony/java/android/telephony/satellite/SatelliteCallback.java
new file mode 100644
index 0000000..1b82d06
--- /dev/null
+++ b/telephony/java/android/telephony/satellite/SatelliteCallback.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite;
+
+import android.annotation.NonNull;
+import android.os.Binder;
+import android.telephony.satellite.stub.SatelliteImplBase;
+
+import java.lang.ref.WeakReference;
+import java.util.concurrent.Executor;
+
+/**
+ * A callback class for monitoring changes in specific satellite service states on the device,
+ * including provision state, position update, message transfer state and others.
+ * <p>
+ * To register a callback, use a {@link SatelliteCallback} which implements the interested
+ * interfaces. For example,
+ * FakeSatelliteProvisionStateCallback extends {@link SatelliteCallback} implements
+ * {@link SatelliteCallback.SatelliteProvisionStateListener}.
+ * <p>
+ * Then override the methods for the state that you wish to receive updates for, and
+ * pass your SatelliteCallback object to the corresponding register function like
+ * {@link SatelliteManager#registerForSatelliteProvisionStateChanged}.
+ * <p>
+ *
+ * @hide
+ */
+public class SatelliteCallback {
+    private ISatelliteStateListener mCallbackStub;
+
+    /**
+     * The SatelliteCallback needs an executor to execute the callback interfaces.
+     */
+    public void init(@NonNull Executor executor) {
+        if (executor == null) {
+            throw new IllegalArgumentException("SatelliteCallback executor must be non-null");
+        }
+        mCallbackStub = new ISatelliteStateListenerStub(this, executor);
+    }
+
+    public ISatelliteStateListener getCallbackStub() {
+        return mCallbackStub;
+    }
+
+    /**
+     * Interface for satellite provision state change listener.
+     */
+    public interface SatelliteProvisionStateListener {
+        /**
+         * Called when satellite provision state changes.
+         *
+         * @param features The list of provisioned features.
+         * @param provisioned The new provision state. {@code true} means satellite is provisioned
+         *                    {@code false} means satellite is not provisioned.
+         */
+        void onSatelliteProvisionStateChanged(
+                @SatelliteImplBase.Feature int[] features, boolean provisioned);
+    }
+
+    /**
+     * Interface for position update change listener.
+     */
+    public interface SatellitePositionUpdateListener {
+        /**
+         * Called when the satellite position changes.
+         *
+         * @param pointingInfo The pointing info containing the satellite location.
+         */
+        void onSatellitePositionUpdate(@NonNull PointingInfo pointingInfo);
+
+        /**
+         * Called when satellite message transfer state changes.
+         *
+         * @param state The new message transfer state.
+         */
+        void onMessageTransferStateUpdate(
+                @SatelliteManager.SatelliteMessageTransferState int state);
+    }
+
+    private static class ISatelliteStateListenerStub extends ISatelliteStateListener.Stub {
+        private WeakReference<SatelliteCallback> mSatelliteCallbackWeakRef;
+        private Executor mExecutor;
+
+        ISatelliteStateListenerStub(SatelliteCallback satelliteCallback, Executor executor) {
+            mSatelliteCallbackWeakRef = new WeakReference<>(satelliteCallback);
+            mExecutor = executor;
+        }
+
+        public void onSatelliteProvisionStateChanged(
+                @SatelliteImplBase.Feature int[] features, boolean provisioned) {
+            SatelliteProvisionStateListener listener =
+                    (SatelliteProvisionStateListener) mSatelliteCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
+                    () -> listener.onSatelliteProvisionStateChanged(features, provisioned)));
+        }
+
+        public void onSatellitePositionUpdate(@NonNull PointingInfo pointingInfo) {
+            SatellitePositionUpdateListener listener =
+                    (SatellitePositionUpdateListener) mSatelliteCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
+                    () -> listener.onSatellitePositionUpdate(pointingInfo)));
+        }
+
+        public void onMessageTransferStateUpdate(
+                @SatelliteManager.SatelliteMessageTransferState int state) {
+            SatellitePositionUpdateListener listener =
+                    (SatellitePositionUpdateListener) mSatelliteCallbackWeakRef.get();
+            if (listener == null) return;
+
+            Binder.withCleanCallingIdentity(() -> mExecutor.execute(
+                    () -> listener.onMessageTransferStateUpdate(state)));
+        }
+    }
+}
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 7a60c58..ea9bca3 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -26,26 +26,29 @@
 import android.content.Context;
 import android.content.pm.PackageManager;
 import android.os.Binder;
+import android.os.CancellationSignal;
+import android.os.ICancellationSignal;
 import android.os.RemoteException;
 import android.telephony.SubscriptionManager;
 import android.telephony.TelephonyFrameworkInitializer;
-import android.util.ArrayMap;
+import android.telephony.satellite.stub.SatelliteImplBase;
 
+import com.android.internal.telephony.IIntArrayConsumer;
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.ITelephony;
 import com.android.telephony.Rlog;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
-import java.util.Map;
 import java.util.Objects;
 import java.util.concurrent.Executor;
-import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 
 /**
  * Manages satellite operations such as provisioning, pointing, messaging, location sharing, etc.
- * To get the object, call {@link Context#getSystemService(Context.SATELLITE_SERVICE)}.
+ * To get the object, call {@link Context#getSystemService(String)}. This object is associated
+ * with the {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} and the satellite service is
+ * associated with the device rather than a subscription.
  * To create an instance of {@link SatelliteManager} associated with a specific subscription ID,
  * call {@link #createForSubscriptionId(int)}.
  *
@@ -56,18 +59,11 @@
     private static final String TAG = "SatelliteManager";
 
     /**
-     * Map of all SatellitePositionUpdateCallback and their associated callback ids.
-     */
-    private final Map<SatellitePositionUpdateCallback, Integer> mSatellitePositionUpdateCallbacks =
-            new ArrayMap<>();
-
-    /**
-     * AtomicInteger for the id of the next SatellitePositionUpdateCallback.
-     */
-    private final AtomicInteger mSatellitePositionUpdateCallbackId = new AtomicInteger(0);
-
-    /**
-     * The subscription ID for this SatelliteManager.
+     * The subscription ID for this SatelliteManager. If the
+     * {@link SubscriptionManager#DEFAULT_SUBSCRIPTION_ID} is used, the satellite service will be
+     * associated with the device rather than a subscription. If an active subscription ID
+     * {@link SubscriptionManager#isActiveSubId(int)} is provided, the satellite service will be
+     * associated with that active subscription.
      */
     private final int mSubId;
 
@@ -82,7 +78,6 @@
      * @param context The context the SatelliteManager belongs to.
      */
     public SatelliteManager(@Nullable Context context) {
-        // TODO: replace DEFAULT_SUBSCRIPTION_ID with DEFAULT_SATELLITE_SUBSCRIPTION_ID
         this(context, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
     }
 
@@ -120,23 +115,24 @@
      */
     public static final int SATELLITE_SERVICE_SERVER_ERROR = 2;
     /**
-     * Unexpected telephony internal error.
+     * Telephony is not in a valid state to serve requests from clients.
      */
-    public static final int SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR = 3;
+    public static final int SATELLITE_SERVICE_INVALID_TELEPHONY_STATE = 3;
     /**
-     * Modem error received from the satellite service.
+     * RIL layer got an unexpected or incorrect response from modem for a request.
      */
-    public static final int SATELLITE_SERVICE_MODEM_ERROR = 4;
+    public static final int SATELLITE_SERVICE_UNEXPECTED_MODEM_RESPONSE = 4;
     /**
-     * System error received from the satellite service.
+     * An error in the RIL layer occurs when processing a request. This generic RIL error should be
+     * used only when other RIL specific errors cannot be used.
      */
-    public static final int SATELLITE_SERVICE_SYSTEM_ERROR = 5;
+    public static final int SATELLITE_SERVICE_RIL_ERROR = 5;
     /**
-     * Invalid arguments passed.
+     * RIL layer has received a request with invalid arguments from the Telephony framework.
      */
     public static final int SATELLITE_SERVICE_INVALID_ARGUMENTS = 6;
     /**
-     * Invalid modem state.
+     * Satellite modem is not in a valid state to serve requests from clients.
      */
     public static final int SATELLITE_SERVICE_INVALID_MODEM_STATE = 7;
     /**
@@ -144,67 +140,203 @@
      */
     public static final int SATELLITE_SERVICE_INVALID_SIM_STATE = 8;
     /**
-     * Invalid state.
+     * RIL layer is not in a valid state to serve requests from clients.
      */
-    public static final int SATELLITE_SERVICE_INVALID_STATE = 9;
+    public static final int SATELLITE_SERVICE_INVALID_RIL_STATE = 9;
     /**
-     * Satellite service is unavailable.
+     * Radio did not start or is resetting.
      */
-    public static final int SATELLITE_SERVICE_NOT_AVAILABLE = 10;
+    public static final int SATELLITE_SERVICE_RADIO_NOT_AVAILABLE = 10;
     /**
-     * Satellite service is not supported by the device or OS.
+     * The request is not supported by either the satellite modem or the network.
      */
-    public static final int SATELLITE_SERVICE_NOT_SUPPORTED = 11;
+    public static final int SATELLITE_SERVICE_REQUEST_NOT_SUPPORTED = 11;
     /**
-     * Satellite service is rate limited.
+     * Requests denied by the satellite modem or the network due to overly-frequent requests.
      */
-    public static final int SATELLITE_SERVICE_RATE_LIMITED = 12;
+    public static final int SATELLITE_SERVICE_REQUEST_RATE_LIMITED = 12;
     /**
-     * Satellite service has no memory available.
+     * Satellite modem or network has no resources available to handle requests from clients.
      */
-    public static final int SATELLITE_SERVICE_NO_MEMORY = 13;
+    public static final int SATELLITE_SERVICE_NO_RESOURCES = 13;
     /**
-     * Satellite service has no resources available.
+     * Telephony framework failed to send a request to the satellite service on the device or the
+     * satellite modem.
      */
-    public static final int SATELLITE_SERVICE_NO_RESOURCES = 14;
+    public static final int SATELLITE_SERVICE_REQUEST_FAILED = 14;
     /**
-     * Failed to send a request to the satellite service.
+     * A generic error which should be used only when other specific errors cannot be used.
      */
-    public static final int SATELLITE_SERVICE_REQUEST_FAILED = 15;
+    public static final int SATELLITE_SERVICE_ERROR = 15;
     /**
-     * Failed to send a request to the satellite service for the given subscription ID.
+     * Satellite service is disabled on the requested subscription or the device.
      */
-    public static final int SATELLITE_SERVICE_INVALID_SUBSCRIPTION_ID = 16;
+    public static final int SATELLITE_SERVICE_DISABLED = 16;
     /**
-     * Error received from satellite service.
+     * Satellite is already provisioned for the subscription or the device.
      */
-    public static final int SATELLITE_SERVICE_ERROR = 17;
+    public static final int SATELLITE_SERVICE_ALREADY_PROVISIONED = 17;
     /**
-     * Satellite service is disabled on the requested subscription.
+     * Provisioning is already in progress.
      */
-    public static final int SATELLITE_SERVICE_DISABLED = 18;
+    public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 18;
+    /**
+     * The ongoing request was aborted by either the satellite modem or the network.
+     */
+    public static final int SATELLITE_SERVICE_REQUEST_ABORTED = 19;
+    /**
+     * The device/subscription is barred to access the satellite service.
+     */
+    public static final int SATELLITE_SERVICE_ACCESS_BARRED = 20;
+    /**
+     * The requesting feature is not supported by the satellite service provider.
+     */
+    public static final int SATELLITE_SERVICE_FEATURE_NOT_SUPPORTED = 21;
+    /**
+     * The modem of the device is not compatible with the satellite service provider.
+     */
+    public static final int SATELLITE_SERVICE_MODEM_INCOMPATIBLE = 22;
+    /**
+     * The satellite network is not ready to serve requests from clients.
+     */
+    public static final int SATELLITE_SERVICE_NETWORK_NOT_READY = 23;
+    /**
+     * The satellite server is not ready to serve requests from clients.
+     */
+    public static final int SATELLITE_SERVICE_SERVER_NOT_READY = 24;
+    /**
+     * The request was rejected by the satellite server.
+     */
+    public static final int SATELLITE_SERVICE_SERVER_REJECT = 25;
+    /**
+     * Satellite modem timeout to receive ACK or response from the satellite network after
+     * sending a request to the network.
+     */
+    public static final int SATELLITE_SERVICE_NETWORK_TIMEOUT = 26;
+    /**
+     * Satellite modem cannot detect any satellite signal.
+     */
+    public static final int SATELLITE_SERVICE_NO_SATELLITE_SIGNAL = 27;
+    /**
+     * Device does not have a subscription.
+     */
+    public static final int SATELLITE_SERVICE_NO_SUBSCRIPTION = 28;
+    /**
+     * Operation is not allowed by either the satellite modem, or satellite network, or satellite
+     * server.
+     */
+    public static final int SATELLITE_SERVICE_OPERATION_NOT_ALLOWED = 29;
+    /**
+     * The radio technology is not supported by the satellite service provider.
+     */
+    public static final int SATELLITE_SERVICE_RADIO_TECHNOLOGY_NOT_SUPPORTED = 30;
+    /**
+     * SIM is absent.
+     */
+    public static final int SATELLITE_SERVICE_SIM_ABSENT = 31;
+    /**
+     * SIM is busy.
+     */
+    public static final int SATELLITE_SERVICE_SIM_BUSY = 32;
+    /**
+     * Received error from SIM card.
+     */
+    public static final int SATELLITE_SERVICE_SIM_ERR = 33;
+    /**
+     * The target EF is full.
+     */
+    public static final int SATELLITE_SERVICE_SIM_FULL = 34;
+    /**
+     * The subscription/user is not authorized to register with the satellite service provider.
+     */
+    public static final int SATELLITE_SERVICE_SUBSCRIBER_NOT_AUTHORIZED = 35;
+    /**
+     * The callback was already registered with Telephony framework.
+     */
+    public static final int SATELLITE_SERVICE_CALLBACK_ALREADY_REGISTERED = 36;
+    /**
+     * The callback was not registered with Telephony framework.
+     */
+    public static final int SATELLITE_SERVICE_CALLBACK_NOT_REGISTERED = 37;
+    /**
+     * The request cannot be performed since the subscriber/user's account balance is not
+     * sufficient.
+     */
+    public static final int SATELLITE_SERVICE_NOT_SUFFICIENT_ACCOUNT_BALANCE = 38;
+    /**
+     * While processing a request from the Telephony framework, the satellite modem detects
+     * terrestrial signal, aborts the request, and switches to the terrestrial network.
+     */
+    public static final int SATELLITE_SERVICE_SWITCHED_FROM_SATELLITE_TO_TERRESTRIAL = 39;
+    /**
+     * The subscriber/user is not registered with the service provider.
+     */
+    public static final int SATELLITE_SERVICE_UNIDENTIFIED_SUBSCRIBER = 40;
+    /**
+     * The contact to be added/removed is either not existing or not valid.
+     */
+    public static final int SATELLITE_SERVICE_INVALID_CONTACT = 41;
+    /**
+     * The encoding scheme is not supported by either the satellite provider or the device.
+     */
+    public static final int SATELLITE_SERVICE_ENCODING_NOT_SUPPORTED = 42;
+    /**
+     * Received error from the satellite network. This generic error code should be used only when
+     * the error cannot be mapped to other specific network error codes.
+     */
+    public static final int SATELLITE_SERVICE_NETWORK_ERROR = 43;
+    /**
+     * Modem hit unexpected error scenario while handling this request.
+     */
+    public static final int SATELLITE_SERVICE_MODEM_ERROR = 44;
 
     /** @hide */
     @IntDef(prefix = {"SATELLITE_SERVICE_"}, value = {
             SATELLITE_SERVICE_SUCCESS,
             SATELLITE_SERVICE_SERVER_NOT_REACHABLE,
             SATELLITE_SERVICE_SERVER_ERROR,
-            SATELLITE_SERVICE_TELEPHONY_INTERNAL_ERROR,
-            SATELLITE_SERVICE_MODEM_ERROR,
-            SATELLITE_SERVICE_SYSTEM_ERROR,
+            SATELLITE_SERVICE_INVALID_TELEPHONY_STATE,
+            SATELLITE_SERVICE_UNEXPECTED_MODEM_RESPONSE,
+            SATELLITE_SERVICE_RIL_ERROR,
             SATELLITE_SERVICE_INVALID_ARGUMENTS,
             SATELLITE_SERVICE_INVALID_MODEM_STATE,
             SATELLITE_SERVICE_INVALID_SIM_STATE,
-            SATELLITE_SERVICE_INVALID_STATE,
-            SATELLITE_SERVICE_NOT_AVAILABLE,
-            SATELLITE_SERVICE_NOT_SUPPORTED,
-            SATELLITE_SERVICE_RATE_LIMITED,
-            SATELLITE_SERVICE_NO_MEMORY,
+            SATELLITE_SERVICE_INVALID_RIL_STATE,
+            SATELLITE_SERVICE_RADIO_NOT_AVAILABLE,
+            SATELLITE_SERVICE_REQUEST_NOT_SUPPORTED,
+            SATELLITE_SERVICE_REQUEST_RATE_LIMITED,
             SATELLITE_SERVICE_NO_RESOURCES,
             SATELLITE_SERVICE_REQUEST_FAILED,
-            SATELLITE_SERVICE_INVALID_SUBSCRIPTION_ID,
             SATELLITE_SERVICE_ERROR,
-            SATELLITE_SERVICE_DISABLED
+            SATELLITE_SERVICE_DISABLED,
+            SATELLITE_SERVICE_ALREADY_PROVISIONED,
+            SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
+            SATELLITE_SERVICE_REQUEST_ABORTED,
+            SATELLITE_SERVICE_ACCESS_BARRED,
+            SATELLITE_SERVICE_FEATURE_NOT_SUPPORTED,
+            SATELLITE_SERVICE_MODEM_INCOMPATIBLE,
+            SATELLITE_SERVICE_NETWORK_NOT_READY,
+            SATELLITE_SERVICE_SERVER_NOT_READY,
+            SATELLITE_SERVICE_SERVER_REJECT,
+            SATELLITE_SERVICE_NETWORK_TIMEOUT,
+            SATELLITE_SERVICE_NO_SATELLITE_SIGNAL,
+            SATELLITE_SERVICE_NO_SUBSCRIPTION,
+            SATELLITE_SERVICE_OPERATION_NOT_ALLOWED,
+            SATELLITE_SERVICE_RADIO_TECHNOLOGY_NOT_SUPPORTED,
+            SATELLITE_SERVICE_SIM_ABSENT,
+            SATELLITE_SERVICE_SIM_BUSY,
+            SATELLITE_SERVICE_SIM_ERR,
+            SATELLITE_SERVICE_SIM_FULL,
+            SATELLITE_SERVICE_SUBSCRIBER_NOT_AUTHORIZED,
+            SATELLITE_SERVICE_CALLBACK_ALREADY_REGISTERED,
+            SATELLITE_SERVICE_CALLBACK_NOT_REGISTERED,
+            SATELLITE_SERVICE_NOT_SUFFICIENT_ACCOUNT_BALANCE,
+            SATELLITE_SERVICE_SWITCHED_FROM_SATELLITE_TO_TERRESTRIAL,
+            SATELLITE_SERVICE_UNIDENTIFIED_SUBSCRIBER,
+            SATELLITE_SERVICE_INVALID_CONTACT,
+            SATELLITE_SERVICE_ENCODING_NOT_SUPPORTED,
+            SATELLITE_SERVICE_NETWORK_ERROR,
+            SATELLITE_SERVICE_MODEM_ERROR
     })
     @Retention(RetentionPolicy.SOURCE)
     public @interface SatelliteServiceResult {}
@@ -241,73 +373,29 @@
     public @interface SatelliteMessageTransferState {}
 
     /**
-     * Callback for position updates from the satellite service.
-     */
-    public interface SatellitePositionUpdateCallback {
-        /**
-         * Called when the satellite position changes.
-         *
-         * @param pointingInfo The pointing info containing the satellite location.
-         */
-        void onSatellitePositionUpdate(@NonNull PointingInfo pointingInfo);
-
-        /**
-         * Called when satellite message transfer state changes.
-         *
-         * @param state The new message transfer state.
-         */
-        void onMessageTransferStateUpdate(@SatelliteMessageTransferState int state);
-    }
-
-    /**
      * Start receiving satellite position updates.
      * This can be called by the pointing UI when the user starts pointing to the satellite.
      * Modem should continue to report the pointing input as the device or satellite moves.
      * Satellite position updates are started only on {@link #SATELLITE_SERVICE_SUCCESS}.
      * All other results indicate that this operation failed.
      *
-     * @param executor The executor to run callbacks on.
-     * @param callback The callback to notify of changes in satellite position.
+     * @param executor - The executor on which the callback will be called.
+     * @param callback The callback to notify of changes in satellite position. This
+     *                 SatelliteCallback should implement the interface
+     *                 {@link SatelliteCallback.SatellitePositionUpdateListener}.
      * @return The result of the operation.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @SatelliteServiceResult public int startSatellitePositionUpdates(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull SatellitePositionUpdateCallback callback) {
+            @NonNull Executor executor, @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(executor);
         Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                int id;
-                if (mSatellitePositionUpdateCallbacks.containsKey(callback)) {
-                    id = mSatellitePositionUpdateCallbacks.get(callback);
-                } else {
-                    id = mSatellitePositionUpdateCallbackId.getAndIncrement();
-                }
-                int result = telephony.startSatellitePositionUpdates(mSubId, id,
-                        new ISatellitePositionUpdateCallback.Stub() {
-                            @Override
-                            public void onSatellitePositionUpdate(
-                                    @NonNull PointingInfo pointingInfo) {
-                                logd("onSatellitePositionUpdate: pointingInfo=" + pointingInfo);
-                                executor.execute(() -> Binder.withCleanCallingIdentity(
-                                        () -> callback.onSatellitePositionUpdate(pointingInfo)));
-                            }
-
-                            @Override
-                            public void onMessageTransferStateUpdate(
-                                    @SatelliteMessageTransferState int state) {
-                                logd("onMessageTransferStateUpdate: state=" + state);
-                                executor.execute(() -> Binder.withCleanCallingIdentity(
-                                        () -> callback.onMessageTransferStateUpdate(state)));
-                            }
-                        });
-                if (result == SATELLITE_SERVICE_SUCCESS) {
-                    mSatellitePositionUpdateCallbacks.put(callback, id);
-                }
-                return result;
+                callback.init(executor);
+                return telephony.startSatellitePositionUpdates(mSubId, callback.getCallbackStub());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -325,30 +413,20 @@
      * All other results indicate that this operation failed.
      *
      * @param callback The callback that was passed in {@link
-     *                 #startSatellitePositionUpdates(Executor, SatellitePositionUpdateCallback)}.
+     *                 #startSatellitePositionUpdates(Executor, SatelliteCallback)}.
      * @return The result of the operation.
      * @throws IllegalArgumentException if the callback is invalid.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     @SatelliteServiceResult public int stopSatellitePositionUpdates(
-            @NonNull SatellitePositionUpdateCallback callback) {
+            @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(callback);
 
-        if (!mSatellitePositionUpdateCallbacks.containsKey(callback)) {
-            throw new IllegalArgumentException(
-                    "startSatellitePositionUpdates was never called with the callback provided.");
-        }
-
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                int result = telephony.stopSatellitePositionUpdates(mSubId,
-                        mSatellitePositionUpdateCallbacks.get(callback));
-                if (result == SATELLITE_SERVICE_SUCCESS) {
-                    mSatellitePositionUpdateCallbacks.remove(callback);
-                    // TODO: Notify SmsHandler that pointing UI stopped
-                }
-                return result;
+                return telephony.stopSatellitePositionUpdates(mSubId, callback.getCallbackStub());
+                // TODO: Notify SmsHandler that pointing UI stopped
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -399,6 +477,164 @@
         return SATELLITE_SERVICE_REQUEST_FAILED;
     }
 
+
+    /**
+     * Register the subscription with a satellite provider. This is needed if the provider allows
+     * dynamic registration.
+     *
+     * @param features List of features to be provisioned.
+     * @param executor The optional executor to run callbacks on.
+     * @param callback The optional callback to get the error code of the request.
+     * @param cancellationSignal The optional signal used by the caller to cancel the provision
+     *                           request. Even when the cancellation is signaled, Telephony will
+     *                           still trigger the callback to return the result of this request.
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    public void provisionSatelliteService(
+            @NonNull @SatelliteImplBase.Feature int[] features,
+            @Nullable @CallbackExecutor Executor executor,
+            @SatelliteServiceResult @Nullable Consumer<Integer> callback,
+            @Nullable CancellationSignal cancellationSignal) {
+        Objects.requireNonNull(features);
+
+        ICancellationSignal cancelRemote = null;
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                IIntegerConsumer callbackStub = new IIntegerConsumer.Stub() {
+                    @Override
+                    public void accept(int result) {
+                        if (executor == null || callback == null) {
+                            logd("provisionSatelliteService: executor and/or callback is null");
+                            return;
+                        }
+                        Binder.withCleanCallingIdentity(() -> {
+                            executor.execute(() -> callback.accept(result));
+                        });
+                    }
+                };
+                cancelRemote = telephony.provisionSatelliteService(mSubId, features, callbackStub);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("provisionSatelliteService RemoteException=" + ex);
+            ex.rethrowFromSystemServer();
+        }
+        if (cancellationSignal != null) {
+            cancellationSignal.setRemote(cancelRemote);
+        }
+    }
+
+    /**
+     * Register for the satellite provision state change.
+     *
+     * @param executor - The executor on which the callback will be called.
+     * @param callback The callback to handle the satellite provision state changed event. This
+     *                 SatelliteCallback should implement the interface
+     *                 {@link SatelliteCallback.SatelliteProvisionStateListener}.
+     * @return The error code of the request.
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteServiceResult
+    public int registerForSatelliteProvisionStateChanged(
+            @NonNull Executor executor, @NonNull SatelliteCallback callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                callback.init(executor);
+                return telephony.registerForSatelliteProvisionStateChanged(
+                        mSubId, callback.getCallbackStub());
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("registerForSatelliteProvisionStateChanged RemoteException: " + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_SERVICE_REQUEST_FAILED;
+    }
+
+    /**
+     * Unregister for the satellite provision state change.
+     *
+     * @param callback The callback that was passed to
+     * {@link #registerForSatelliteProvisionStateChanged(Executor, SatelliteCallback)}
+     * @return The error code of the request.
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteServiceResult
+    public int unregisterForSatelliteProvisionStateChanged(@NonNull SatelliteCallback callback) {
+        Objects.requireNonNull(callback);
+
+        if (callback.getCallbackStub() == null) {
+            loge("unregisterForSatelliteProvisionStateChanged: callbackStub is null");
+            return SATELLITE_SERVICE_CALLBACK_NOT_REGISTERED;
+        }
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                return telephony.unregisterForSatelliteProvisionStateChanged(
+                        mSubId, callback.getCallbackStub());
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("unregisterForSatelliteProvisionStateChanged RemoteException: " + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_SERVICE_REQUEST_FAILED;
+    }
+
+    /**
+     * Get the list of provisioned satellite features.
+     *
+     * @param executor The executor to run callbacks on.
+     * @param resultListener The callback to get the list of provisioned features when the request
+     *                       returns success result.
+     * @return The error code of the request.
+     * @throws SecurityException if the caller doesn't have required permission.
+     * @throws IllegalStateException if the Telephony process is not currently available.
+     */
+    @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+    @SatelliteServiceResult
+    public int getProvisionedSatelliteFeatures(
+            @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<int[]> resultListener) {
+        Objects.requireNonNull(resultListener);
+        Objects.requireNonNull(executor);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                IIntArrayConsumer callbackStub = new IIntArrayConsumer.Stub() {
+                    @Override
+                    public void accept(int[] result) {
+                        Binder.withCleanCallingIdentity(() -> {
+                            executor.execute(() -> resultListener.accept(result));
+                        });
+                    }
+                };
+                return telephony.getProvisionedSatelliteFeatures(mSubId, callbackStub);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("getProvisionedSatelliteFeatures() RemoteException:" + ex);
+            ex.rethrowFromSystemServer();
+        }
+        return SATELLITE_SERVICE_REQUEST_FAILED;
+    }
+
     private static ITelephony getITelephony() {
         ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
                 .getTelephonyServiceManager()
diff --git a/telephony/java/com/android/internal/telephony/IIntArrayConsumer.aidl b/telephony/java/com/android/internal/telephony/IIntArrayConsumer.aidl
new file mode 100644
index 0000000..c208755
--- /dev/null
+++ b/telephony/java/com/android/internal/telephony/IIntArrayConsumer.aidl
@@ -0,0 +1,23 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.telephony;
+
+// Copies consumer pattern for an operation that requires an int array result from another
+// process to finish.
+oneway interface IIntArrayConsumer {
+    void accept(in int[] result);
+}
\ No newline at end of file
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 5486365..24483a8 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -21,6 +21,7 @@
 import android.content.Intent;
 import android.content.IntentSender;
 import android.os.Bundle;
+import android.os.ICancellationSignal;
 import android.os.IBinder;
 import android.os.Messenger;
 import android.os.ParcelFileDescriptor;
@@ -66,13 +67,14 @@
 import android.telephony.ims.aidl.IImsRegistration;
 import android.telephony.ims.aidl.IImsRegistrationCallback;
 import android.telephony.ims.aidl.IRcsConfigCallback;
-import android.telephony.satellite.ISatellitePositionUpdateCallback;
+import android.telephony.satellite.ISatelliteStateListener;
 import com.android.ims.internal.IImsServiceFeatureCallback;
 import com.android.internal.telephony.CellNetworkScanResult;
 import com.android.internal.telephony.IBooleanConsumer;
 import com.android.internal.telephony.ICallForwardingInfoCallback;
 import com.android.internal.telephony.IccLogicalChannelRequest;
 import com.android.internal.telephony.IImsStateCallback;
+import com.android.internal.telephony.IIntArrayConsumer;
 import com.android.internal.telephony.IIntegerConsumer;
 import com.android.internal.telephony.INumberVerificationCallback;
 import com.android.internal.telephony.OperatorInfo;
@@ -2702,16 +2704,52 @@
     /**
      * Start receiving satellite pointing updates.
      */
-    int startSatellitePositionUpdates(int subId, int callbackId,
-            in ISatellitePositionUpdateCallback callback);
+    int startSatellitePositionUpdates(int subId, in ISatelliteStateListener callback);
 
     /**
      * Stop receiving satellite pointing updates.
      */
-    int stopSatellitePositionUpdates(int subId, int callbackId);
+    int stopSatellitePositionUpdates(int subId, ISatelliteStateListener callback);
 
     /**
      * Get maximum number of characters per text message on satellite.
      */
     int getMaxCharactersPerSatelliteTextMessage(int subId, IIntegerConsumer internalCallback);
-}
\ No newline at end of file
+
+    /**
+     * Register the subscription with a satellite provider.
+     * This is needed to register the subscription if the provider allows dynamic registration.
+     *
+     * @param subId The subId of the subscription to be provisioned.
+     * @param features List of features to be provisioned.
+     * @param callback The callback to get the error code of the request.
+     * @return The signal transport used by callers to cancel the provision request.
+     */
+    ICancellationSignal provisionSatelliteService(int subId, in int[] features,
+            in IIntegerConsumer callback);
+
+    /**
+     * Register for the satellite provision state change.
+     *
+     * @param subId The subId of the subscription to be provisioned.
+     * @param callback The callback to handle the satellite provision state changed event.
+     */
+    int registerForSatelliteProvisionStateChanged(int subId, ISatelliteStateListener callback);
+
+    /**
+     * Unregister for the satellite provision state change.
+     *
+     * @param subId The subId of the subscription associated with the satellite service.
+     * @param callback The callback that was passed to
+     *                   registerForSatelliteProvisionStateChanged.
+     */
+    int unregisterForSatelliteProvisionStateChanged(int subId, ISatelliteStateListener callback);
+
+    /**
+     * Get the list of provisioned satellite features.
+     *
+     * @param subId The subId of the subscription to be provisioned.
+     * @param callback The callback to get the list of provisioned satellite features.
+     */
+    int getProvisionedSatelliteFeatures(int subId, IIntArrayConsumer callback);
+}
diff --git a/telephony/java/com/android/internal/telephony/RILConstants.java b/telephony/java/com/android/internal/telephony/RILConstants.java
index 6e56963..45daab3 100644
--- a/telephony/java/com/android/internal/telephony/RILConstants.java
+++ b/telephony/java/com/android/internal/telephony/RILConstants.java
@@ -120,6 +120,31 @@
     int BLOCKED_DUE_TO_CALL = 69;                   /* SMS is blocked due to call control */
     int RF_HARDWARE_ISSUE = 70;                     /* RF HW issue is detected */
     int NO_RF_CALIBRATION_INFO = 71;                /* No RF calibration in device */
+    int ENCODING_NOT_SUPPORTED = 72;                /* The encoding scheme is not supported by
+                                                       either the network or the MS. */
+    int FEATURE_NOT_SUPPORTED = 73;                 /* The requesting feature is not supported by
+                                                       the service provider. */
+    int INVALID_CONTACT = 74;                       /* The contact to be added is either not
+                                                       existing or not valid. */
+    int MODEM_INCOMPATIBLE = 75;                    /* The modem of the MS is not compatible with
+                                                       the service provider. */
+    int NETWORK_TIMEOUT = 76;                       /* Modem timeout to receive ACK or response from
+                                                       network after sending a request to it. */
+    int NO_SATELLITE_SIGNAL = 77;                   /* Modem fails to communicate with the satellite
+                                                       network since there is no satellite signal.*/
+    int NOT_SUFFICIENT_ACCOUNT_BALANCE = 78;        /* The request cannot be performed since the
+                                                       subscriber's account balance is not
+                                                       sufficient. */
+    int RADIO_TECHNOLOGY_NOT_SUPPORTED = 79;        /* The radio technology is not supported by the
+                                                       service provider. */
+    int SUBSCRIBER_NOT_AUTHORIZED = 80;             /* The subscription is not authorized to
+                                                       register with the service provider. */
+    int SWITCHED_FROM_SATELLITE_TO_TERRESTRIAL = 81; /* While processing a request from the
+                                                       Framework the satellite modem detects
+                                                       terrestrial signal, aborts the request, and
+                                                       switches to the terrestrial network. */
+    int UNIDENTIFIED_SUBSCRIBER = 82;               /* The subscriber is not registered with the
+                                                       service provider */
 
     // Below is list of OEM specific error codes which can by used by OEMs in case they don't want to
     // reveal particular replacement for Generic failure