[automerger skipped] Merge 24Q4 (ab/12406339) into aosp-main-future am: ae39266591 -s ours

am skip reason: Merged-In I1b0cc247f6024dc85724eb07a0dbcc6527d77181 with SHA-1 dcc28bd02c is already in history

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/libs/gsma_services/+/30284515

Change-Id: I5603c19bc4f2c27da2aa7eabe4811371b41bd067
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCommunicationAllowedStateCallbackWrapper2.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCommunicationAllowedStateCallbackWrapper2.java
new file mode 100644
index 0000000..86785e3
--- /dev/null
+++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteCommunicationAllowedStateCallbackWrapper2.java
@@ -0,0 +1,48 @@
+/*
+ * 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 android.telephony.satellite.wrapper;
+
+import android.annotation.Nullable;
+import android.telephony.satellite.SatelliteAccessConfiguration;
+
+/** A callback class for monitoring satellite communication allowed state change events. */
+public interface SatelliteCommunicationAllowedStateCallbackWrapper2 {
+    /**
+     * Telephony does not guarantee that whenever there is a change in communication allowed state,
+     * this API will be called. Telephony does its best to detect the changes and notify its
+     * listeners accordingly.
+     *
+     * @param isAllowed {@code true} means satellite allow state is changed,
+     *                  {@code false} satellite allow state is not changed
+     */
+    void onSatelliteCommunicationAllowedStateChanged(boolean isAllowed);
+
+    /**
+     * Callback method invoked when the satellite access configuration changes
+     *
+     * @param satelliteAccessConfiguration The satellite access configuration associated with
+     *                                     the current location. When satellite is not allowed at
+     *                                     the current location,
+     *                                     {@code satelliteAccessConfiguration} will be null.
+     * @hide
+     */
+    default void onSatelliteAccessConfigurationChanged(
+            @Nullable SatelliteAccessConfiguration satelliteAccessConfiguration) {
+    }
+
+    ;
+}
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
index e4f38f9..7b3feb0 100644
--- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
+++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteManagerWrapper.java
@@ -26,6 +26,7 @@
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.content.Context;
+import android.os.Binder;
 import android.os.CancellationSignal;
 import android.os.OutcomeReceiver;
 import android.telephony.NetworkRegistrationInfo;
@@ -39,6 +40,7 @@
 import android.telephony.satellite.NtnSignalStrength;
 import android.telephony.satellite.NtnSignalStrengthCallback;
 import android.telephony.satellite.PointingInfo;
+import android.telephony.satellite.SatelliteAccessConfiguration;
 import android.telephony.satellite.SatelliteCapabilities;
 import android.telephony.satellite.SatelliteCapabilitiesCallback;
 import android.telephony.satellite.SatelliteCommunicationAllowedStateCallback;
@@ -61,6 +63,8 @@
 import java.lang.reflect.Method;
 import java.time.Duration;
 import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
@@ -126,6 +130,10 @@
           SatelliteCommunicationAllowedStateCallback>
           sSatelliteCommunicationAllowedStateCallbackWrapperMap = new ConcurrentHashMap<>();
 
+    private static final ConcurrentHashMap<SatelliteCommunicationAllowedStateCallbackWrapper2,
+            SatelliteCommunicationAllowedStateCallback>
+            sSatelliteCommunicationAllowedStateCallbackWrapperMap2 = new ConcurrentHashMap<>();
+
   private final SatelliteManager mSatelliteManager;
   private final SubscriptionManager mSubscriptionManager;
   private final TelephonyManager mTelephonyManager;
@@ -174,6 +182,12 @@
    * Datagram type indicating that the message to be sent or received is of type SMS.
    */
   public static final int DATAGRAM_TYPE_SMS = 6;
+  /**
+   * Datagram type indicating that the message to be sent is an SMS checking
+   * for pending incoming SMS.
+   * @hide
+   */
+    public static final int DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS = 7;
 
   /** @hide */
   @IntDef(
@@ -185,7 +199,8 @@
               DATAGRAM_TYPE_KEEP_ALIVE,
               DATAGRAM_TYPE_LAST_SOS_MESSAGE_STILL_NEED_HELP,
               DATAGRAM_TYPE_LAST_SOS_MESSAGE_NO_HELP_NEEDED,
-              DATAGRAM_TYPE_SMS
+              DATAGRAM_TYPE_SMS,
+              DATAGRAM_TYPE_CHECK_PENDING_INCOMING_SMS
       })
   @Retention(RetentionPolicy.SOURCE)
   public @interface DatagramType {}
@@ -549,6 +564,13 @@
       boolean isEmergency,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("requestEnabled: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     mSatelliteManager.requestEnabled(new EnableRequestAttributes.Builder(enableSatellite)
             .setDemoMode(enableDemoMode)
             .setEmergencyMode(isEmergency)
@@ -559,6 +581,14 @@
   public void requestIsEnabled(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestIsEnabled: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
         new OutcomeReceiver<Boolean, SatelliteException>() {
           @Override
@@ -578,6 +608,14 @@
   public void requestIsDemoModeEnabled(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestIsDemoModeEnabled: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
         new OutcomeReceiver<Boolean, SatelliteException>() {
           @Override
@@ -597,6 +635,14 @@
   public void requestIsEmergencyModeEnabled(
           @NonNull @CallbackExecutor Executor executor,
           @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestIsEmergencyModeEnabled: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
         new OutcomeReceiver<Boolean, SatelliteException>() {
           @Override
@@ -616,6 +662,12 @@
   public void requestIsSupported(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestIsSupported: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onResult(false)));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
         new OutcomeReceiver<Boolean, SatelliteException>() {
           @Override
@@ -635,6 +687,14 @@
   public void requestCapabilities(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<SatelliteCapabilitiesWrapper, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestCapabilities: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
         new OutcomeReceiver<SatelliteCapabilities, SatelliteException>() {
           @Override
@@ -667,6 +727,12 @@
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener,
       @NonNull SatelliteTransmissionUpdateCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("startTransmissionUpdates: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
 
     SatelliteTransmissionUpdateCallback internalCallback =
         new SatelliteTransmissionUpdateCallback() {
@@ -721,6 +787,12 @@
           @NonNull @CallbackExecutor Executor executor,
           @SatelliteResult @NonNull Consumer<Integer> resultListener,
           @NonNull SatelliteTransmissionUpdateCallbackWrapper2 callback) {
+    if (mSatelliteManager == null) {
+      logd("startTransmissionUpdates2: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
 
     SatelliteTransmissionUpdateCallback internalCallback =
             new SatelliteTransmissionUpdateCallback() {
@@ -779,6 +851,13 @@
       @NonNull SatelliteTransmissionUpdateCallbackWrapper callback,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("stopTransmissionUpdates: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     SatelliteTransmissionUpdateCallback internalCallback =
         sSatelliteTransmissionUpdateCallbackWrapperMap.remove(callback);
     if (internalCallback != null) {
@@ -797,6 +876,13 @@
           @NonNull SatelliteTransmissionUpdateCallbackWrapper2 callback,
           @NonNull @CallbackExecutor Executor executor,
           @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("stopTransmissionUpdates2: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     SatelliteTransmissionUpdateCallback internalCallback =
             sSatelliteTransmissionUpdateCallbackWrapperMap2.remove(callback);
     if (internalCallback != null) {
@@ -815,6 +901,13 @@
       @Nullable CancellationSignal cancellationSignal,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("provisionService: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     mSatelliteManager.provisionService(
         token, provisionData, cancellationSignal, executor, resultListener);
   }
@@ -829,6 +922,13 @@
       @NonNull String token,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("deprovisionService: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     mSatelliteManager.deprovisionService(token, executor, resultListener);
   }
 
@@ -837,6 +937,11 @@
   public int registerForProvisionStateChanged(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull SatelliteProvisionStateCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("registerForProvisionStateChanged: mSatelliteManager is null");
+      return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+    }
+
     SatelliteProvisionStateCallback internalCallback =
         new SatelliteProvisionStateCallback() {
           @Override
@@ -863,6 +968,11 @@
    */
   public void unregisterForProvisionStateChanged(
       @NonNull SatelliteProvisionStateCallbackWrapper callback) {
+    if (mSatelliteManager == null){
+      logd("unregisterForProvisionStateChanged: mSatelliteManager is null");
+      return;
+    }
+
     SatelliteProvisionStateCallback internalCallback =
         sSatelliteProvisionStateCallbackWrapperMap.remove(callback);
     if (internalCallback != null) {
@@ -874,6 +984,14 @@
   public void requestIsProvisioned(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestIsProvisioned: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
         new OutcomeReceiver<Boolean, SatelliteException>() {
           @Override
@@ -894,6 +1012,11 @@
   public int registerForModemStateChanged(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull SatelliteModemStateCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("registerForModemStateChanged: mSatelliteManager is null");
+      return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+    }
+
     SatelliteModemStateCallback internalCallback =
         new SatelliteModemStateCallback() {
           public void onSatelliteModemStateChanged(@SatelliteModemState int state) {
@@ -912,6 +1035,11 @@
   public int registerForModemStateChanged(
           @NonNull @CallbackExecutor Executor executor,
           @NonNull SatelliteModemStateCallbackWrapper2 callback) {
+    if (mSatelliteManager == null) {
+      logd("registerForModemStateChanged: mSatelliteManager is null");
+      return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+    }
+
     SatelliteModemStateCallback internalCallback =
             new SatelliteModemStateCallback() {
               public void onSatelliteModemStateChanged(@SatelliteModemState int state) {
@@ -925,6 +1053,10 @@
               public void onRegistrationFailure(int causeCode) {
                 callback.onRegistrationFailure(causeCode);
               }
+
+              public void onTerrestrialNetworkAvailableChanged(boolean isAvailable) {
+                callback.onTerrestrialNetworkAvailableChanged(isAvailable);
+              }
             };
     sSatelliteModemStateCallbackWrapperMap2.put(callback, internalCallback);
 
@@ -939,6 +1071,11 @@
    */
   public void unregisterForModemStateChanged(
       @NonNull SatelliteModemStateCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("unregisterForModemStateChanged: mSatelliteManager is null");
+      return;
+    }
+
     SatelliteModemStateCallback internalCallback = sSatelliteModemStateCallbackWrapperMap.remove(
             callback);
     if (internalCallback != null) {
@@ -952,6 +1089,11 @@
    */
   public void unregisterForModemStateChanged(
           @NonNull SatelliteModemStateCallbackWrapper2 callback) {
+    if (mSatelliteManager == null) {
+      logd("unregisterForModemStateChanged: mSatelliteManager is null");
+      return;
+    }
+
     SatelliteModemStateCallback internalCallback = sSatelliteModemStateCallbackWrapperMap2.remove(
             callback);
     if (internalCallback != null) {
@@ -964,6 +1106,11 @@
   public int registerForIncomingDatagram(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull SatelliteDatagramCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("registerForIncomingDatagram: mSatelliteManager is null");
+      return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+    }
+
     SatelliteDatagramCallback internalCallback =
         new SatelliteDatagramCallback() {
           @Override
@@ -989,6 +1136,11 @@
    * before, the request will be ignored.
    */
   public void unregisterForIncomingDatagram(@NonNull SatelliteDatagramCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("unregisterForIncomingDatagram: mSatelliteManager is null");
+      return;
+    }
+
     SatelliteDatagramCallback internalCallback =
             sSatelliteDatagramCallbackWrapperMap.remove(callback);
     if (internalCallback != null) {
@@ -1029,6 +1181,13 @@
         mListenerWrapper2.onCarrierRoamingNtnEligibleStateChanged(eligible);
       }
     }
+
+    @Override
+    public void onCarrierRoamingNtnAvailableServicesChanged(
+            @NetworkRegistrationInfo.ServiceType List<Integer> availableServices) {
+      logd("onCarrierRoamingNtnAvailableServicesChanged: availableServices="
+              + availableServices.stream().map(String::valueOf).collect(Collectors.joining(", ")));
+    }
   }
 
   /** Register for carrier roaming non-terrestrial network mode changes. */
@@ -1082,6 +1241,13 @@
   public void pollPendingDatagrams(
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("pollPendingDatagrams: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     mSatelliteManager.pollPendingDatagrams(executor, resultListener);
   }
 
@@ -1098,6 +1264,13 @@
       boolean needFullScreenPointingUI,
       @NonNull @CallbackExecutor Executor executor,
       @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("sendDatagram: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     SatelliteDatagram datagramInternal = new SatelliteDatagram(datagram.getSatelliteDatagram());
     mSatelliteManager.sendDatagram(
         datagramType, datagramInternal, needFullScreenPointingUI, executor, resultListener);
@@ -1107,6 +1280,14 @@
   public void requestIsCommunicationAllowedForCurrentLocation(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestIsCommunicationAllowedForCurrentLocation: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
         new OutcomeReceiver<Boolean, SatelliteException>() {
           @Override
@@ -1123,6 +1304,34 @@
         executor, internalCallback);
   }
 
+  /** Request to get satellite configuration for the current location. */
+  public void requestSatelliteConfigurationForCurrentLocation(
+          @NonNull @CallbackExecutor Executor executor,
+          @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestSatelliteConfigurationForCurrentLocation: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
+    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.requestSatelliteAccessConfigurationForCurrentLocation(executor,
+            internalCallback);
+  }
+
   /**
    * Request to get the duration in seconds after which the satellite will be visible. This will be
    * {@link Duration#ZERO} if the satellite is currently visible.
@@ -1130,6 +1339,14 @@
   public void requestTimeForNextSatelliteVisibility(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<Duration, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestTimeForNextSatelliteVisibility: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
         new OutcomeReceiver<Duration, SatelliteException>() {
           @Override
@@ -1149,6 +1366,11 @@
    * Inform whether the device is aligned with the satellite for demo mode.
    */
   public void setDeviceAlignedWithSatellite(boolean isAligned) {
+    if (mSatelliteManager == null) {
+      logd("setDeviceAlignedWithSatellite: mSatelliteManager is null");
+      return;
+    }
+
     mSatelliteManager.setDeviceAlignedWithSatellite(isAligned);
   }
 
@@ -1177,6 +1399,14 @@
   public void requestNtnSignalStrength(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull OutcomeReceiver<NtnSignalStrengthWrapper, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestNtnSignalStrength: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
             new OutcomeReceiver<NtnSignalStrength, SatelliteException>() {
               @Override
@@ -1197,6 +1427,11 @@
   public void registerForNtnSignalStrengthChanged(
       @NonNull @CallbackExecutor Executor executor,
       @NonNull NtnSignalStrengthCallbackWrapper callback) {
+    if (mSatelliteManager == null){
+      logd("registerForNtnSignalStrengthChanged: mSatelliteManager is null");
+      return;
+    }
+
     NtnSignalStrengthCallback internalCallback =
         new NtnSignalStrengthCallback() {
           @Override
@@ -1216,6 +1451,11 @@
   @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
   public void unregisterForNtnSignalStrengthChanged(
       @NonNull NtnSignalStrengthCallbackWrapper callback) {
+    if (mSatelliteManager == null){
+      logd("unregisterForNtnSignalStrengthChanged: mSatelliteManager is null");
+      return;
+    }
+
     NtnSignalStrengthCallback internalCallback =
             sNtnSignalStrengthCallbackWrapperMap.remove(callback);
     if (internalCallback != null) {
@@ -1260,6 +1500,11 @@
   public int registerForCapabilitiesChanged(
           @NonNull @CallbackExecutor Executor executor,
           @NonNull SatelliteCapabilitiesCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("requestForCapabilitiesChanged: mSatelliteManager is null");
+      return SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+    }
+
     SatelliteCapabilitiesCallback internalCallback =
             capabilities -> callback.onSatelliteCapabilitiesChanged(
                     new SatelliteCapabilitiesWrapper(
@@ -1281,6 +1526,11 @@
   @FlaggedApi(Flags.FLAG_OEM_ENABLED_SATELLITE_FLAG)
   public void unregisterForCapabilitiesChanged(
           @NonNull SatelliteCapabilitiesCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("unregisterForCapabilitiesChanged: mSatelliteManager is null");
+      return;
+    }
+
     SatelliteCapabilitiesCallback internalCallback =
             sSatelliteCapabilitiesCallbackWrapperMap.remove(callback);
     if (internalCallback != null) {
@@ -1394,6 +1644,13 @@
   public void requestAttachEnabledForCarrier(int subId, boolean enableSatellite,
           @NonNull @CallbackExecutor Executor executor,
           @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("requestAttachEnabledForCarrier: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     mSatelliteManager.requestAttachEnabledForCarrier(subId, enableSatellite, executor,
             resultListener);
   }
@@ -1419,6 +1676,14 @@
   public void requestIsAttachEnabledForCarrier(int subId,
           @NonNull @CallbackExecutor Executor executor,
           @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestIsAttachEnabledForCarrier: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
             new OutcomeReceiver<Boolean, SatelliteException>() {
               @Override
@@ -1451,6 +1716,13 @@
           @SatelliteCommunicationRestrictionReason int reason,
           @NonNull @CallbackExecutor Executor executor,
           @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("addAttachRestrictionForCarrier: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     mSatelliteManager.addAttachRestrictionForCarrier(subId, reason, executor, resultListener);
   }
 
@@ -1471,6 +1743,13 @@
           @SatelliteCommunicationRestrictionReason int reason,
           @NonNull @CallbackExecutor Executor executor,
           @SatelliteResult @NonNull Consumer<Integer> resultListener) {
+    if (mSatelliteManager == null) {
+      logd("removeAttachRestrictionForCarrier: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> resultListener.accept(
+              SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED)));
+      return;
+    }
+
     mSatelliteManager.removeAttachRestrictionForCarrier(subId, reason, executor, resultListener);
   }
 
@@ -1487,6 +1766,11 @@
    */
   @SatelliteCommunicationRestrictionReason
   @NonNull public Set<Integer> getAttachRestrictionReasonsForCarrier(int subId) {
+    if (mSatelliteManager == null) {
+      logd("getAttachRestrictionReasonsForCarrier: mSatelliteManager is null");
+      return Collections.emptySet();
+    }
+
     return mSatelliteManager.getAttachRestrictionReasonsForCarrier(subId);
   }
 
@@ -1499,6 +1783,11 @@
    * be returned.
    */
   @NonNull public List<String> getSatellitePlmnsForCarrier(int subId) {
+    if (mSatelliteManager == null) {
+      logd("getSatellitePlmnsForCarrier: mSatelliteManager is null");
+      return new ArrayList<>();
+    }
+
     return mSatelliteManager.getSatellitePlmnsForCarrier(subId);
   }
 
@@ -1507,6 +1796,11 @@
   public int registerForSupportedStateChanged(
           @NonNull @CallbackExecutor Executor executor,
           @NonNull SatelliteSupportedStateCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("registerForSupportedStateChanged: mSatelliteManager is null");
+      return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+    }
+
     SatelliteSupportedStateCallback internalCallback =
             new SatelliteSupportedStateCallback() {
               @Override
@@ -1525,6 +1819,14 @@
           @NonNull @CallbackExecutor Executor executor,
           @NonNull OutcomeReceiver<SatelliteSessionStatsWrapper,
                   SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestSessionStats: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
             new OutcomeReceiver<SatelliteSessionStats, SatelliteException>() {
               @Override
@@ -1558,6 +1860,11 @@
    */
   public void unregisterForSupportedStateChanged(
           @NonNull SatelliteSupportedStateCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("unregisterForSupportedStateChanged: mSatelliteManager is null");
+      return;
+    }
+
     SatelliteSupportedStateCallback internalCallback =
             sSatelliteSupportedStateCallbackWrapperMap.remove(callback);
     if (internalCallback != null) {
@@ -1570,6 +1877,11 @@
   public int registerForCommunicationAllowedStateChanged(
           @NonNull @CallbackExecutor Executor executor,
           @NonNull SatelliteCommunicationAllowedStateCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("requestForCommunicationAllowedStateChanged: mSatelliteManager is null");
+      return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+    }
+
     SatelliteCommunicationAllowedStateCallback internalCallback =
             new SatelliteCommunicationAllowedStateCallback() {
               @Override
@@ -1583,12 +1895,46 @@
     return result;
   }
 
+  /** Registers for the satellite communication allowed state changed. */
+  @SatelliteResult
+  public int registerForCommunicationAllowedStateChanged2(
+          @NonNull @CallbackExecutor Executor executor,
+          @NonNull SatelliteCommunicationAllowedStateCallbackWrapper2 callback) {
+    if (mSatelliteManager == null) {
+      logd("registerForCommunicationAllowedStateChanged2: mSatelliteManager is null");
+      return SatelliteManagerWrapper.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED;
+    }
+
+    SatelliteCommunicationAllowedStateCallback internalCallback =
+            new SatelliteCommunicationAllowedStateCallback() {
+              @Override
+              public void onSatelliteCommunicationAllowedStateChanged(boolean supported) {
+                callback.onSatelliteCommunicationAllowedStateChanged(supported);
+              }
+
+              @Override
+              public void onSatelliteAccessConfigurationChanged(SatelliteAccessConfiguration
+                      satelliteAccessConfiguration) {
+                callback.onSatelliteAccessConfigurationChanged(satelliteAccessConfiguration);
+              }
+            };
+    sSatelliteCommunicationAllowedStateCallbackWrapperMap2.put(callback, internalCallback);
+    int result = mSatelliteManager.registerForCommunicationAllowedStateChanged(executor,
+            internalCallback);
+    return result;
+  }
+
   /**
    * Unregisters for the satellite communication allowed state changed. If callback was not
    * registered before, the request will be ignored.
    */
   public void unregisterForCommunicationAllowedStateChanged(
           @NonNull SatelliteCommunicationAllowedStateCallbackWrapper callback) {
+    if (mSatelliteManager == null) {
+      logd("unregisterForCommunicationAllowedStateChanged: mSatelliteManager is null");
+      return;
+    }
+
     SatelliteCommunicationAllowedStateCallback internalCallback =
             sSatelliteCommunicationAllowedStateCallbackWrapperMap.remove(callback);
     if (internalCallback != null) {
@@ -1636,6 +1982,14 @@
           @NonNull @CallbackExecutor Executor executor,
           @NonNull OutcomeReceiver<List<SatelliteSubscriberProvisionStatusWrapper>,
                   SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("requestSatelliteSubscriberProvisionStatus: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     Objects.requireNonNull(executor);
     Objects.requireNonNull(callback);
 
@@ -1665,6 +2019,14 @@
   public void provisionSatellite(@NonNull List<SatelliteSubscriberInfoWrapper> list,
           @NonNull @CallbackExecutor Executor executor,
           @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("provisionSatellite: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
     OutcomeReceiver internalCallback =
             new OutcomeReceiver<Boolean, SatelliteException>() {
               @Override
@@ -1707,6 +2069,11 @@
   }
 
   public boolean isSatelliteSubscriberIdSupported() {
+    if (mSatelliteManager == null) {
+      logd("isSatelliteSubscriberIdSupported: mSatelliteManager is null");
+      return false;
+    }
+
     try {
       final String methodName = "requestSatelliteSubscriberProvisionStatus";
       Method method = mSatelliteManager.getClass().getMethod(methodName, Executor.class,
@@ -1717,6 +2084,63 @@
     }
   }
 
+  /**
+   * Deliver the list of deprovisioned satellite subscriber ids.
+   *
+   * @param list List of deprovisioned SatelliteSubscriberInfo.
+   * @param executor The executor on which the callback will be called.
+   * @param callback The callback object to which the result will be delivered.
+   */
+  @FlaggedApi(Flags.FLAG_CARRIER_ROAMING_NB_IOT_NTN)
+  public void deprovisionSatellite(@NonNull List<SatelliteSubscriberInfoWrapper> list,
+          @NonNull @CallbackExecutor Executor executor,
+          @NonNull OutcomeReceiver<Boolean, SatelliteExceptionWrapper> callback) {
+    if (mSatelliteManager == null) {
+      logd("deprovisionSatellite: mSatelliteManager is null");
+      executor.execute(() -> Binder.withCleanCallingIdentity(() -> callback.onError(
+              new SatelliteExceptionWrapper(
+                      SatelliteManager.SATELLITE_RESULT_REQUEST_NOT_SUPPORTED))));
+      return;
+    }
+
+    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.deprovisionSatellite(list.stream()
+            .map(info -> new SatelliteSubscriberInfo.Builder()
+                    .setSubscriberId(info.getSubscriberId())
+                    .setCarrierId(info.getCarrierId()).setNiddApn(info.getNiddApn())
+                    .setSubId(info.getSubId()).setSubscriberIdType(info.getSubscriberIdType())
+                    .build())
+            .collect(Collectors.toList()), executor, internalCallback);
+  }
+
+  /**
+   * Inform whether application supports NTN SMS in satellite mode.
+   *
+   * This method is used by default messaging application to inform framework whether it supports
+   * NTN SMS or not.
+   *
+   * @param ntnSmsSupported {@code true} If application supports NTN SMS, else {@code false}.
+   */
+  public void setNtnSmsSupported(boolean ntnSmsSupported) {
+    if (mSatelliteManager == null) {
+      logd("setNtnSmsSupported: mSatelliteManager is null");
+      return;
+    }
+
+    mSatelliteManager.setNtnSmsSupported(ntnSmsSupported);
+  }
+
   @Nullable
   private ServiceState getServiceStateForSubscriptionId(int subId) {
     if (!mSubscriptionManager.isValidSubscriptionId(subId)) {
diff --git a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper2.java b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper2.java
index 054167b..ea01f8b 100644
--- a/satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper2.java
+++ b/satellite_client/src/android/telephony/satellite/wrapper/SatelliteModemStateCallbackWrapper2.java
@@ -40,4 +40,11 @@
    *        For LTE (EMM), cause codes are TS 24.301 Sec 9.9.3.9
    */
   default void onRegistrationFailure(int causeCode) {};
+
+  /**
+   * Indicates that the background search for terrestrial network is finished with result
+   *
+   * @param isAvailable True means there's terrestrial network and false means there's not.
+   */
+  default void onTerrestrialNetworkAvailableChanged(boolean isAvailable) {};
 }