Satellite API changes

Have register/unregister methods return the error synchronously.
Add requestIsSatelliteCommunicationAllowedForCurrentLocation
Add requestTimeForNextSatelliteVisibility
Update SatelliteStateListener#onMessageTransferStateUpdate
Update SatelliteMessageTransferState
Remove features from SatelliteCapabilities

Test: atest SatelliteManagerTest
Bug: 268791334
Change-Id: I65465c83364bd09d5b2a30f9afd6afe283294ca9
diff --git a/telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl b/telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl
index 0ce9c98..cc4c543 100644
--- a/telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl
+++ b/telephony/java/android/telephony/satellite/ISatelliteStateListener.aidl
@@ -26,7 +26,8 @@
 oneway interface ISatelliteStateListener {
     void onSatelliteProvisionStateChanged(in boolean provisioned);
     void onSatellitePositionUpdate(in PointingInfo pointingInfo);
-    void onMessageTransferStateUpdate(in int state);
+    void onMessageTransferStateUpdate(in int state, in int sendPendingCount,
+            in int receivePendingCount, in int errorCode);
     void onSatelliteModemStateChange(in int state);
     void onPendingMessageCount(in int count);
     void onSatelliteDatagrams(in SatelliteDatagram[] datagrams);
diff --git a/telephony/java/android/telephony/satellite/SatelliteCallback.java b/telephony/java/android/telephony/satellite/SatelliteCallback.java
index 5250562..7f24a2f 100644
--- a/telephony/java/android/telephony/satellite/SatelliteCallback.java
+++ b/telephony/java/android/telephony/satellite/SatelliteCallback.java
@@ -20,7 +20,6 @@
 import android.os.Binder;
 
 import java.lang.ref.WeakReference;
-import java.util.List;
 import java.util.concurrent.Executor;
 
 /**
@@ -70,7 +69,7 @@
     }
 
     /**
-     * Interface for position update change listener.
+     * Interface for position update and message transfer state change listener.
      */
     public interface SatellitePositionUpdateListener {
         /**
@@ -84,9 +83,13 @@
          * Called when satellite message transfer state changes.
          *
          * @param state The new message transfer state.
+         * @param sendPendingCount The number of messages that are currently being sent.
+         * @param receivePendingCount The number of messages that are currently being received.
+         * @param errorCode If message transfer failed, the reason for failure.
          */
         void onMessageTransferStateUpdate(
-                @SatelliteManager.SatelliteMessageTransferState int state);
+                @SatelliteManager.SatelliteMessageTransferState int state, int sendPendingCount,
+                int receivePendingCount, @SatelliteManager.SatelliteError int errorCode);
     }
 
     /**
@@ -95,13 +98,13 @@
     public interface SatelliteStateListener {
         /**
          * Called when satellite state changes.
-         * @param state - The new satellite state.
+         * @param state The new satellite state.
          */
         void onSatelliteModemStateChange(@SatelliteManager.SatelliteModemState int state);
 
         /**
          * Called when there are pending messages to be received from satellite.
-         * @param count - pending message count.
+         * @param count Pending message count.
          */
         void onPendingMessageCount(int count);
     }
@@ -112,7 +115,7 @@
     public interface SatelliteDatagramListener {
         /**
          * Called when there are incoming datagrams to be received.
-         * @param datagrams - datagrams to be received over satellite.
+         * @param datagrams Datagrams to be received over satellite.
          */
         void onSatelliteDatagrams(SatelliteDatagram[] datagrams);
     }
@@ -145,13 +148,15 @@
         }
 
         public void onMessageTransferStateUpdate(
-                @SatelliteManager.SatelliteMessageTransferState int state) {
+                @SatelliteManager.SatelliteMessageTransferState int state, int sendPendingCount,
+                int receivePendingCount, @SatelliteManager.SatelliteError int errorCode) {
             SatellitePositionUpdateListener listener =
                     (SatellitePositionUpdateListener) mSatelliteCallbackWeakRef.get();
             if (listener == null) return;
 
             Binder.withCleanCallingIdentity(() -> mExecutor.execute(
-                    () -> listener.onMessageTransferStateUpdate(state)));
+                    () -> listener.onMessageTransferStateUpdate(
+                            state, sendPendingCount, receivePendingCount, errorCode)));
         }
 
 
diff --git a/telephony/java/android/telephony/satellite/SatelliteCapabilities.java b/telephony/java/android/telephony/satellite/SatelliteCapabilities.java
index c5ae4db..74f6f57 100644
--- a/telephony/java/android/telephony/satellite/SatelliteCapabilities.java
+++ b/telephony/java/android/telephony/satellite/SatelliteCapabilities.java
@@ -33,8 +33,8 @@
     private Set<Integer> mSupportedRadioTechnologies;
 
     /**
-     * Whether satellite mode is always on (this to indicate power impact of keeping it on is
-     * very minimal).
+     * Whether satellite modem is always on.
+     * This indicates the power impact of keeping it on is very minimal.
      */
     private boolean mIsAlwaysOn;
 
@@ -44,12 +44,7 @@
     private boolean mNeedsPointingToSatellite;
 
     /**
-     * List of features supported by the Satellite modem.
-     */
-    private Set<Integer> mSupportedFeatures;
-
-    /**
-     * Whether UE needs a separate SIM profile to communicate with the Satellite network.
+     * Whether UE needs a separate SIM profile to communicate with the satellite network.
      */
     private boolean mNeedsSeparateSimProfile;
 
@@ -57,12 +52,10 @@
      * @hide
      */
     public SatelliteCapabilities(Set<Integer> supportedRadioTechnologies, boolean isAlwaysOn,
-            boolean needsPointingToSatellite, Set<Integer> supportedFeatures,
-            boolean needsSeparateSimProfile) {
+            boolean needsPointingToSatellite, boolean needsSeparateSimProfile) {
         mSupportedRadioTechnologies = supportedRadioTechnologies;
         mIsAlwaysOn = isAlwaysOn;
         mNeedsPointingToSatellite = needsPointingToSatellite;
-        mSupportedFeatures = supportedFeatures;
         mNeedsSeparateSimProfile = needsSeparateSimProfile;
     }
 
@@ -88,35 +81,23 @@
 
         out.writeBoolean(mIsAlwaysOn);
         out.writeBoolean(mNeedsPointingToSatellite);
-
-        if (mSupportedFeatures != null && !mSupportedFeatures.isEmpty()) {
-            out.writeInt(mSupportedFeatures.size());
-            for (int feature : mSupportedFeatures) {
-                out.writeInt(feature);
-            }
-        } else {
-            out.writeInt(0);
-        }
-
         out.writeBoolean(mNeedsSeparateSimProfile);
     }
 
-    public static final @android.annotation.NonNull Creator<SatelliteCapabilities> CREATOR =
-            new Creator<SatelliteCapabilities>() {
-                @Override
-                public SatelliteCapabilities createFromParcel(Parcel in) {
-                    return new SatelliteCapabilities(in);
-                }
+    @NonNull public static final Creator<SatelliteCapabilities> CREATOR = new Creator<>() {
+        @Override
+        public SatelliteCapabilities createFromParcel(Parcel in) {
+            return new SatelliteCapabilities(in);
+        }
 
-                @Override
-                public SatelliteCapabilities[] newArray(int size) {
-                    return new SatelliteCapabilities[size];
-                }
-            };
+        @Override
+        public SatelliteCapabilities[] newArray(int size) {
+            return new SatelliteCapabilities[size];
+        }
+    };
 
-    @NonNull
     @Override
-    public String toString() {
+    @NonNull public String toString() {
         StringBuilder sb = new StringBuilder();
 
         sb.append("SupportedRadioTechnology:");
@@ -129,16 +110,6 @@
             sb.append("none,");
         }
 
-        sb.append("SupportedFeatures:");
-        if (mSupportedFeatures != null && !mSupportedFeatures.isEmpty()) {
-            for (int feature : mSupportedFeatures) {
-                sb.append(feature);
-                sb.append(",");
-            }
-        } else {
-            sb.append("none,");
-        }
-
         sb.append("isAlwaysOn:");
         sb.append(mIsAlwaysOn);
         sb.append(",");
@@ -152,26 +123,39 @@
         return sb.toString();
     }
 
-    @NonNull
-    public Set<Integer> getSupportedRadioTechnologies() {
+    /**
+     * @return The list of technologies supported by the satellite modem.
+     */
+    @NonNull public Set<Integer> getSupportedRadioTechnologies() {
         return mSupportedRadioTechnologies;
     }
 
+    /**
+     * Get whether the satellite modem is always on.
+     * This indicates the power impact of keeping it on is very minimal.
+     *
+     * @return {@code true} if the satellite modem is always on and {@code false} otherwise.
+     */
     public boolean isAlwaysOn() {
         return mIsAlwaysOn;
     }
 
-    /** Get function for mNeedsPointingToSatellite */
+    /**
+     * Get whether UE needs to point to a satellite to send and receive data.
+     *
+     * @return {@code true} if UE needs to pointing to a satellite to send and receive data and
+     *         {@code false} otherwise.
+     */
     public boolean needsPointingToSatellite() {
         return mNeedsPointingToSatellite;
     }
 
-    @NonNull
-    public Set<Integer> getSupportedFeatures() {
-        return mSupportedFeatures;
-    }
-
-    /** Get function for mNeedsSeparateSimProfile */
+    /**
+     * Get whether UE needs a separate SIM profile to communicate with the satellite network.
+     *
+     * @return {@code true} if UE needs a separate SIM profile to comunicate with the satellite
+     *         network and {@code false} otherwise.
+     */
     public boolean needsSeparateSimProfile() {
         return mNeedsSeparateSimProfile;
     }
@@ -187,15 +171,6 @@
 
         mIsAlwaysOn = in.readBoolean();
         mNeedsPointingToSatellite = in.readBoolean();
-
-        mSupportedFeatures = new HashSet<>();
-        int numSupportedFeatures = in.readInt();
-        if (numSupportedFeatures > 0) {
-            for (int i = 0; i < numSupportedFeatures; i++) {
-                mSupportedFeatures.add(in.readInt());
-            }
-        }
-
         mNeedsSeparateSimProfile = in.readBoolean();
     }
 }
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index 100799e..9ce4310 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -144,6 +144,21 @@
     public static final String KEY_SATELLITE_PROVISIONED = "satellite_provisioned";
 
     /**
+     * Bundle key to get the response from
+     * {@link #requestIsSatelliteCommunicationAllowedForCurrentLocation(Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_SATELLITE_COMMUNICATION_ALLOWED =
+            "satellite_communication_allowed";
+
+    /**
+     * Bundle key to get the response from
+     * {@link #requestTimeForNextSatelliteVisibility(Executor, OutcomeReceiver)}.
+     * @hide
+     */
+    public static final String KEY_SATELLITE_NEXT_VISIBILITY = "satellite_next_visibility";
+
+    /**
      * The request was successfully processed.
      */
     public static final int SATELLITE_ERROR_NONE = 0;
@@ -294,7 +309,7 @@
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            Rlog.e(TAG, "setSatelliteEnabled RemoteException: ", ex);
+            Rlog.e(TAG, "setSatelliteEnabled() RemoteException: ", ex);
             ex.rethrowFromSystemServer();
         }
     }
@@ -460,33 +475,45 @@
     }
 
     /**
-     * Message transfer is waiting to acquire.
+     * The default state indicating that message transfer is idle.
+     * This should be sent immediately after either
+     * {@link #SATELLITE_MESSAGE_TRANSFER_STATE_SUCCESS} or
+     * {@link #SATELLITE_MESSAGE_TRANSFER_STATE_FAILED}.
      */
-    public static final int SATELLITE_MESSAGE_TRANSFER_STATE_WAITING_TO_ACQUIRE = 0;
+    public static final int SATELLITE_MESSAGE_TRANSFER_STATE_IDLE = 0;
     /**
-     * Message is being sent.
+     * A transition state indicating that a message is being sent.
      */
     public static final int SATELLITE_MESSAGE_TRANSFER_STATE_SENDING = 1;
     /**
-     * Message is being received.
+     * A transition state indicating that a message is being received.
      */
     public static final int SATELLITE_MESSAGE_TRANSFER_STATE_RECEIVING = 2;
     /**
-     * Message transfer is being retried.
+     * A transition state indicating that message transfer is being retried.
      */
     public static final int SATELLITE_MESSAGE_TRANSFER_STATE_RETRYING = 3;
     /**
-     * Message transfer is complete.
+     * An end state indicating that message transfer completed successfully.
+     * After message transfer completes, {@link #SATELLITE_MESSAGE_TRANSFER_STATE_IDLE}
+     * must be sent before reporting any additional message transfer state changes.
      */
-    public static final int SATELLITE_MESSAGE_TRANSFER_STATE_COMPLETE = 4;
+    public static final int SATELLITE_MESSAGE_TRANSFER_STATE_SUCCESS = 4;
+    /**
+     * An end state indicating that message transfer completed with a failure.
+     * After message transfer completes, {@link #SATELLITE_MESSAGE_TRANSFER_STATE_IDLE}
+     * must be sent before reporting any additional message transfer state changes.
+     */
+    public static final int SATELLITE_MESSAGE_TRANSFER_STATE_FAILED = 5;
 
     /** @hide */
     @IntDef(prefix = {"SATELLITE_MESSAGE_TRANSFER_STATE_"}, value = {
-            SATELLITE_MESSAGE_TRANSFER_STATE_WAITING_TO_ACQUIRE,
+            SATELLITE_MESSAGE_TRANSFER_STATE_IDLE,
             SATELLITE_MESSAGE_TRANSFER_STATE_SENDING,
             SATELLITE_MESSAGE_TRANSFER_STATE_RECEIVING,
             SATELLITE_MESSAGE_TRANSFER_STATE_RETRYING,
-            SATELLITE_MESSAGE_TRANSFER_STATE_COMPLETE
+            SATELLITE_MESSAGE_TRANSFER_STATE_SUCCESS,
+            SATELLITE_MESSAGE_TRANSFER_STATE_FAILED
     })
     public @interface SatelliteMessageTransferState {}
 
@@ -534,6 +561,11 @@
      * Modem should continue to report the pointing input as the device or satellite moves.
      * Satellite position updates are started only on {@link #SATELLITE_ERROR_NONE}.
      * All other results indicate that this operation failed.
+     * Once satellite position updates begin, message transfer state updates will be sent
+     * through {@link SatelliteCallback.SatellitePositionUpdateListener}.
+     * Modem should report any changes in message transfer state and indicate success or failure
+     * by reporting {@link #SATELLITE_MESSAGE_TRANSFER_STATE_SUCCESS} or
+     * {@link #SATELLITE_MESSAGE_TRANSFER_STATE_FAILED}.
      *
      * @param executor The executor on which the callback and error code listener will be called.
      * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
@@ -568,7 +600,7 @@
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("startSatellitePositionUpdates RemoteException: " + ex);
+            loge("startSatellitePositionUpdates() RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
     }
@@ -576,8 +608,8 @@
     /**
      * Stop receiving satellite position updates.
      * This can be called by the pointing UI when the user stops pointing to the satellite.
-     * Satellite position updates are stopped only on {@link #SATELLITE_ERROR_NONE}.
-     * All other results indicate that this operation failed.
+     * Satellite position updates are stopped and the callback is unregistered only on
+     * {@link #SATELLITE_ERROR_NONE}. All other results that this operation failed.
      *
      * @param callback The callback that was passed to
      *       {@link #startSatellitePositionUpdates(Executor, Consumer, SatelliteCallback)}.
@@ -585,7 +617,6 @@
      * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
-     * @throws IllegalArgumentException if the callback is invalid.
      * @throws IllegalStateException if the Telephony process is not currently available.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
@@ -613,7 +644,7 @@
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("stopSatellitePositionUpdates RemoteException: " + ex);
+            loge("stopSatellitePositionUpdates() RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
     }
@@ -671,7 +702,6 @@
         }
     }
 
-
     /**
      * Provision the device with a satellite provider.
      * This is needed if the provider allows dynamic registration.
@@ -712,7 +742,7 @@
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("provisionSatelliteService RemoteException=" + ex);
+            loge("provisionSatelliteService() RemoteException=" + ex);
             ex.rethrowFromSystemServer();
         }
         if (cancellationSignal != null) {
@@ -757,7 +787,7 @@
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("deprovisionSatelliteService RemoteException=" + ex);
+            loge("deprovisionSatelliteService() RemoteException=" + ex);
             ex.rethrowFromSystemServer();
         }
     }
@@ -765,90 +795,72 @@
     /**
      * Register for the satellite provision state change.
      *
-     * @param executor The executor on which the callback and error code listener will be called.
-     * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
-     * @param callback The callback to handle the satellite provision state changed event. This
-     *                 SatelliteCallback should implement the interface
+     * @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 {@link SatelliteError} result of the operation.
+     *
      * @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 registerForSatelliteProvisionStateChanged(
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<Integer> errorCodeListener, @NonNull SatelliteCallback callback) {
+    @SatelliteError public int registerForSatelliteProvisionStateChanged(
+            @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(executor);
-        Objects.requireNonNull(errorCodeListener);
         Objects.requireNonNull(callback);
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
                 callback.init(executor);
-                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
-                    @Override
-                    public void accept(int result) {
-                        executor.execute(() -> Binder.withCleanCallingIdentity(
-                                () -> errorCodeListener.accept(result)));
-                    }
-                };
-                telephony.registerForSatelliteProvisionStateChanged(
-                        mSubId, errorCallback, callback.getCallbackStub());
+                return telephony.registerForSatelliteProvisionStateChanged(
+                        mSubId, callback.getCallbackStub());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("registerForSatelliteProvisionStateChanged RemoteException: " + ex);
+            loge("registerForSatelliteProvisionStateChanged() RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
+        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
      * Unregister for the satellite provision state change.
      *
-     * @param callback The callback that was passed to
-     * {@link #registerForSatelliteProvisionStateChanged(Executor, Consumer, SatelliteCallback)}.
-     * @param executor The executor on which the error code listener will be called.
-     * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
+     * @param callback The callback that was passed to {@link
+     *                 #registerForSatelliteProvisionStateChanged(Executor, SatelliteCallback)}.
+     *
+     * @return The {@link SatelliteError} result of the operation.
      *
      * @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 unregisterForSatelliteProvisionStateChanged(@NonNull SatelliteCallback callback,
-            @NonNull @CallbackExecutor Executor executor,
-            @NonNull Consumer<Integer> errorCodeListener) {
+    @SatelliteError public int unregisterForSatelliteProvisionStateChanged(
+            @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(callback);
-        Objects.requireNonNull(executor);
-        Objects.requireNonNull(errorCodeListener);
 
         if (callback.getCallbackStub() == null) {
             loge("unregisterForSatelliteProvisionStateChanged: callbackStub is null");
-            executor.execute(() -> Binder.withCleanCallingIdentity(
-                    () -> errorCodeListener.accept(SATELLITE_INVALID_ARGUMENTS)));
-            return;
+            return SATELLITE_INVALID_ARGUMENTS;
         }
 
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                IIntegerConsumer errorCallback = new IIntegerConsumer.Stub() {
-                    @Override
-                    public void accept(int result) {
-                        executor.execute(() -> Binder.withCleanCallingIdentity(
-                                () -> errorCodeListener.accept(result)));
-                    }
-                };
-                telephony.unregisterForSatelliteProvisionStateChanged(mSubId, errorCallback,
+                return telephony.unregisterForSatelliteProvisionStateChanged(mSubId,
                         callback.getCallbackStub());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
         } catch (RemoteException ex) {
-            loge("unregisterForSatelliteProvisionStateChanged RemoteException: " + ex);
+            loge("unregisterForSatelliteProvisionStateChanged() RemoteException: " + ex);
             ex.rethrowFromSystemServer();
         }
+        return SATELLITE_REQUEST_FAILED;
     }
 
     /**
@@ -908,19 +920,19 @@
     /**
      * Register for listening to satellite modem state changes.
      *
-     * @param executor - The executor on which the callback will be called.
-     * @param callback - The callback to handle the satellite state change event. This
-     *                 SatelliteCallback should implement the interface
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback to handle the satellite state change event.
+     *                 This SatelliteCallback should implement the interface
      *                 {@link SatelliteCallback.SatelliteStateListener}.
      *
-     * @return The error code of the request.
+     * @return The {@link SatelliteError} result of the operation.
+     *
      * @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)
-    @SatelliteError
-    public int registerForSatelliteModemStateChange(@NonNull @CallbackExecutor Executor executor,
-            @NonNull SatelliteCallback callback) {
+    @SatelliteError public int registerForSatelliteModemStateChange(
+            @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(executor);
         Objects.requireNonNull(callback);
 
@@ -943,10 +955,11 @@
     /**
      * Unregister to stop listening to satellite modem state changes.
      *
-     * @param callback - The callback that was passed to
-     * {@link #registerForSatelliteModemStateChange(Executor, SatelliteCallback)}
+     * @param callback The callback that was passed to
+     *                 {@link #registerForSatelliteModemStateChange(Executor, SatelliteCallback)}.
      *
-     * @return The error code of the request.
+     * @return The {@link SatelliteError} result of the operation.
+     *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
      */
@@ -978,19 +991,19 @@
     /**
      * Register to receive incoming datagrams over satellite.
      *
-     * @param datagramType - type of datagram
-     * @param executor - The executor on which the callback will be called.
-     * @param callback - The callback to handle incoming datagrams over satellite. This
-     *                 SatelliteCallback should implement the interface
+     * @param datagramType Type of datagram.
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback to handle incoming datagrams over satellite.
+     *                 This SatelliteCallback should implement the interface
      *                 {@link SatelliteCallback.SatelliteDatagramListener}.
      *
-     * @return The error code of the request.
+     * @return The {@link SatelliteError} result of the operation.
+     *
      * @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)
-    @SatelliteError
-    public int registerForSatelliteDatagram(@DatagramType int datagramType,
+    @SatelliteError public int registerForSatelliteDatagram(@DatagramType int datagramType,
             @NonNull @CallbackExecutor Executor executor, @NonNull SatelliteCallback callback) {
         Objects.requireNonNull(executor);
         Objects.requireNonNull(callback);
@@ -1014,16 +1027,16 @@
     /**
      * Unregister to stop receiving incoming datagrams over satellite.
      *
-     * @param callback - The callback that was passed to
-     * {@link #registerForSatelliteDatagram(int, Executor, SatelliteCallback)}
+     * @param callback The callback that was passed to
+     *                 {@link #registerForSatelliteDatagram(int, Executor, SatelliteCallback)}.
      *
-     * @return The error code of the request.
+     * @return The {@link SatelliteError} result of the operation.
+     *
      * @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)
-    @SatelliteError
-    public int unregisterForSatelliteDatagram(@NonNull SatelliteCallback callback) {
+    @SatelliteError public int unregisterForSatelliteDatagram(@NonNull SatelliteCallback callback) {
         Objects.requireNonNull(callback);
 
         if (callback.getCallbackStub() == null) {
@@ -1034,8 +1047,7 @@
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
-                return telephony.unregisterForSatelliteDatagram(mSubId,
-                        callback.getCallbackStub());
+                return telephony.unregisterForSatelliteDatagram(mSubId, callback.getCallbackStub());
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -1054,8 +1066,7 @@
      * @throws IllegalStateException if the Telephony process is not currently available.
      */
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
-    @SatelliteError
-    public int pollPendingSatelliteDatagrams() {
+    @SatelliteError public int pollPendingSatelliteDatagrams() {
         try {
             ITelephony telephony = getITelephony();
             if (telephony != null) {
@@ -1072,10 +1083,11 @@
 
     /**
      * Send datagram over satellite.
-     * @param datagramType - type of datagram
-     * @param datagram - datagram to send over satellite
-     * @param executor - The executor on which the result listener will be called.
-     * @param resultListener - Listener that will be called with the result of the operation.
+     *
+     * @param datagramType Type of datagram.
+     * @param datagram Datagram to send over satellite.
+     * @param executor The executor on which the error code listener will be called.
+     * @param errorCodeListener Listener for the {@link SatelliteError} result of the operation.
      *
      * @throws SecurityException if the caller doesn't have required permission.
      * @throws IllegalStateException if the Telephony process is not currently available.
@@ -1083,10 +1095,10 @@
     @RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
     public void sendSatelliteDatagram(@DatagramType int datagramType,
             @NonNull SatelliteDatagram datagram, @NonNull @CallbackExecutor Executor executor,
-            @SatelliteError @NonNull Consumer<Integer> resultListener) {
+            @SatelliteError @NonNull Consumer<Integer> errorCodeListener) {
         Objects.requireNonNull(datagram);
         Objects.requireNonNull(executor);
-        Objects.requireNonNull(resultListener);
+        Objects.requireNonNull(errorCodeListener);
 
         try {
             ITelephony telephony = getITelephony();
@@ -1095,11 +1107,10 @@
                     @Override
                     public void accept(int result) {
                         executor.execute(() -> Binder.withCleanCallingIdentity(
-                                () -> resultListener.accept(result)));
+                                () -> errorCodeListener.accept(result)));
                     }
                 };
-                telephony.sendSatelliteDatagram(mSubId, datagramType, datagram,
-                        internalCallback);
+                telephony.sendSatelliteDatagram(mSubId, datagramType, datagram, internalCallback);
             } else {
                 throw new IllegalStateException("telephony service is null.");
             }
@@ -1109,6 +1120,119 @@
         }
     }
 
+    /**
+     * Request to get whether satellite communication is allowed for the current location.
+     *
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback object to which the result will be delivered.
+     *                 If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+     *                 will return a {@code boolean} with value {@code true} if satellite
+     *                 communication is allowed for the current location and
+     *                 {@code false} otherwise.
+     *                 If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+     *                 will return a {@link SatelliteException} with the {@link SatelliteError}.
+     *
+     * @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 requestIsSatelliteCommunicationAllowedForCurrentLocation(
+            @NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                ResultReceiver receiver = new ResultReceiver(null) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_ERROR_NONE) {
+                            if (resultData.containsKey(KEY_SATELLITE_COMMUNICATION_ALLOWED)) {
+                                boolean isSatelliteCommunicationAllowed =
+                                        resultData.getBoolean(KEY_SATELLITE_COMMUNICATION_ALLOWED);
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(isSatelliteCommunicationAllowed)));
+                            } else {
+                                loge("KEY_SATELLITE_COMMUNICATION_ALLOWED does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(
+                                                new SatelliteException(SATELLITE_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
+                    }
+                };
+                telephony.requestIsSatelliteCommunicationAllowedForCurrentLocation(mSubId,
+                        receiver);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("requestIsSatelliteCommunicationAllowedForCurrentLocation() RemoteException: "
+                    + ex);
+            ex.rethrowFromSystemServer();
+        }
+    }
+
+    /**
+     * Request to get the time after which the satellite will next be visible. This is an
+     * {@code int} representing the duration in seconds after which the satellite will be visible.
+     * This will return {@code 0} if the satellite is currently visible.
+     *
+     * @param executor The executor on which the callback will be called.
+     * @param callback The callback object to which the result will be delivered.
+     *                 If the request is successful, {@link OutcomeReceiver#onResult(Object)}
+     *                 will return the time after which the satellite will next be visible.
+     *                 If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+     *                 will return a {@link SatelliteException} with the {@link SatelliteError}.
+     *
+     * @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 requestTimeForNextSatelliteVisibility(@NonNull @CallbackExecutor Executor executor,
+            @NonNull OutcomeReceiver<Integer, SatelliteException> callback) {
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(callback);
+
+        try {
+            ITelephony telephony = getITelephony();
+            if (telephony != null) {
+                ResultReceiver receiver = new ResultReceiver(null) {
+                    @Override
+                    protected void onReceiveResult(int resultCode, Bundle resultData) {
+                        if (resultCode == SATELLITE_ERROR_NONE) {
+                            if (resultData.containsKey(KEY_SATELLITE_NEXT_VISIBILITY)) {
+                                int nextVisibilityDuration =
+                                        resultData.getInt(KEY_SATELLITE_NEXT_VISIBILITY);
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onResult(nextVisibilityDuration)));
+                            } else {
+                                loge("KEY_SATELLITE_NEXT_VISIBILITY does not exist.");
+                                executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                        callback.onError(
+                                                new SatelliteException(SATELLITE_REQUEST_FAILED))));
+                            }
+                        } else {
+                            executor.execute(() -> Binder.withCleanCallingIdentity(() ->
+                                    callback.onError(new SatelliteException(resultCode))));
+                        }
+                    }
+                };
+                telephony.requestTimeForNextSatelliteVisibility(mSubId, receiver);
+            } else {
+                throw new IllegalStateException("telephony service is null.");
+            }
+        } catch (RemoteException ex) {
+            loge("requestTimeForNextSatelliteVisibility() RemoteException: " + ex);
+            ex.rethrowFromSystemServer();
+        }
+    }
+
     private static ITelephony getITelephony() {
         ITelephony binder = ITelephony.Stub.asInterface(TelephonyFrameworkInitializer
                 .getTelephonyServiceManager()
diff --git a/telephony/java/com/android/internal/telephony/ITelephony.aidl b/telephony/java/com/android/internal/telephony/ITelephony.aidl
index 9090edb..ec8dafb 100644
--- a/telephony/java/com/android/internal/telephony/ITelephony.aidl
+++ b/telephony/java/com/android/internal/telephony/ITelephony.aidl
@@ -2771,7 +2771,7 @@
     /**
      * Request to get the maximum number of characters per text message on satellite.
      *
-     * @param subId The subId to get the maximum number of characters for.
+     * @param subId The subId of the subscription to get the maximum number of characters for.
      * @param receiver Result receiver to get the error code of the request and the requested
      *                 maximum number of characters per text message on satellite.
      */
@@ -2814,26 +2814,26 @@
     /**
      * Register for the satellite provision state change.
      *
-     * @param subId The subId of the subscription to register for provision state changes for.
-     * @param errorCallback The callback to get the error code of the request.
+     * @param subId The subId of the subscription to register for provision state changes.
      * @param callback The callback to handle the satellite provision state changed event.
+     *
+     * @return The {@link SatelliteError} result of the operation.
      */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
             + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
-    void registerForSatelliteProvisionStateChanged(int subId,
-            in IIntegerConsumer errorCallback, in ISatelliteStateListener callback);
+    int registerForSatelliteProvisionStateChanged(int subId, in ISatelliteStateListener callback);
 
     /**
      * Unregister for the satellite provision state change.
      *
-     * @param subId The subId of the subscription associated with the satellite service.
-     * @param errorCallback The callback to get the error code of the request.
+     * @param subId The subId of the subscription to unregister for provision state changes.
      * @param callback The callback that was passed to registerForSatelliteProvisionStateChanged.
+     *
+     * @return The {@link SatelliteError} result of the operation.
      */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
             + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
-    void unregisterForSatelliteProvisionStateChanged(int subId,
-            in IIntegerConsumer errorCallback, in ISatelliteStateListener callback);
+    int unregisterForSatelliteProvisionStateChanged(int subId, in ISatelliteStateListener callback);
 
     /**
      * Request to get whether the device is provisioned with a satellite provider.
@@ -2849,8 +2849,10 @@
     /**
      * Register for listening to satellite modem state changes.
      *
-     * @param subId - The subId of the subscription used for listening to satellite state changes.
-     * @param callback - The callback to handle the satellite state changed event.
+     * @param subId The subId of the subscription to register for satellite modem state changes.
+     * @param callback The callback to handle the satellite modem state changed event.
+     *
+     * @return The {@link SatelliteError} result of the operation.
      */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
             + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
@@ -2859,8 +2861,10 @@
     /**
      * Unregister to stop listening to satellite modem state changes.
      *
-     * @param subId - The subId of the subscription associated with the satellite service.
-     * @param callback - The callback that was passed to registerForSatelliteStateChange.
+     * @param subId The subId of the subscription to unregister for satellite modem state changes.
+     * @param callback The callback that was passed to registerForSatelliteStateChange.
+     *
+     * @return The {@link SatelliteError} result of the operation.
      */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
             + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
@@ -2869,43 +2873,73 @@
    /**
      * Register to receive incoming datagrams over satellite.
      *
-     * @param subId - The subId of the subscription used for receiving datagrams.
-     * @param datagramType - type of datagram
-     * @param callback - The callback to receive incoming datagrams.
+     * @param subId The subId of the subscription to register for incoming satellite datagrams.
+     * @param datagramType Type of datagram.
+     * @param callback The callback to handle receiving incoming datagrams.
+     *
+     * @return The {@link SatelliteError} result of the operation.
      */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
-                + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
     int registerForSatelliteDatagram(int subId, int datagramType, ISatelliteStateListener callback);
 
    /**
      * Unregister to stop receiving incoming datagrams over satellite.
      *
-     * @param subId - The subId of the subscription associated with the satellite service.
-     * @param callback - The callback that was passed to registerForSatelliteDatagram.
+     * @param subId The subId of the subscription to unregister for incoming satellite datagrams.
+     * @param callback The callback that was passed to registerForSatelliteDatagram.
+     *
+     * @return The {@link SatelliteError} result of the operation.
      */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
-                + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
     int unregisterForSatelliteDatagram(int subId, ISatelliteStateListener callback);
 
    /**
     * Poll pending satellite datagrams over satellite.
     *
-    * @param subId - The subId of the subscription used for receiving datagrams.
+    * @param subId The subId of the subscription to poll pending satellite datagrams for.
+    *
+    * @return The {@link SatelliteError} result of the operation.
     */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
-                + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
     int pollPendingSatelliteDatagrams(int subId);
 
    /**
     * Send datagram over satellite.
     *
-    * @param subId - The subId of the subscription used for receiving datagrams.
-    * @param datagramType - type of datagram
-    * @param datagram - datagram to send over satellite
-    * @param callback - The callback to get the error code of the request.
+    * @param subId The subId of the subscription to send satellite datagrams for.
+    * @param datagramType Type of datagram.
+    * @param datagram Datagram to send over satellite.
+    * @param callback The callback to get the error code of the request.
     */
     @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
-                    + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
     void sendSatelliteDatagram(int subId, int datagramType, in SatelliteDatagram datagram,
             IIntegerConsumer callback);
+
+    /**
+     * Request to get whether satellite communication is allowed for the current location.
+     *
+     * @param subId The subId of the subscription to get whether satellite communication is allowed
+     *              for the current location for.
+     * @param receiver Result receiver to get the error code of the request and whether satellite
+     *                 communication is allowed for the current location.
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void requestIsSatelliteCommunicationAllowedForCurrentLocation(int subId,
+            in ResultReceiver receiver);
+
+    /**
+     * Request to get the time after which the satellite will next be visible.
+     *
+     * @param subId The subId to get the time after which the satellite will next be visible for.
+     * @param receiver Result receiver to get the error code of the request and the requested
+     *                 time after which the satellite will next be visible.
+     */
+    @JavaPassthrough(annotation="@android.annotation.RequiresPermission("
+            + "android.Manifest.permission.SATELLITE_COMMUNICATION)")
+    void requestTimeForNextSatelliteVisibility(int subId, in ResultReceiver receiver);
 }