Snap for 12134224 from 4ee1c609cc1c294a9e194885a79b88e5625bd31f to simpleperf-release

Change-Id: Ia4daeb35a738912531e23514d02cf04f2753d340
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/NtnSignalStrengthCallbackWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthCallbackWrapper.java
new file mode 100644
index 0000000..46aef62
--- /dev/null
+++ b/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthCallbackWrapper.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.wrapper;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import com.android.internal.telephony.flags.Flags;
+
+/**
+ * Encapsulates the callback class for notifying satellite signal strength change.
+ */
+@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+public interface NtnSignalStrengthCallbackWrapper {
+  /**
+   * Called when non-terrestrial network signal strength changes.
+   * @param ntnSignalStrength The new non-terrestrial network signal strength.
+   */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  void onNtnSignalStrengthChanged(@NonNull NtnSignalStrengthWrapper ntnSignalStrength);
+}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthWrapper.java
new file mode 100644
index 0000000..5198457
--- /dev/null
+++ b/satellite_client/src/android/telephony/satellite/wrapper/NtnSignalStrengthWrapper.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.wrapper;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
+import android.annotation.NonNull;
+import com.android.internal.telephony.flags.Flags;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/** Encapsulates the non-terrestrial network signal strength related information. */
+@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+public final class NtnSignalStrengthWrapper {
+
+  /** Non-terrestrial network signal strength is not available. */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public static final int NTN_SIGNAL_STRENGTH_NONE = 0;
+  /** Non-terrestrial network signal strength is poor. */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public static final int NTN_SIGNAL_STRENGTH_POOR = 1;
+  /** Non-terrestrial network signal strength is moderate. */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public static final int NTN_SIGNAL_STRENGTH_MODERATE = 2;
+  /** Non-terrestrial network signal strength is good. */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public static final int NTN_SIGNAL_STRENGTH_GOOD = 3;
+  /** Non-terrestrial network signal strength is great. */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public static final int NTN_SIGNAL_STRENGTH_GREAT = 4;
+  @NtnSignalStrengthLevel private final int mLevel;
+
+  /** @hide */
+  @IntDef(prefix = "NTN_SIGNAL_STRENGTH_", value = {
+      NTN_SIGNAL_STRENGTH_NONE,
+      NTN_SIGNAL_STRENGTH_POOR,
+      NTN_SIGNAL_STRENGTH_MODERATE,
+      NTN_SIGNAL_STRENGTH_GOOD,
+      NTN_SIGNAL_STRENGTH_GREAT
+  })
+  @Retention(RetentionPolicy.SOURCE)
+  public @interface NtnSignalStrengthLevel {}
+
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public NtnSignalStrengthWrapper(@NonNull @NtnSignalStrengthLevel int level) {
+    this.mLevel = level;
+  }
+
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  @NtnSignalStrengthLevel public int getLevel() {
+    return mLevel;
+  }
+}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCapabilitiesCallbackWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCapabilitiesCallbackWrapper.java
new file mode 100644
index 0000000..c538608
--- /dev/null
+++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCapabilitiesCallbackWrapper.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.telephony.satellite.wrapper;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+
+import com.android.internal.telephony.flags.Flags;
+
+/**
+ * A callback class for satellite capabilities change events.
+ */
+@FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+public interface SatelliteCapabilitiesCallbackWrapper {
+  /**
+   * Called when satellite capability has changed.
+   * @param capabilities The new satellite capabilities.
+   */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  void onSatelliteCapabilitiesChanged(@NonNull SatelliteCapabilitiesWrapper capabilities);
+}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
index b13a0fc..d230e8f 100644
--- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
+++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
@@ -16,32 +16,52 @@
 
 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;
+import android.annotation.FlaggedApi;
 import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 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;
 import android.telephony.satellite.SatelliteCapabilities;
+import android.telephony.satellite.SatelliteCapabilitiesCallback;
 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;
+import com.android.telephony.Rlog;
+
 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,
@@ -51,24 +71,37 @@
   private static final String TAG = "SatelliteManagerWrapper";
 
   private static final ConcurrentHashMap<
+      SatelliteDatagramCallbackWrapper, SatelliteDatagramCallback>
+      sSatelliteDatagramCallbackWrapperMap = new ConcurrentHashMap<>();
+
+  private static final ConcurrentHashMap<
           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>
       sSatelliteTransmissionUpdateCallbackWrapperMap = new ConcurrentHashMap<>();
 
   private static final ConcurrentHashMap<
-          SatelliteDatagramCallbackWrapper, SatelliteDatagramCallback>
-      sSatelliteDatagramCallbackWrapperMap = new ConcurrentHashMap<>();
+          NtnSignalStrengthCallbackWrapper, NtnSignalStrengthCallback>
+      sNtnSignalStrengthCallbackWrapperMap = new ConcurrentHashMap<>();
+
+  private static final ConcurrentHashMap<
+          SatelliteCapabilitiesCallbackWrapper, SatelliteCapabilitiesCallback>
+          sSatelliteCapabilitiesCallbackWrapperMap = new ConcurrentHashMap<>();
 
   private final SatelliteManager mSatelliteManager;
+  private final SubscriptionManager mSubscriptionManager;
+  private final TelephonyManager mTelephonyManager;
 
   SatelliteManagerWrapper(Context context) {
-    mSatelliteManager = (SatelliteManager) context.getSystemService("satellite");
+    mSatelliteManager = context.getSystemService(SatelliteManager.class);
+    mSubscriptionManager = context.getSystemService(SubscriptionManager.class);
+    mTelephonyManager = context.getSystemService(TelephonyManager.class);
   }
 
   /**
@@ -224,104 +257,107 @@
   public @interface SatelliteDatagramTransferState {}
 
   /** The request was successfully processed. */
-  public static final int SATELLITE_ERROR_NONE = 0;
+  public static final int SATELLITE_RESULT_SUCCESS = 0;
   /** A generic error which should be used only when other specific errors cannot be used. */
-  public static final int SATELLITE_ERROR = 1;
+  public static final int SATELLITE_RESULT_ERROR = 1;
   /** Error received from the satellite server. */
-  public static final int SATELLITE_SERVER_ERROR = 2;
+  public static final int SATELLITE_RESULT_SERVER_ERROR = 2;
   /**
    * Error received from the vendor service. This generic error code should be used only when the
    * error cannot be mapped to other specific service error codes.
    */
-  public static final int SATELLITE_SERVICE_ERROR = 3;
+  public static final int SATELLITE_RESULT_SERVICE_ERROR = 3;
   /**
    * Error received from satellite modem. This generic error code should be used only when the error
    * cannot be mapped to other specific modem error codes.
    */
-  public static final int SATELLITE_MODEM_ERROR = 4;
+  public static final int SATELLITE_RESULT_MODEM_ERROR = 4;
   /**
    * Error received from the satellite network. This generic error code should be used only when the
    * error cannot be mapped to other specific network error codes.
    */
-  public static final int SATELLITE_NETWORK_ERROR = 5;
+  public static final int SATELLITE_RESULT_NETWORK_ERROR = 5;
   /** Telephony is not in a valid state to receive requests from clients. */
-  public static final int SATELLITE_INVALID_TELEPHONY_STATE = 6;
+  public static final int SATELLITE_RESULT_INVALID_TELEPHONY_STATE = 6;
   /** Satellite modem is not in a valid state to receive requests from clients. */
-  public static final int SATELLITE_INVALID_MODEM_STATE = 7;
+  public static final int SATELLITE_RESULT_INVALID_MODEM_STATE = 7;
   /**
    * Either vendor service, or modem, or Telephony framework has received a request with invalid
    * arguments from its clients.
    */
-  public static final int SATELLITE_INVALID_ARGUMENTS = 8;
+  public static final int SATELLITE_RESULT_INVALID_ARGUMENTS = 8;
   /**
    * Telephony framework failed to send a request or receive a response from the vendor service or
    * satellite modem due to internal error.
    */
-  public static final int SATELLITE_REQUEST_FAILED = 9;
+  public static final int SATELLITE_RESULT_REQUEST_FAILED = 9;
   /** Radio did not start or is resetting. */
-  public static final int SATELLITE_RADIO_NOT_AVAILABLE = 10;
+  public static final int SATELLITE_RESULT_RADIO_NOT_AVAILABLE = 10;
   /** The request is not supported by either the satellite modem or the network. */
-  public static final int SATELLITE_REQUEST_NOT_SUPPORTED = 11;
+  public static final int SATELLITE_RESULT_REQUEST_NOT_SUPPORTED = 11;
   /** Satellite modem or network has no resources available to handle requests from clients. */
-  public static final int SATELLITE_NO_RESOURCES = 12;
+  public static final int SATELLITE_RESULT_NO_RESOURCES = 12;
   /** Satellite service is not provisioned yet. */
-  public static final int SATELLITE_SERVICE_NOT_PROVISIONED = 13;
+  public static final int SATELLITE_RESULT_SERVICE_NOT_PROVISIONED = 13;
   /** Satellite service provision is already in progress. */
-  public static final int SATELLITE_SERVICE_PROVISION_IN_PROGRESS = 14;
+  public static final int SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS = 14;
   /**
    * The ongoing request was aborted by either the satellite modem or the network. This error is
    * also returned when framework decides to abort current send request as one of the previous send
    * request failed.
    */
-  public static final int SATELLITE_REQUEST_ABORTED = 15;
+  public static final int SATELLITE_RESULT_REQUEST_ABORTED = 15;
   /** The device/subscriber is barred from accessing the satellite service. */
-  public static final int SATELLITE_ACCESS_BARRED = 16;
+  public static final int SATELLITE_RESULT_ACCESS_BARRED = 16;
   /**
    * Satellite modem timeout to receive ACK or response from the satellite network after sending a
    * request to the network.
    */
-  public static final int SATELLITE_NETWORK_TIMEOUT = 17;
+  public static final int SATELLITE_RESULT_NETWORK_TIMEOUT = 17;
   /** Satellite network is not reachable from the modem. */
-  public static final int SATELLITE_NOT_REACHABLE = 18;
+  public static final int SATELLITE_RESULT_NOT_REACHABLE = 18;
   /** The device/subscriber is not authorized to register with the satellite service provider. */
-  public static final int SATELLITE_NOT_AUTHORIZED = 19;
+  public static final int SATELLITE_RESULT_NOT_AUTHORIZED = 19;
   /** The device does not support satellite. */
-  public static final int SATELLITE_NOT_SUPPORTED = 20;
+  public static final int SATELLITE_RESULT_NOT_SUPPORTED = 20;
   /** The current request is already in-progress. */
-  public static final int SATELLITE_REQUEST_IN_PROGRESS = 21;
+  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_MODEM_BUSY = 22;
+  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(
-      prefix = {"SATELLITE_"},
+      prefix = {"SATELLITE_RESULT_"},
       value = {
-        SATELLITE_ERROR_NONE,
-        SATELLITE_ERROR,
-        SATELLITE_SERVER_ERROR,
-        SATELLITE_SERVICE_ERROR,
-        SATELLITE_MODEM_ERROR,
-        SATELLITE_NETWORK_ERROR,
-        SATELLITE_INVALID_TELEPHONY_STATE,
-        SATELLITE_INVALID_MODEM_STATE,
-        SATELLITE_INVALID_ARGUMENTS,
-        SATELLITE_REQUEST_FAILED,
-        SATELLITE_RADIO_NOT_AVAILABLE,
-        SATELLITE_REQUEST_NOT_SUPPORTED,
-        SATELLITE_NO_RESOURCES,
-        SATELLITE_SERVICE_NOT_PROVISIONED,
-        SATELLITE_SERVICE_PROVISION_IN_PROGRESS,
-        SATELLITE_REQUEST_ABORTED,
-        SATELLITE_ACCESS_BARRED,
-        SATELLITE_NETWORK_TIMEOUT,
-        SATELLITE_NOT_REACHABLE,
-        SATELLITE_NOT_AUTHORIZED,
-        SATELLITE_NOT_SUPPORTED,
-        SATELLITE_REQUEST_IN_PROGRESS,
-        SATELLITE_MODEM_BUSY
+        SATELLITE_RESULT_SUCCESS,
+        SATELLITE_RESULT_ERROR,
+        SATELLITE_RESULT_SERVER_ERROR,
+        SATELLITE_RESULT_SERVICE_ERROR,
+        SATELLITE_RESULT_MODEM_ERROR,
+        SATELLITE_RESULT_NETWORK_ERROR,
+        SATELLITE_RESULT_INVALID_TELEPHONY_STATE,
+        SATELLITE_RESULT_INVALID_MODEM_STATE,
+        SATELLITE_RESULT_INVALID_ARGUMENTS,
+        SATELLITE_RESULT_REQUEST_FAILED,
+        SATELLITE_RESULT_RADIO_NOT_AVAILABLE,
+        SATELLITE_RESULT_REQUEST_NOT_SUPPORTED,
+        SATELLITE_RESULT_NO_RESOURCES,
+        SATELLITE_RESULT_SERVICE_NOT_PROVISIONED,
+        SATELLITE_RESULT_SERVICE_PROVISION_IN_PROGRESS,
+        SATELLITE_RESULT_REQUEST_ABORTED,
+        SATELLITE_RESULT_ACCESS_BARRED,
+        SATELLITE_RESULT_NETWORK_TIMEOUT,
+        SATELLITE_RESULT_NOT_REACHABLE,
+        SATELLITE_RESULT_NOT_AUTHORIZED,
+        SATELLITE_RESULT_NOT_SUPPORTED,
+        SATELLITE_RESULT_REQUEST_IN_PROGRESS,
+        SATELLITE_RESULT_MODEM_BUSY,
+        SATELLITE_RESULT_ILLEGAL_STATE
       })
   @Retention(RetentionPolicy.SOURCE)
-  public @interface SatelliteError {}
+  public @interface SatelliteResult {}
 
   /** Suggested device hold position is unknown. */
   public static final int DEVICE_HOLD_POSITION_UNKNOWN = 0;
@@ -344,7 +380,35 @@
   @Retention(RetentionPolicy.SOURCE)
   public @interface DeviceHoldPosition {}
 
-  /** Exception from the satellite service containing the {@link SatelliteError} error code. */
+  /**
+   * 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;
 
@@ -364,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,
-      @SatelliteError @NonNull Consumer<Integer> resultListener) {
-    mSatelliteManager.requestSatelliteEnabled(
-        enableSatellite, enableDemoMode, executor, resultListener);
+      @SatelliteResult @NonNull Consumer<Integer> 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 =
@@ -389,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. */
@@ -411,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 =
@@ -427,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 =
@@ -451,20 +537,20 @@
             callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
           }
         };
-    mSatelliteManager.requestSatelliteCapabilities(executor, internalCallback);
+    mSatelliteManager.requestCapabilities(executor, internalCallback);
   }
 
   /**
    * Start receiving satellite transmission updates. This can be called by the pointing UI when the
    * user starts pointing to the satellite. Modem should continue to report the pointing input as
    * the device or satellite moves. Satellite transmission updates are started only on {@link
-   * #SATELLITE_ERROR_NONE}. All other results indicate that this operation failed. Once satellite
-   * transmission updates begin, position and datagram transfer state updates will be sent through
-   * {@link SatelliteTransmissionUpdateCallback}.
+   * #SATELLITE_RESULT_SUCCESS}. All other results indicate that this operation failed.
+   * 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,
-      @SatelliteError @NonNull Consumer<Integer> resultListener,
+      @SatelliteResult @NonNull Consumer<Integer> resultListener,
       @NonNull SatelliteTransmissionUpdateCallbackWrapper callback) {
 
     SatelliteTransmissionUpdateCallback internalCallback =
@@ -474,7 +560,7 @@
           public void onSendDatagramStateChanged(
               @SatelliteDatagramTransferState int state,
               int sendPendingCount,
-              @SatelliteError int errorCode) {
+              @SatelliteResult int errorCode) {
             callback.onSendDatagramStateChanged(state, sendPendingCount, errorCode);
           }
 
@@ -482,7 +568,7 @@
           public void onReceiveDatagramStateChanged(
               @SatelliteDatagramTransferState int state,
               int receivePendingCount,
-              @SatelliteError int errorCode) {
+              @SatelliteResult int errorCode) {
             callback.onReceiveDatagramStateChanged(state, receivePendingCount, errorCode);
           }
 
@@ -496,23 +582,23 @@
         };
     sSatelliteTransmissionUpdateCallbackWrapperMap.put(callback, internalCallback);
 
-    mSatelliteManager.startSatelliteTransmissionUpdates(executor, resultListener, internalCallback);
+    mSatelliteManager.startTransmissionUpdates(executor, resultListener, internalCallback);
   }
 
   /**
    * Stop receiving satellite transmission updates. This can be called by the pointing UI when the
    * user stops pointing to the satellite. Satellite transmission updates are stopped and the
-   * callback is unregistered only on {@link #SATELLITE_ERROR_NONE}. All other results that this
+   * 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,
-      @SatelliteError @NonNull Consumer<Integer> resultListener) {
+      @SatelliteResult @NonNull Consumer<Integer> resultListener) {
     SatelliteTransmissionUpdateCallback internalCallback =
         sSatelliteTransmissionUpdateCallbackWrapperMap.get(callback);
     if (internalCallback != null) {
-      mSatelliteManager.stopSatelliteTransmissionUpdates(
+      mSatelliteManager.stopTransmissionUpdates(
           internalCallback, executor, resultListener);
     }
   }
@@ -521,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,
-      @SatelliteError @NonNull Consumer<Integer> resultListener) {
-    mSatelliteManager.provisionSatelliteService(
+      @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    mSatelliteManager.provisionService(
         token, provisionData, cancellationSignal, executor, resultListener);
   }
 
@@ -537,16 +623,16 @@
    * SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean)} should report as
    * deprovisioned.
    */
-  public void deprovisionSatelliteService(
+  public void deprovisionService(
       @NonNull String token,
       @NonNull @CallbackExecutor Executor executor,
-      @SatelliteError @NonNull Consumer<Integer> resultListener) {
-    mSatelliteManager.deprovisionSatelliteService(token, executor, resultListener);
+      @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    mSatelliteManager.deprovisionService(token, executor, resultListener);
   }
 
   /** Registers for the satellite provision state changed. */
-  @SatelliteError
-  public int registerForSatelliteProvisionStateChanged(
+  @SatelliteResult
+  public int registerForProvisionStateChanged(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull SatelliteProvisionStateCallbackWrapper callback) {
     SatelliteProvisionStateCallback internalCallback =
@@ -558,7 +644,7 @@
         };
     sSatelliteProvisionStateCallbackWrapperMap.put(callback, internalCallback);
     int result =
-        mSatelliteManager.registerForSatelliteProvisionStateChanged(executor, internalCallback);
+        mSatelliteManager.registerForProvisionStateChanged(executor, internalCallback);
     return result;
   }
 
@@ -566,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 =
@@ -591,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. */
-  @SatelliteError
-  public int registerForSatelliteModemStateChanged(
+  @SatelliteResult
+  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;
   }
 
@@ -616,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. */
-  @SatelliteError
-  public int registerForSatelliteDatagram(
+  @SatelliteResult
+  public int registerForIncomingDatagram(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull SatelliteDatagramCallbackWrapper callback) {
     SatelliteDatagramCallback internalCallback =
@@ -645,7 +732,7 @@
           }
         };
     sSatelliteDatagramCallbackWrapperMap.put(callback, internalCallback);
-    int result = mSatelliteManager.registerForSatelliteDatagram(executor, internalCallback);
+    int result = mSatelliteManager.registerForIncomingDatagram(executor, internalCallback);
     return result;
   }
 
@@ -653,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,
-      @SatelliteError @NonNull Consumer<Integer> resultListener) {
-    mSatelliteManager.pollPendingSatelliteDatagrams(executor, resultListener);
+      @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    mSatelliteManager.pollPendingDatagrams(executor, resultListener);
   }
 
   /**
@@ -674,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,
-      @SatelliteError @NonNull Consumer<Integer> resultListener) {
+      @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 =
@@ -701,7 +788,7 @@
             callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
           }
         };
-    mSatelliteManager.requestIsSatelliteCommunicationAllowedForCurrentLocation(
+    mSatelliteManager.requestIsCommunicationAllowedForCurrentLocation(
         executor, internalCallback);
   }
 
@@ -730,8 +817,8 @@
   /**
    * Inform whether the device is aligned with the satellite for demo mode.
    */
-  public void onDeviceAlignedWithSatellite(boolean isAligned) {
-    mSatelliteManager.onDeviceAlignedWithSatellite(isAligned);
+  public void setDeviceAlignedWithSatellite(boolean isAligned) {
+    mSatelliteManager.setDeviceAlignedWithSatellite(isAligned);
   }
 
   private Map<Integer, AntennaPositionWrapper> transformToAntennaPositionWrapperMap(
@@ -752,4 +839,348 @@
 
     return output;
   }
+
+  /** Request to get the signal strength of the satellite connection. */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  @NonNull
+  public void requestNtnSignalStrength(
+      @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()));
+              }
+
+              @Override
+              public void onError(SatelliteException exception) {
+                callback.onError(new SatelliteExceptionWrapper(exception.getErrorCode()));
+          }
+        };
+    mSatelliteManager.requestNtnSignalStrength(executor, internalCallback);
+  }
+
+  /** Registers for NTN signal strength changed from satellite modem. */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public void registerForNtnSignalStrengthChanged(
+      @NonNull @CallbackExecutor Executor executor,
+      @NonNull NtnSignalStrengthCallbackWrapper callback) {
+    NtnSignalStrengthCallback internalCallback =
+        new NtnSignalStrengthCallback() {
+          @Override
+          public void onNtnSignalStrengthChanged(@NonNull NtnSignalStrength ntnSignalStrength) {
+            callback.onNtnSignalStrengthChanged(
+                new NtnSignalStrengthWrapper(ntnSignalStrength.getLevel()));
+          }
+        };
+    sNtnSignalStrengthCallbackWrapperMap.put(callback, internalCallback);
+    mSatelliteManager.registerForNtnSignalStrengthChanged(executor, internalCallback);
+  }
+
+  /**
+   * Unregisters for NTN signal strength changed from satellite modem.
+   * If callback was not registered before, the request will be ignored.
+   */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public void unregisterForNtnSignalStrengthChanged(
+      @NonNull NtnSignalStrengthCallbackWrapper callback) {
+    NtnSignalStrengthCallback internalCallback = sNtnSignalStrengthCallbackWrapperMap.get(callback);
+    if (internalCallback != null) {
+      try {
+        mSatelliteManager.unregisterForNtnSignalStrengthChanged(internalCallback);
+      } catch (Exception ex) {
+        throw ex;
+      }
+    }
+  }
+
+  /**
+   * Wrapper API to provide a way to check if the subscription is exclusively for non-terrestrial
+   * networks.
+   *
+   * @param subId The unique SubscriptionInfo key in database.
+   * @return {@code true} if it is a non-terrestrial network subscription, {@code false}
+   * otherwise.
+   * Note: The method returns {@code false} if the parameter is invalid or any other error occurs.
+   */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public boolean isOnlyNonTerrestrialNetworkSubscription(int subId) {
+    List<SubscriptionInfo> subInfoList = mSubscriptionManager.getAvailableSubscriptionInfoList();
+
+    for (SubscriptionInfo subInfo : subInfoList) {
+      if (subInfo.getSubscriptionId() == subId) {
+        logd("found matched subscription info");
+        return subInfo.isOnlyNonTerrestrialNetwork();
+      }
+    }
+    logd("failed to found matched subscription info");
+    return false;
+  }
+
+  /**
+   * Wrapper API to register for satellite capabilities change event from the satellite service.
+   *
+   * @param executor The executor on which the callback will be called.
+   * @param callback The callback to handle the satellite capabilities changed event.
+   */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public int registerForCapabilitiesChanged(
+          @NonNull @CallbackExecutor Executor executor,
+          @NonNull SatelliteCapabilitiesCallbackWrapper callback) {
+    SatelliteCapabilitiesCallback internalCallback =
+            capabilities -> callback.onSatelliteCapabilitiesChanged(
+                    new SatelliteCapabilitiesWrapper(
+                            capabilities.getSupportedRadioTechnologies(),
+                            capabilities.isPointingRequired(),
+                            capabilities.getMaxBytesPerOutgoingDatagram(),
+                            transformToAntennaPositionWrapperMap(
+                                    capabilities.getAntennaPositionMap())));
+    sSatelliteCapabilitiesCallbackWrapperMap.put(callback, internalCallback);
+    return mSatelliteManager.registerForCapabilitiesChanged(executor, internalCallback);
+  }
+
+  /**
+   * Wrapper API to unregisters for satellite capabilities change event from the satellite service.
+   * If callback was not registered before, the request will be ignored.
+   *
+   * @param callback The callback that was passed to.
+   */
+  @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
+  public void unregisterForCapabilitiesChanged(
+          @NonNull SatelliteCapabilitiesCallbackWrapper callback) {
+    SatelliteCapabilitiesCallback internalCallback =
+            sSatelliteCapabilitiesCallbackWrapperMap.get(callback);
+    if (internalCallback != null) {
+      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/satellite_client/src/android/telephony/satellite/wrapper/SatelliteTransmissionUpdateCallbackWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteTransmissionUpdateCallbackWrapper.java
index c65f4f6..381b397 100644
--- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteTransmissionUpdateCallbackWrapper.java
+++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteTransmissionUpdateCallbackWrapper.java
@@ -40,7 +40,7 @@
   void onSendDatagramStateChanged(
       @SatelliteManagerWrapper.SatelliteDatagramTransferState int state,
       int sendPendingCount,
-      @SatelliteManagerWrapper.SatelliteError int errorCode);
+      @SatelliteManagerWrapper.SatelliteResult int errorCode);
 
   /**
    * Called when satellite datagram receive state changed.
@@ -52,5 +52,5 @@
   void onReceiveDatagramStateChanged(
       @SatelliteManagerWrapper.SatelliteDatagramTransferState int state,
       int receivePendingCount,
-      @SatelliteManagerWrapper.SatelliteError int errorCode);
+      @SatelliteManagerWrapper.SatelliteResult int errorCode);
 }
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.