Add deprovisionSatellite api

Bug: 368435815
Test: atest SatelliteControllerTest
Test: manual test with test apk b/368435815#comment2
Test: manual test -wrapper with test apk b/368435815#comment3
Flag: com.android.internal.telephony.flags.carrier_roaming_nb_iot_ntn

Change-Id: I6604b0fa80fcb07f9fc4435ffb70563b967d68e2
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index 4624884..ba7629d 100644
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -14424,6 +14424,26 @@
     }
 
     /**
+     * Deliver the list of deprovisioned satellite subscriber ids.
+     *
+     * @param list List of deprovisioned satellite subscriber ids.
+     * @param result The result receiver that returns whether deliver success or fail.
+     *
+     * @throws SecurityException if the caller doesn't have the required permission.
+     */
+    @Override
+    public void deprovisionSatellite(@NonNull List<SatelliteSubscriberInfo> list,
+            @NonNull ResultReceiver result) {
+        enforceSatelliteCommunicationPermission("deprovisionSatellite");
+        final long identity = Binder.clearCallingIdentity();
+        try {
+            mSatelliteController.deprovisionSatellite(list, result);
+        } finally {
+            Binder.restoreCallingIdentity(identity);
+        }
+    }
+
+    /**
      * This API can be used by only CTS to override the cached value for the device overlay config
      * value :
      * config_satellite_gateway_service_package and
diff --git a/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml b/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
index 151f6ca..f6bd44e 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_SatelliteControl.xml
@@ -138,6 +138,12 @@
             android:layout_height="wrap_content"
             android:paddingRight="4dp"
             android:text="@string/provisionSatellite"/>
+        <Button
+            android:id="@+id/deprovisionSatellite"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/deprovisionSatellite"/>
          <Button
             android:id="@+id/Back"
             android:onClick="Back"
diff --git a/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml b/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
index 39a4bd6..f8df900 100644
--- a/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
+++ b/testapps/TestSatelliteApp/res/layout/activity_TestSatelliteWrapper.xml
@@ -167,6 +167,24 @@
             android:layout_height="wrap_content"
             android:paddingRight="4dp"
             android:text="@string/unregisterForModemStateChanged"/>
+        <Button
+            android:id="@+id/requestSatelliteSubscriberProvisionStatusWrapper"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/requestSatelliteSubscriberProvisionStatus"/>
+        <Button
+            android:id="@+id/provisionSatelliteWrapper"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/provisionSatellite"/>
+        <Button
+            android:id="@+id/deprovisionSatelliteWrapper"
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            android:paddingRight="4dp"
+            android:text="@string/deprovisionSatellite"/>
         <LinearLayout
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
diff --git a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
index 728576a..ee19512 100644
--- a/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
+++ b/testapps/TestSatelliteApp/res/values/donottranslate_strings.xml
@@ -95,6 +95,7 @@
 
     <string name="requestSatelliteSubscriberProvisionStatus">requestSatelliteSubscriberProvisionStatus</string>
     <string name="provisionSatellite">provisionSatellite</string>
+    <string name="deprovisionSatellite">deprovisionSatellite</string>
 
     <string name="Back">Back</string>
     <string name="ClearLog">Clear Log</string>
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java
index 15c8fd8..08984be 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/Provisioning.java
@@ -24,12 +24,14 @@
 import android.os.OutcomeReceiver;
 import android.telephony.satellite.SatelliteManager;
 import android.telephony.satellite.SatelliteProvisionStateCallback;
+import android.telephony.satellite.SatelliteSubscriberProvisionStatus;
 import android.telephony.satellite.stub.SatelliteResult;
 import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.TextView;
 
+import java.util.List;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
@@ -82,6 +84,12 @@
             Log.d(TAG, "onSatelliteProvisionStateChanged in SatelliteTestApp: provisioned="
                     + mProvisioned);
         }
+
+        @Override
+        public void onSatelliteSubscriptionProvisionStateChanged(
+                List<SatelliteSubscriberProvisionStatus> list) {
+            Log.d(TAG, "onSatelliteSubscriptionProvisionStateChanged in SatelliteTestApp" + list);
+        }
     }
 
     private void provisionServiceApp(View view) {
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
index 379fc74..e079424 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/SatelliteControl.java
@@ -92,6 +92,8 @@
                 .setOnClickListener(this::requestSatelliteSubscriberProvisionStatusApp);
         findViewById(R.id.provisionSatellite)
                 .setOnClickListener(this::provisionSatelliteApp);
+        findViewById(R.id.deprovisionSatellite)
+                .setOnClickListener(this::deprovisionSatelliteApp);
         findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
             @Override
             public void onClick(View view) {
@@ -456,4 +458,36 @@
         }
         mSatelliteManager.provisionSatellite(list, Runnable::run, receiver);
     }
+
+    private void deprovisionSatelliteApp(View view) {
+        final AtomicReference<Boolean> enabled = new AtomicReference<>();
+        final AtomicReference<Integer> errorCode = new AtomicReference<>();
+        OutcomeReceiver<Boolean, SatelliteManager.SatelliteException> receiver =
+                new OutcomeReceiver<>() {
+                    @Override
+                    public void onResult(Boolean result) {
+                        enabled.set(result);
+                        TextView textView = findViewById(R.id.text_id);
+                        if (enabled.get()) {
+                            textView.setText("deprovisionSatellite is true");
+                        } else {
+                            textView.setText("Status for deprovisionSatellite result : "
+                                    + enabled.get());
+                        }
+                    }
+
+                    @Override
+                    public void onError(SatelliteManager.SatelliteException exception) {
+                        errorCode.set(exception.getErrorCode());
+                        TextView textView = findViewById(R.id.text_id);
+                        textView.setText("Status for deprovisionSatellite error : "
+                                + SatelliteErrorUtils.mapError(errorCode.get()));
+                    }
+                };
+        List<SatelliteSubscriberInfo> list = new ArrayList<>();
+        for (SatelliteSubscriberProvisionStatus status : mSatelliteSubscriberProvisionStatuses) {
+            list.add(status.getSatelliteSubscriberInfo());
+        }
+        mSatelliteManager.deprovisionSatellite(list, Runnable::run, receiver);
+    }
 }
diff --git a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
index d8e6e7c..97cb9c3 100644
--- a/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
+++ b/testapps/TestSatelliteApp/src/com/android/phone/testapps/satellitetestapp/TestSatelliteWrapper.java
@@ -30,6 +30,8 @@
 import android.telephony.satellite.wrapper.SatelliteCommunicationAllowedStateCallbackWrapper;
 import android.telephony.satellite.wrapper.SatelliteManagerWrapper;
 import android.telephony.satellite.wrapper.SatelliteModemStateCallbackWrapper2;
+import android.telephony.satellite.wrapper.SatelliteSubscriberInfoWrapper;
+import android.telephony.satellite.wrapper.SatelliteSubscriberProvisionStatusWrapper;
 import android.util.Log;
 import android.view.View;
 import android.view.View.OnClickListener;
@@ -62,6 +64,8 @@
     private SatelliteCapabilitiesCallbackWrapper mSatelliteCapabilitiesCallback;
     private SubscriptionManager mSubscriptionManager;
     private int mSubId;
+    private List<SatelliteSubscriberProvisionStatusWrapper> mSatelliteSubscriberProvisionStatuses =
+            new ArrayList<>();
 
     private ListView mLogListView;
 
@@ -117,6 +121,12 @@
                 .setOnClickListener(this::registerForModemStateChanged);
         findViewById(R.id.unregisterForModemStateChanged)
                 .setOnClickListener(this::unregisterForModemStateChanged);
+        findViewById(R.id.requestSatelliteSubscriberProvisionStatusWrapper)
+                .setOnClickListener(this::requestSatelliteSubscriberProvisionStatus);
+        findViewById(R.id.provisionSatelliteWrapper)
+                .setOnClickListener(this::provisionSatellite);
+        findViewById(R.id.deprovisionSatelliteWrapper)
+                .setOnClickListener(this::deprovisionSatellite);
 
         findViewById(R.id.Back).setOnClickListener(new OnClickListener() {
             @Override
@@ -389,7 +399,137 @@
         }
     }
 
+    private void requestSatelliteSubscriberProvisionStatus(View view) {
+        addLogMessage("requestSatelliteSubscriberProvisionStatus");
+        logd("requestSatelliteSubscriberProvisionStatus");
 
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("requestSatelliteSubscriberProvisionStatus: Subscription ID is invalid");
+            logd("requestSatelliteSubscriberProvisionStatus: Subscription ID is invalid");
+            return;
+        }
+
+        OutcomeReceiver<List<SatelliteSubscriberProvisionStatusWrapper>,
+                SatelliteManagerWrapper.SatelliteExceptionWrapper> receiver =
+                new OutcomeReceiver<>() {
+                    @Override
+                    public void onResult(List<SatelliteSubscriberProvisionStatusWrapper> result) {
+                        mSatelliteSubscriberProvisionStatuses = result;
+                        logd("requestSatelliteSubscriberProvisionStatus: onResult=" + result);
+                        addLogMessage(
+                                "requestSatelliteSubscriberProvisionStatus: onResult=" + result);
+                    }
+
+                    @Override
+                    public void onError(
+                            SatelliteManagerWrapper.SatelliteExceptionWrapper exception) {
+                        if (exception != null) {
+                            String onError = "requestSatelliteSubscriberProvisionStatus exception: "
+                                    + translateResultCodeToString(exception.getErrorCode());
+                            logd(onError);
+                            addLogMessage(onError);
+                        }
+                    }
+                };
+
+        try {
+            mSatelliteManagerWrapper.requestSatelliteSubscriberProvisionStatus(mExecutor, receiver);
+        } catch (SecurityException | IllegalArgumentException ex) {
+            String errorMessage = "requestSatelliteSubscriberProvisionStatus: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
+
+    private void provisionSatellite(View view) {
+        addLogMessage("provisionSatellite");
+        logd("provisionSatellite");
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("provisionSatellite: Subscription ID is invalid");
+            logd("provisionSatellite: Subscription ID is invalid");
+            return;
+        }
+
+        OutcomeReceiver<Boolean,
+                SatelliteManagerWrapper.SatelliteExceptionWrapper> receiver =
+                new OutcomeReceiver<>() {
+                    @Override
+                    public void onResult(Boolean result) {
+                        logd("provisionSatellite: onResult=" + result);
+                        addLogMessage("provisionSatellite: onResult=" + result);
+                    }
+
+                    @Override
+                    public void onError(
+                            SatelliteManagerWrapper.SatelliteExceptionWrapper exception) {
+                        if (exception != null) {
+                            String onError = "provisionSatellite exception: "
+                                    + translateResultCodeToString(exception.getErrorCode());
+                            logd(onError);
+                            addLogMessage(onError);
+                        }
+                    }
+                };
+
+        List<SatelliteSubscriberInfoWrapper> list = new ArrayList<>();
+        for (SatelliteSubscriberProvisionStatusWrapper status :
+                mSatelliteSubscriberProvisionStatuses) {
+            list.add(status.getSatelliteSubscriberInfo());
+        }
+        try {
+            mSatelliteManagerWrapper.provisionSatellite(list, mExecutor, receiver);
+        } catch (SecurityException | IllegalArgumentException ex) {
+            String errorMessage = "provisionSatellite: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
+
+    private void deprovisionSatellite(View view) {
+        addLogMessage("deprovisionSatellite");
+        logd("deprovisionSatellite");
+
+        if (mSubId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
+            addLogMessage("deprovisionSatellite: Subscription ID is invalid");
+            logd("deprovisionSatellite: Subscription ID is invalid");
+            return;
+        }
+
+        OutcomeReceiver<Boolean,
+                SatelliteManagerWrapper.SatelliteExceptionWrapper> receiver =
+                new OutcomeReceiver<>() {
+                    @Override
+                    public void onResult(Boolean result) {
+                        logd("deprovisionSatellite: onResult=" + result);
+                        addLogMessage("deprovisionSatellite: onResult=" + result);
+                    }
+
+                    @Override
+                    public void onError(
+                            SatelliteManagerWrapper.SatelliteExceptionWrapper exception) {
+                        if (exception != null) {
+                            String onError = "deprovisionSatellite exception: "
+                                    + translateResultCodeToString(exception.getErrorCode());
+                            logd(onError);
+                            addLogMessage(onError);
+                        }
+                    }
+                };
+
+        List<SatelliteSubscriberInfoWrapper> list = new ArrayList<>();
+        for (SatelliteSubscriberProvisionStatusWrapper status :
+                mSatelliteSubscriberProvisionStatuses) {
+            list.add(status.getSatelliteSubscriberInfo());
+        }
+        try {
+            mSatelliteManagerWrapper.deprovisionSatellite(list, mExecutor, receiver);
+        } catch (SecurityException | IllegalArgumentException ex) {
+            String errorMessage = "deprovisionSatellite: " + ex.getMessage();
+            logd(errorMessage);
+            addLogMessage(errorMessage);
+        }
+    }
 
     public class NtnSignalStrengthCallback implements NtnSignalStrengthCallbackWrapper {
         @Override