Merge Android 24Q2 Release (ab/11526283) to aosp-main-future

Bug: 337098550
Merged-In: If747db67f30bd8fc419b1042a3df90c633e36db4
Change-Id: Iba24ee2291cc4f6c6796e86383235e6ed45bb6c2
diff --git a/satellite_client/Android.bp b/satellite_client/Android.bp
index 1661dcf..89c5c4b 100644
--- a/satellite_client/Android.bp
+++ b/satellite_client/Android.bp
@@ -17,6 +17,10 @@
         "app-compat-annotations",
         "unsupportedappusage",
     ],
+    required: [
+        "android.telephony.satellite.xml",
+    ],
+    provides_uses_lib: "android.telephony.satellite",
     optimize: {
         ignore_warnings: false,
         proguard_flags_files: ["proguard.flags"],
@@ -28,5 +32,4 @@
     sub_dir: "sysconfig",
     system_ext_specific: true,
     src: "android.telephony.satellite.xml",
-}
-
+}
\ No newline at end of file
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
index ff36bf5..d230e8f 100644
--- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
+++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
@@ -16,6 +16,8 @@
 
 package android.telephony.satellite.wrapper;
 
+import static android.telephony.AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
+import static android.telephony.NetworkRegistrationInfo.DOMAIN_PS;
 import static android.telephony.satellite.SatelliteManager.SatelliteException;
 
 import android.annotation.CallbackExecutor;
@@ -26,9 +28,13 @@
 import android.content.Context;
 import android.os.CancellationSignal;
 import android.os.OutcomeReceiver;
+import android.telephony.NetworkRegistrationInfo;
+import android.telephony.ServiceState;
 import android.telephony.SubscriptionInfo;
 import android.telephony.SubscriptionManager;
+import android.telephony.TelephonyManager;
 import android.telephony.satellite.AntennaPosition;
+import android.telephony.satellite.EnableRequestAttributes;
 import android.telephony.satellite.NtnSignalStrength;
 import android.telephony.satellite.NtnSignalStrengthCallback;
 import android.telephony.satellite.PointingInfo;
@@ -37,8 +43,8 @@
 import android.telephony.satellite.SatelliteDatagram;
 import android.telephony.satellite.SatelliteDatagramCallback;
 import android.telephony.satellite.SatelliteManager;
+import android.telephony.satellite.SatelliteModemStateCallback;
 import android.telephony.satellite.SatelliteProvisionStateCallback;
-import android.telephony.satellite.SatelliteStateCallback;
 import android.telephony.satellite.SatelliteTransmissionUpdateCallback;
 
 import com.android.internal.telephony.flags.Flags;
@@ -47,12 +53,15 @@
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
 import java.time.Duration;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.Executor;
 import java.util.function.Consumer;
+import java.util.stream.Collectors;
 
 /**
  * Wrapper for satellite operations such as provisioning, pointing, messaging, location sharing,
@@ -69,8 +78,9 @@
           SatelliteProvisionStateCallbackWrapper, SatelliteProvisionStateCallback>
       sSatelliteProvisionStateCallbackWrapperMap = new ConcurrentHashMap<>();
 
-  private static final ConcurrentHashMap<SatelliteStateCallbackWrapper, SatelliteStateCallback>
-      sSatelliteStateCallbackWrapperMap = new ConcurrentHashMap<>();
+  private static final ConcurrentHashMap<SatelliteModemStateCallbackWrapper,
+          SatelliteModemStateCallback> sSatelliteModemStateCallbackWrapperMap =
+          new ConcurrentHashMap<>();
 
   private static final ConcurrentHashMap<
           SatelliteTransmissionUpdateCallbackWrapper, SatelliteTransmissionUpdateCallback>
@@ -86,10 +96,12 @@
 
   private final SatelliteManager mSatelliteManager;
   private final SubscriptionManager mSubscriptionManager;
+  private final TelephonyManager mTelephonyManager;
 
   SatelliteManagerWrapper(Context context) {
     mSatelliteManager = context.getSystemService(SatelliteManager.class);
     mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+    mTelephonyManager = context.getSystemService(TelephonyManager.class);
   }
 
   /**
@@ -312,6 +324,8 @@
   public static final int SATELLITE_RESULT_REQUEST_IN_PROGRESS = 21;
   /** Satellite modem is currently busy due to which current request cannot be processed. */
   public static final int SATELLITE_RESULT_MODEM_BUSY = 22;
+  /** Telephony process is not currently available or satellite is not supported. */
+  public static final int SATELLITE_RESULT_ILLEGAL_STATE = 23;
 
   /** @hide */
   @IntDef(
@@ -339,7 +353,8 @@
         SATELLITE_RESULT_NOT_AUTHORIZED,
         SATELLITE_RESULT_NOT_SUPPORTED,
         SATELLITE_RESULT_REQUEST_IN_PROGRESS,
-        SATELLITE_RESULT_MODEM_BUSY
+        SATELLITE_RESULT_MODEM_BUSY,
+        SATELLITE_RESULT_ILLEGAL_STATE
       })
   @Retention(RetentionPolicy.SOURCE)
   public @interface SatelliteResult {}
@@ -365,6 +380,34 @@
   @Retention(RetentionPolicy.SOURCE)
   public @interface DeviceHoldPosition {}
 
+  /**
+   * Satellite communication restricted by user.
+   * @hide
+   */
+  public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER = 0;
+
+  /**
+   * Satellite communication restricted by geolocation. This can be
+   * triggered based upon geofence input provided by carrier to enable or disable satellite.
+   */
+  public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION = 1;
+
+  /**
+   * Satellite communication restricted by entitlement server. This can be triggered based on
+   * the EntitlementStatus value received from the entitlement server to enable or disable
+   * satellite.
+   */
+  public static final int SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT = 2;
+
+  /** @hide */
+  @IntDef(prefix = "SATELLITE_COMMUNICATION_RESTRICTION_REASON_", value = {
+          SATELLITE_COMMUNICATION_RESTRICTION_REASON_USER,
+          SATELLITE_COMMUNICATION_RESTRICTION_REASON_GEOLOCATION,
+          SATELLITE_COMMUNICATION_RESTRICTION_REASON_ENTITLEMENT
+  })
+  @Retention(RetentionPolicy.SOURCE)
+  public @interface SatelliteCommunicationRestrictionReason {}
+
   /** Exception from the satellite service containing the {@link SatelliteResult} error code. */
   public static class SatelliteExceptionWrapper extends Exception {
     private final int mErrorCode;
@@ -385,17 +428,20 @@
    * enabled, this may also disable the cellular modem, and if the satellite modem is disabled, this
    * may also re-enable the cellular modem.
    */
-  public void requestSatelliteEnabled(
+  public void requestEnabled(
       boolean enableSatellite,
       boolean enableDemoMode,
+      boolean isEmergency,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
-    mSatelliteManager.requestSatelliteEnabled(
-        enableSatellite, enableDemoMode, executor, resultListener);
+    mSatelliteManager.requestEnabled(new EnableRequestAttributes.Builder(enableSatellite)
+            .setDemoMode(enableDemoMode)
+            .setEmergencyMode(isEmergency)
+            .build(), executor, resultListener);
   }
 
   /** Request to get whether the satellite modem is enabled. */
-  public void requestIsSatelliteEnabled(
+  public void requestIsEnabled(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
     OutcomeReceiver internalCallback =
@@ -410,7 +456,7 @@
             callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
           }
         };
-    mSatelliteManager.requestIsSatelliteEnabled(executor, internalCallback);
+    mSatelliteManager.requestIsEnabled(executor, internalCallback);
   }
 
   /** Request to get whether the satellite service demo mode is enabled. */
@@ -432,8 +478,27 @@
     mSatelliteManager.requestIsDemoModeEnabled(executor, internalCallback);
   }
 
+  /** Request to get whether the satellite service is enabled for emergency mode */
+  public void requestIsEmergencyModeEnabled(
+          @NonNull @CallbackExecutor Executor executor,
+          @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    OutcomeReceiver internalCallback =
+        new OutcomeReceiver<Boolean, SatelliteException>() {
+          @Override
+          public void onResult(Boolean result) {
+            callback.onResult(result);
+          }
+
+          @Override
+          public void onError(SatelliteException exception) {
+            callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
+          }
+        };
+    mSatelliteManager.requestIsEmergencyModeEnabled(executor, internalCallback);
+  }
+
   /** Request to get whether the satellite service is supported on the device. */
-  public void requestIsSatelliteSupported(
+  public void requestIsSupported(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
     OutcomeReceiver internalCallback =
@@ -448,11 +513,11 @@
             callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
           }
         };
-    mSatelliteManager.requestIsSatelliteSupported(executor, internalCallback);
+    mSatelliteManager.requestIsSupported(executor, internalCallback);
   }
 
   /** Request to get the {@link SatelliteCapabilities} of the satellite service. */
-  public void requestSatelliteCapabilities(
+  public void requestCapabilities(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<SatelliteCapabilitiesWrapper, SatelliteExceptionWrapper> callback) {
     OutcomeReceiver internalCallback =
@@ -472,7 +537,7 @@
             callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
           }
         };
-    mSatelliteManager.requestSatelliteCapabilities(executor, internalCallback);
+    mSatelliteManager.requestCapabilities(executor, internalCallback);
   }
 
   /**
@@ -483,7 +548,7 @@
    * Once satellite transmission updates begin, position and datagram transfer state updates
    * will be sent through {@link SatelliteTransmissionUpdateCallback}.
    */
-  public void startSatelliteTransmissionUpdates(
+  public void startTransmissionUpdates(
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener,
       @NonNull SatelliteTransmissionUpdateCallbackWrapper callback) {
@@ -517,7 +582,7 @@
         };
     sSatelliteTransmissionUpdateCallbackWrapperMap.put(callback, internalCallback);
 
-    mSatelliteManager.startSatelliteTransmissionUpdates(executor, resultListener, internalCallback);
+    mSatelliteManager.startTransmissionUpdates(executor, resultListener, internalCallback);
   }
 
   /**
@@ -526,14 +591,14 @@
    * callback is unregistered only on {@link #SATELLITE_RESULT_SUCCESS}. All other results that this
    * operation failed.
    */
-  public void stopSatelliteTransmissionUpdates(
+  public void stopTransmissionUpdates(
       @NonNull SatelliteTransmissionUpdateCallbackWrapper callback,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
     SatelliteTransmissionUpdateCallback internalCallback =
         sSatelliteTransmissionUpdateCallbackWrapperMap.get(callback);
     if (internalCallback != null) {
-      mSatelliteManager.stopSatelliteTransmissionUpdates(
+      mSatelliteManager.stopTransmissionUpdates(
           internalCallback, executor, resultListener);
     }
   }
@@ -542,13 +607,13 @@
    * Provision the device with a satellite provider. This is needed if the provider allows dynamic
    * registration.
    */
-  public void provisionSatelliteService(
+  public void provisionService(
       @NonNull String token,
       @NonNull byte[] provisionData,
       @Nullable CancellationSignal cancellationSignal,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
-    mSatelliteManager.provisionSatelliteService(
+    mSatelliteManager.provisionService(
         token, provisionData, cancellationSignal, executor, resultListener);
   }
 
@@ -558,16 +623,16 @@
    * SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean)} should report as
    * deprovisioned.
    */
-  public void deprovisionSatelliteService(
+  public void deprovisionService(
       @NonNull String token,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
-    mSatelliteManager.deprovisionSatelliteService(token, executor, resultListener);
+    mSatelliteManager.deprovisionService(token, executor, resultListener);
   }
 
   /** Registers for the satellite provision state changed. */
   @SatelliteResult
-  public int registerForSatelliteProvisionStateChanged(
+  public int registerForProvisionStateChanged(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull SatelliteProvisionStateCallbackWrapper callback) {
     SatelliteProvisionStateCallback internalCallback =
@@ -579,7 +644,7 @@
         };
     sSatelliteProvisionStateCallbackWrapperMap.put(callback, internalCallback);
     int result =
-        mSatelliteManager.registerForSatelliteProvisionStateChanged(executor, internalCallback);
+        mSatelliteManager.registerForProvisionStateChanged(executor, internalCallback);
     return result;
   }
 
@@ -587,17 +652,17 @@
    * Unregisters for the satellite provision state changed. If callback was not registered before,
    * the request will be ignored.
    */
-  public void unregisterForSatelliteProvisionStateChanged(
+  public void unregisterForProvisionStateChanged(
       @NonNull SatelliteProvisionStateCallbackWrapper callback) {
     SatelliteProvisionStateCallback internalCallback =
         sSatelliteProvisionStateCallbackWrapperMap.get(callback);
     if (internalCallback != null) {
-      mSatelliteManager.unregisterForSatelliteProvisionStateChanged(internalCallback);
+      mSatelliteManager.unregisterForProvisionStateChanged(internalCallback);
     }
   }
 
   /** Request to get whether this device is provisioned with a satellite provider. */
-  public void requestIsSatelliteProvisioned(
+  public void requestIsProvisioned(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
     OutcomeReceiver internalCallback =
@@ -612,24 +677,24 @@
             callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
           }
         };
-    mSatelliteManager.requestIsSatelliteProvisioned(executor, internalCallback);
+    mSatelliteManager.requestIsProvisioned(executor, internalCallback);
   }
 
   /** Registers for modem state changed from satellite modem. */
   @SatelliteResult
-  public int registerForSatelliteModemStateChanged(
+  public int registerForModemStateChanged(
       @NonNull @CallbackExecutor Executor executor,
-      @NonNull SatelliteStateCallbackWrapper callback) {
-    SatelliteStateCallback internalCallback =
-        new SatelliteStateCallback() {
+      @NonNull SatelliteModemStateCallbackWrapper callback) {
+    SatelliteModemStateCallback internalCallback =
+        new SatelliteModemStateCallback() {
           public void onSatelliteModemStateChanged(@SatelliteModemState int state) {
             callback.onSatelliteModemStateChanged(state);
           }
         };
-    sSatelliteStateCallbackWrapperMap.put(callback, internalCallback);
+    sSatelliteModemStateCallbackWrapperMap.put(callback, internalCallback);
 
     int result =
-        mSatelliteManager.registerForSatelliteModemStateChanged(executor, internalCallback);
+        mSatelliteManager.registerForModemStateChanged(executor, internalCallback);
     return result;
   }
 
@@ -637,17 +702,18 @@
    * Unregisters for modem state changed from satellite modem. If callback was not registered
    * before, the request will be ignored.
    */
-  public void unregisterForSatelliteModemStateChanged(
-      @NonNull SatelliteStateCallbackWrapper callback) {
-    SatelliteStateCallback internalCallback = sSatelliteStateCallbackWrapperMap.get(callback);
+  public void unregisterForModemStateChanged(
+      @NonNull SatelliteModemStateCallbackWrapper callback) {
+    SatelliteModemStateCallback internalCallback = sSatelliteModemStateCallbackWrapperMap.get(
+            callback);
     if (internalCallback != null) {
-      mSatelliteManager.unregisterForSatelliteModemStateChanged(internalCallback);
+      mSatelliteManager.unregisterForModemStateChanged(internalCallback);
     }
   }
 
   /** Register to receive incoming datagrams over satellite. */
   @SatelliteResult
-  public int registerForSatelliteDatagram(
+  public int registerForIncomingDatagram(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull SatelliteDatagramCallbackWrapper callback) {
     SatelliteDatagramCallback internalCallback =
@@ -666,7 +732,7 @@
           }
         };
     sSatelliteDatagramCallbackWrapperMap.put(callback, internalCallback);
-    int result = mSatelliteManager.registerForSatelliteDatagram(executor, internalCallback);
+    int result = mSatelliteManager.registerForIncomingDatagram(executor, internalCallback);
     return result;
   }
 
@@ -674,18 +740,18 @@
    * Unregister to stop receiving incoming datagrams over satellite. If callback was not registered
    * before, the request will be ignored.
    */
-  public void unregisterForSatelliteDatagram(@NonNull SatelliteDatagramCallbackWrapper callback) {
+  public void unregisterForIncomingDatagram(@NonNull SatelliteDatagramCallbackWrapper callback) {
     SatelliteDatagramCallback internalCallback = sSatelliteDatagramCallbackWrapperMap.get(callback);
     if (internalCallback != null) {
-      mSatelliteManager.unregisterForSatelliteDatagram(internalCallback);
+      mSatelliteManager.unregisterForIncomingDatagram(internalCallback);
     }
   }
 
   /** Poll pending satellite datagrams over satellite. */
-  public void pollPendingSatelliteDatagrams(
+  public void pollPendingDatagrams(
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
-    mSatelliteManager.pollPendingSatelliteDatagrams(executor, resultListener);
+    mSatelliteManager.pollPendingDatagrams(executor, resultListener);
   }
 
   /**
@@ -695,19 +761,19 @@
    * input to this method. Datagram received here will be passed down to modem without any encoding
    * or encryption.
    */
-  public void sendSatelliteDatagram(
+  public void sendDatagram(
       @DatagramType int datagramType,
       @NonNull SatelliteDatagramWrapper datagram,
       boolean needFullScreenPointingUI,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
     SatelliteDatagram datagramInternal = new SatelliteDatagram(datagram.getSatelliteDatagram());
-    mSatelliteManager.sendSatelliteDatagram(
+    mSatelliteManager.sendDatagram(
         datagramType, datagramInternal, needFullScreenPointingUI, executor, resultListener);
   }
 
   /** Request to get whether satellite communication is allowed for the current location. */
-  public void requestIsSatelliteCommunicationAllowedForCurrentLocation(
+  public void requestIsCommunicationAllowedForCurrentLocation(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
     OutcomeReceiver internalCallback =
@@ -722,7 +788,7 @@
             callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
           }
         };
-    mSatelliteManager.requestIsSatelliteCommunicationAllowedForCurrentLocation(
+    mSatelliteManager.requestIsCommunicationAllowedForCurrentLocation(
         executor, internalCallback);
   }
 
@@ -781,15 +847,15 @@
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<NtnSignalStrengthWrapper, SatelliteExceptionWrapper> callback) {
     OutcomeReceiver internalCallback =
-        new OutcomeReceiver<NtnSignalStrength, SatelliteException>() {
-          @Override
-          public void onResult(NtnSignalStrength result) {
-            callback.onResult(new NtnSignalStrengthWrapper(result.getLevel()));
-          }
+            new OutcomeReceiver<NtnSignalStrength, SatelliteException>() {
+              @Override
+              public void onResult(NtnSignalStrength result) {
+                callback.onResult(new NtnSignalStrengthWrapper(result.getLevel()));
+              }
 
-          @Override
-          public void onError(SatelliteException exception) {
-            callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
+              @Override
+              public void onError(SatelliteException exception) {
+                callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
           }
         };
     mSatelliteManager.requestNtnSignalStrength(executor, internalCallback);
@@ -799,7 +865,7 @@
   @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
   public void registerForNtnSignalStrengthChanged(
       @NonNull @CallbackExecutor Executor executor,
-      @NonNull NtnSignalStrengthCallbackWrapper callback) throws SatelliteException {
+      @NonNull NtnSignalStrengthCallbackWrapper callback) {
     NtnSignalStrengthCallback internalCallback =
         new NtnSignalStrengthCallback() {
           @Override
@@ -809,11 +875,7 @@
           }
         };
     sNtnSignalStrengthCallbackWrapperMap.put(callback, internalCallback);
-    try {
-      mSatelliteManager.registerForNtnSignalStrengthChanged(executor, internalCallback);
-    } catch (SatelliteException ex) {
-      throw ex;
-    }
+    mSatelliteManager.registerForNtnSignalStrengthChanged(executor, internalCallback);
   }
 
   /**
@@ -863,7 +925,7 @@
    * @param callback The callback to handle the satellite capabilities changed event.
    */
   @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
-  public int registerForSatelliteCapabilitiesChanged(
+  public int registerForCapabilitiesChanged(
           @NonNull @CallbackExecutor Executor executor,
           @NonNull SatelliteCapabilitiesCallbackWrapper callback) {
     SatelliteCapabilitiesCallback internalCallback =
@@ -875,7 +937,7 @@
                             transformToAntennaPositionWrapperMap(
                                     capabilities.getAntennaPositionMap())));
     sSatelliteCapabilitiesCallbackWrapperMap.put(callback, internalCallback);
-    return mSatelliteManager.registerForSatelliteCapabilitiesChanged(executor, internalCallback);
+    return mSatelliteManager.registerForCapabilitiesChanged(executor, internalCallback);
   }
 
   /**
@@ -885,15 +947,239 @@
    * @param callback The callback that was passed to.
    */
   @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
-  public void unregisterForSatelliteCapabilitiesChanged(
+  public void unregisterForCapabilitiesChanged(
           @NonNull SatelliteCapabilitiesCallbackWrapper callback) {
     SatelliteCapabilitiesCallback internalCallback =
             sSatelliteCapabilitiesCallbackWrapperMap.get(callback);
     if (internalCallback != null) {
-      mSatelliteManager.unregisterForSatelliteCapabilitiesChanged(internalCallback);
+      mSatelliteManager.unregisterForCapabilitiesChanged(internalCallback);
     }
   }
 
+  /**
+   * Wrapper API to provide whether current network is non-terrestrial network or not.
+   *
+   * @param subId Subscription ID.
+   *
+   * @return {@code true} if current network is a non-terrestrial network, {@code false} otherwise.
+   * Note: The method returns {@code false} if the no available network info or any other error
+   * occurs.
+   */
+  public boolean isNonTerrestrialNetwork(int subId) {
+    ServiceState ss = getServiceStateForSubscriptionId(subId);
+
+    if (ss == null) {
+      logd("isNonTerrestrialNetwork(): ServiceState is null, return");
+      return false;
+    }
+
+    NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
+    if (nri == null) {
+      logd("isNonTerrestrialNetwork(): NetworkRegistrationInfo is null, return");
+      return false;
+    }
+
+    boolean isNonTerrestrialNetwork = nri.isNonTerrestrialNetwork();
+    logd("isNonTerrestrialNetwork = " + isNonTerrestrialNetwork);
+    return isNonTerrestrialNetwork;
+  }
+
+  /**
+   * Wrapper API to provide the list of available services.
+   *
+   * @param subId Subscription ID.
+   *
+   * @return the list of available service types for given subscription ID.
+   * Note: The method returns empty list if no service is available or any other error occurs.
+   */
+  @NonNull
+  public List<Integer> getAvailableServices(int subId) {
+    ServiceState ss = getServiceStateForSubscriptionId(subId);
+    if (ss == null) {
+      logd("getAvailableServices(): ServiceState is null, return");
+      return new ArrayList<>();
+    }
+
+    NetworkRegistrationInfo nri = ss.getNetworkRegistrationInfo(DOMAIN_PS, TRANSPORT_TYPE_WWAN);
+    if (nri == null) {
+      logd("getAvailableServices(): NetworkRegistrationInfo is null, return empty list");
+      return new ArrayList<>();
+    }
+
+    List<Integer> serviceType = nri.getAvailableServices();
+    logd("getAvailableServices() : serviceType=" + serviceType.stream().map(
+            Object::toString).collect(Collectors.joining(", ")));
+    return serviceType;
+  }
+
+  /**
+   * Wrapper API to get whether device is connected to a non-terrestrial network.
+   *
+   * @param subId Subscription ID.
+   *
+   * @return {@code true} if device is connected to a non-terrestrial network, {@code false}
+   * otherwise.
+   * Note: The method returns {@code false} if the no available network info or any other error
+   * occurs.
+   */
+  public boolean isUsingNonTerrestrialNetwork(int subId) {
+    ServiceState ss = getServiceStateForSubscriptionId(subId);
+
+    if (ss == null) {
+      logd("isUsingNonTerrestrialNetwork(): ServiceState is null, return");
+      return false;
+    }
+
+    boolean isUsingNonTerrestrialNetwork = ss.isUsingNonTerrestrialNetwork();
+    logd("isUsingNonTerrestrialNetwork() returns " + isUsingNonTerrestrialNetwork);
+    return isUsingNonTerrestrialNetwork;
+  }
+
+  /**
+   * User request to enable or disable carrier supported satellite plmn scan and attach by modem.
+   * <p>
+   * This API should be called by only settings app to pass down the user input for
+   * enabling/disabling satellite. This user input will be persisted across device reboots.
+   * <p>
+   * Satellite will be enabled only when the following conditions are met:
+   * <ul>
+   * <li>Users want to enable it.</li>
+   * <li>There is no satellite communication restriction, which is added by
+   * {@link #addAttachRestrictionForCarrier(int, int, Executor, Consumer)}</li>
+   * <li>The carrier config {@link
+   * android.telephony.CarrierConfigManager#KEY_SATELLITE_ATTACH_SUPPORTED_BOOL} is set to
+   * {@code true}.</li>
+   * </ul>
+   *
+   * @param subId The subscription ID of the carrier.
+   * @param enableSatellite {@code true} to enable the satellite and {@code false} to disable.
+   * @param executor The executor on which the error code listener will be called.
+   * @param resultListener Listener for the {@link SatelliteResult} result of the operation.
+   *
+   * @throws SecurityException if the caller doesn't have required permission.
+   * @throws IllegalArgumentException if the subscription is invalid.
+   */
+  public void requestAttachEnabledForCarrier(int subId, boolean enableSatellite,
+          @NonNull @CallbackExecutor Executor executor,
+          @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    mSatelliteManager.requestAttachEnabledForCarrier(subId, enableSatellite, executor,
+            resultListener);
+  }
+
+  /**
+   * Request to get whether the carrier supported satellite plmn scan and attach by modem is
+   * enabled by user.
+   *
+   * @param subId The subscription ID of the carrier.
+   * @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 the satellite
+   *                 is enabled and {@code false} otherwise.
+   *                 If the request is not successful, {@link OutcomeReceiver#onError(Throwable)}
+   *                 will return a {@link SatelliteExceptionWrapper} with the
+   *                 {@link SatelliteResult}.
+   *
+   * @throws SecurityException if the caller doesn't have required permission.
+   * @throws IllegalStateException if the Telephony process is not currently available.
+   * @throws IllegalArgumentException if the subscription is invalid.
+   */
+  public void requestIsAttachEnabledForCarrier(int subId,
+          @NonNull @CallbackExecutor Executor executor,
+          @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    OutcomeReceiver internalCallback =
+            new OutcomeReceiver<Boolean, SatelliteException>() {
+              @Override
+              public void onResult(Boolean result) {
+                callback.onResult(result);
+              }
+
+              @Override
+              public void onError(SatelliteException exception) {
+                callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
+              }
+            };
+    mSatelliteManager.requestIsAttachEnabledForCarrier(subId, executor, internalCallback);
+  }
+
+  /**
+   * Add a restriction reason for disallowing carrier supported satellite plmn scan and attach
+   * by modem.
+   *
+   * @param subId The subscription ID of the carrier.
+   * @param reason Reason for disallowing satellite communication.
+   * @param executor The executor on which the error code listener will be called.
+   * @param resultListener Listener for the {@link SatelliteResult} result of the
+   * operation.
+   *
+   * @throws SecurityException if the caller doesn't have required permission.
+   * @throws IllegalArgumentException if the subscription is invalid.
+   */
+  public void addAttachRestrictionForCarrier(int subId,
+          @SatelliteCommunicationRestrictionReason int reason,
+          @NonNull @CallbackExecutor Executor executor,
+          @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    mSatelliteManager.addAttachRestrictionForCarrier(subId, reason, executor, resultListener);
+  }
+
+  /**
+   * Remove a restriction reason for disallowing carrier supported satellite plmn scan and attach
+   * by modem.
+   *
+   * @param subId The subscription ID of the carrier.
+   * @param reason Reason for disallowing satellite communication.
+   * @param executor The executor on which the error code listener will be called.
+   * @param resultListener Listener for the {@link SatelliteResult} result of the
+   * operation.
+   *
+   * @throws SecurityException if the caller doesn't have required permission.
+   * @throws IllegalArgumentException if the subscription is invalid.
+   */
+  public void removeAttachRestrictionForCarrier(int subId,
+          @SatelliteCommunicationRestrictionReason int reason,
+          @NonNull @CallbackExecutor Executor executor,
+          @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    mSatelliteManager.removeAttachRestrictionForCarrier(subId, reason, executor, resultListener);
+  }
+
+  /**
+   * Get reasons for disallowing satellite attach, as requested by
+   * {@link #addAttachRestrictionForCarrier(int, int, Executor, Consumer)}
+   *
+   * @param subId The subscription ID of the carrier.
+   * @return Set of reasons for disallowing satellite communication.
+   *
+   * @throws SecurityException if the caller doesn't have required permission.
+   * @throws IllegalStateException if the Telephony process is not currently available.
+   * @throws IllegalArgumentException if the subscription is invalid.
+   */
+  @SatelliteCommunicationRestrictionReason
+  @NonNull public Set<Integer> getAttachRestrictionReasonsForCarrier(int subId) {
+    return mSatelliteManager.getAttachRestrictionReasonsForCarrier(subId);
+  }
+
+  /**
+   * Get all satellite PLMNs for which attach is enable for carrier.
+   *
+   * @param subId subId The subscription ID of the carrier.
+   *
+   * @return List of plmn for carrier satellite service. If no plmn is available, empty list will
+   * be returned.
+   */
+  @NonNull public List<String> getSatellitePlmnsForCarrier(int subId) {
+    return mSatelliteManager.getSatellitePlmnsForCarrier(subId);
+  }
+
+  @Nullable
+  private ServiceState getServiceStateForSubscriptionId(int subId) {
+    if (!mSubscriptionManager.isValidSubscriptionId(subId)) {
+      return null;
+    }
+
+    TelephonyManager tm = mTelephonyManager.createForSubscriptionId(subId);
+    return tm.getServiceState();
+  }
+
   private void logd(String message) {
     Rlog.d(TAG, message);
   }
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteStateCallbackWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper.java
similarity index 94%
rename from satellite_client/src/android/telephony/satellite/wrapper/SatelliteStateCallbackWrapper.java
rename to satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper.java
index 3d57fa0..450e48a 100644
--- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteStateCallbackWrapper.java
+++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper.java
@@ -17,7 +17,7 @@
 package android.telephony.satellite.wrapper;
 
 /** A callback class for monitoring satellite modem state change events. */
-public interface SatelliteStateCallbackWrapper {
+public interface SatelliteModemStateCallbackWrapper {
 
   /**
    * Called when satellite modem state changes.
diff --git a/ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java b/ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java
new file mode 100644
index 0000000..37ad354
--- /dev/null
+++ b/ts43authentication/src/com/android/libraries/ts43authentication/AuthenticationOutcomeReceiver.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2024 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.libraries.ts43authentication;
+
+/**
+ * Callback interface intended for use when an TS.43 authentication request may result in a failure.
+ * This interface may be used in cases where an asynchronous API may complete either with a value
+ * or with a {@link Throwable} that indicates an error.
+ * Functionally the same as an OutcomeReceiver, but creating a new class for backwards compatibility
+ * on devices with SDK < 31.
+ *
+ * @param <R> The type of the result that's being sent.
+ * @param <E> The type of the {@link Throwable} that contains more information about the error.
+ */
+public interface AuthenticationOutcomeReceiver <R, E extends Throwable> {
+    /**
+     * Called when the asynchronous operation succeeds and delivers a result value.
+     *
+     * @param result The value delivered by the asynchronous operation.
+     */
+    void onResult(R result);
+
+    /**
+     * Called when the asynchronous operation fails. The mode of failure is indicated by the
+     * {@link Throwable} passed as an argument to this method.
+     *
+     * @param error A subclass of {@link Throwable} with more details about the error that occurred.
+     */
+    default void onError(E error) {}
+}
diff --git a/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java b/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java
index be3931d..da45671 100644
--- a/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java
+++ b/ts43authentication/src/com/android/libraries/ts43authentication/Ts43AuthenticationLibrary.java
@@ -22,10 +22,10 @@
 import android.content.pm.Signature;
 import android.content.pm.SigningInfo;
 import android.os.Binder;
+import android.os.Build;
 import android.os.Handler;
 import android.os.Looper;
 import android.os.Message;
-import android.os.OutcomeReceiver;
 import android.os.PersistableBundle;
 import android.telephony.SubscriptionInfo;
 import android.util.Log;
@@ -43,7 +43,6 @@
 import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import java.util.ArrayList;
-import java.util.HexFormat;
 import java.util.List;
 import java.util.concurrent.Executor;
 import java.util.concurrent.locks.ReentrantLock;
@@ -131,12 +130,12 @@
         @Nullable private final String mEntitlementVersion;
         private final String mAppId;
         private final Executor mExecutor;
-        private final OutcomeReceiver<
+        private final AuthenticationOutcomeReceiver<
                 Ts43Authentication.Ts43AuthToken, AuthenticationException> mCallback;
 
         private EapAkaAuthenticationRequest(String appName, @Nullable String appVersion,
                 int slotIndex, URL entitlementServerAddress, @Nullable String entitlementVersion,
-                String appId, Executor executor, OutcomeReceiver<
+                String appId, Executor executor, AuthenticationOutcomeReceiver<
                         Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) {
             mAppName = appName;
             mAppVersion = appVersion;
@@ -157,12 +156,12 @@
         @Nullable private final String mEntitlementVersion;
         private final String mAppId;
         private final Executor mExecutor;
-        private final OutcomeReceiver<URL, AuthenticationException> mCallback;
+        private final AuthenticationOutcomeReceiver<URL, AuthenticationException> mCallback;
 
         private OidcAuthenticationServerRequest(String appName, @Nullable String appVersion,
                 int slotIndex, URL entitlementServerAddress, @Nullable String entitlementVersion,
                 String appId, Executor executor,
-                OutcomeReceiver<URL, AuthenticationException> callback) {
+                AuthenticationOutcomeReceiver<URL, AuthenticationException> callback) {
             mAppName = appName;
             mAppVersion = appVersion;
             mSlotIndex = slotIndex;
@@ -179,11 +178,12 @@
         @Nullable private final String mEntitlementVersion;
         private final URL mAesUrl;
         private final Executor mExecutor;
-        private final OutcomeReceiver<
+        private final AuthenticationOutcomeReceiver<
                 Ts43Authentication.Ts43AuthToken, AuthenticationException> mCallback;
 
         private OidcAuthenticationRequest(URL entitlementServerAddress,
-                @Nullable String entitlementVersion, URL aesUrl, Executor executor, OutcomeReceiver<
+                @Nullable String entitlementVersion, URL aesUrl, Executor executor,
+                AuthenticationOutcomeReceiver<
                         Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) {
             mEntitlementServerAddress = entitlementServerAddress;
             mEntitlementVersion = entitlementVersion;
@@ -216,14 +216,17 @@
      *        Refer to GSMA Service Entitlement Configuration section 2.3.
      * @param executor The executor on which the callback will be called.
      * @param callback The callback to receive the results of the authentication request.
-     *        If authentication is successful, {@link OutcomeReceiver#onResult(Object)} will return
-     *        a {@link Ts43Authentication.Ts43AuthToken} with the token and validity.
-     *        If the authentication fails, {@link OutcomeReceiver#onError(Throwable)} will return an
+     *        If authentication is successful,
+     *        {@link AuthenticationOutcomeReceiver#onResult(Object)} will return a
+     *        {@link Ts43Authentication.Ts43AuthToken} with the token and validity.
+     *        If the authentication fails,
+     *        {@link AuthenticationOutcomeReceiver#onError(Throwable)} will return an
      *        {@link AuthenticationException} with the failure details.
      */
     public void requestEapAkaAuthentication(PersistableBundle configs, String packageName,
             @Nullable String appVersion, int slotIndex, URL entitlementServerAddress,
-            @Nullable String entitlementVersion, String appId, Executor executor, OutcomeReceiver<
+            @Nullable String entitlementVersion, String appId, Executor executor,
+            AuthenticationOutcomeReceiver<
                     Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) {
         String[] allowedPackageInfo = configs.getStringArray(KEY_ALLOWED_CERTIFICATES_STRING_ARRAY);
         String certificate = getMatchingCertificate(allowedPackageInfo, packageName);
@@ -245,8 +248,8 @@
      * The client should present the content of the URL to the user to continue the authentication
      * process. After receiving a response from the authentication server, the client can call
      * {@link #requestOidcAuthentication(
-     * PersistableBundle, String, URL, String, URL, Executor, OutcomeReceiver)} to get the
-     * authentication token.
+     * PersistableBundle, String, URL, String, URL, Executor, AuthenticationOutcomeReceiver)} to get
+     * the authentication token.
      *
      * @param configs The configurations that should be applied to this authentication request.
      *        The keys of the bundle must be in {@link ConfigurationKey}.
@@ -267,18 +270,18 @@
      *        Refer to GSMA Service Entitlement Configuration section 2.3.
      * @param executor The executor on which the callback will be called.
      * @param callback The callback to receive the results of the authentication server request.
-     *        If the request is successful, {@link OutcomeReceiver#onResult(Object)} will return a
-     *        {@link URL} with all the required parameters for the client to launch a user interface
-     *        for users to complete the authentication process. The parameters in URL include
-     *        {@code client_id}, {@code redirect_uri}, {@code state}, and {@code nonce}.
-     *        If the authentication fails, {@link OutcomeReceiver#onError(Throwable)} will return an
-     *        {@link AuthenticationException} with the failure details.
+     *        If the request is successful, {@link AuthenticationOutcomeReceiver#onResult(Object)}
+     *        will return a {@link URL} with all the required parameters for the client to launch a
+     *        user interface for users to complete the authentication process. The parameters in URL
+     *        include {@code client_id}, {@code redirect_uri}, {@code state}, and {@code nonce}.
+     *        If the authentication fails, {@link AuthenticationOutcomeReceiver#onError(Throwable)}
+     *        will return an {@link AuthenticationException} with the failure details.
      */
     public void requestOidcAuthenticationServer(PersistableBundle configs,
             String packageName, @Nullable String appVersion, int slotIndex,
             URL entitlementServerAddress, @Nullable String entitlementVersion,
             String appId, Executor executor,
-            OutcomeReceiver<URL, AuthenticationException> callback) {
+            AuthenticationOutcomeReceiver<URL, AuthenticationException> callback) {
         String[] allowedPackageInfo = configs.getStringArray(KEY_ALLOWED_CERTIFICATES_STRING_ARRAY);
         String certificate = getMatchingCertificate(allowedPackageInfo, packageName);
         if (isCallingPackageAllowed(allowedPackageInfo, packageName, certificate)) {
@@ -309,15 +312,16 @@
      *        URL include the OIDC authentication code {@code code} and {@code state}.
      * @param executor The executor on which the callback will be called.
      * @param callback The callback to receive the results of the authentication request.
-     *        If authentication is successful, {@link OutcomeReceiver#onResult(Object)} will return
-     *        a {@link Ts43Authentication.Ts43AuthToken} with the token and validity.
-     *        If the authentication fails, {@link OutcomeReceiver#onError(Throwable)} will return an
-     *        {@link AuthenticationException} with the failure details.
+     *        If authentication is successful,
+     *        {@link AuthenticationOutcomeReceiver#onResult(Object)} will return a
+     *        {@link Ts43Authentication.Ts43AuthToken} with the token and validity.
+     *        If the authentication fails, {@link AuthenticationOutcomeReceiver#onError(Throwable)}
+     *        will return an {@link AuthenticationException} with the failure details.
      */
     public void requestOidcAuthentication(PersistableBundle configs,
             String packageName, URL entitlementServerAddress,
             @Nullable String entitlementVersion, URL aesUrl, Executor executor,
-            OutcomeReceiver<
+            AuthenticationOutcomeReceiver<
                     Ts43Authentication.Ts43AuthToken, AuthenticationException> callback) {
         String[] allowedPackageInfo = configs.getStringArray(KEY_ALLOWED_CERTIFICATES_STRING_ARRAY);
         String certificate = getMatchingCertificate(allowedPackageInfo, packageName);
@@ -372,7 +376,7 @@
         for (Signature signature : signatures) {
             byte[] signatureHash = md.digest(signature.toByteArray());
             for (String certificate : allowedCertificates) {
-                byte[] certificateHash = HexFormat.of().parseHex(certificate);
+                byte[] certificateHash = hexStringToBytes(certificate);
                 if (Arrays.equals(signatureHash, certificateHash)) {
                     Log.d(TAG, "Found matching certificate for package " + packageName + ": "
                             + certificate);
@@ -412,8 +416,14 @@
     @Nullable private Signature[] getMainPackageSignatures(String packageName) {
         PackageInfo packageInfo;
         try {
-            packageInfo = mPackageManager.getPackageInfo(packageName,
-                    PackageManager.PackageInfoFlags.of(PackageManager.GET_SIGNING_CERTIFICATES));
+            if (Build.VERSION.SDK_INT < 33) {
+                packageInfo = mPackageManager.getPackageInfo(packageName,
+                        PackageManager.GET_SIGNING_CERTIFICATES);
+            } else {
+                packageInfo = mPackageManager.getPackageInfo(packageName,
+                        PackageManager.PackageInfoFlags.of(
+                                PackageManager.GET_SIGNING_CERTIFICATES));
+            }
         } catch (PackageManager.NameNotFoundException e) {
             Log.e(TAG, "Unable to find package name: " + packageName);
             return null;
@@ -439,6 +449,25 @@
         return signatures;
     }
 
+    @Nullable private byte[] hexStringToBytes(@Nullable String hex) {
+        if (hex == null) {
+            return null;
+        }
+
+        int length = hex.length();
+        byte[] ret = new byte[length / 2];
+
+        for (int i = 0; i < length; i += 2) {
+            ret[i / 2] =
+                    (byte) ((hexCharToInt(hex.charAt(i)) << 4) | hexCharToInt(hex.charAt(i + 1)));
+        }
+        return ret;
+    }
+
+    private int hexCharToInt(char hex) {
+        return Integer.parseInt(String.valueOf(hex), 16);
+    }
+
     private boolean isCallingPackageAllowed(@Nullable String[] allowedPackageInfo,
             String packageName, @Nullable String certificate) {
         // Check that the package name matches that of the calling package.