[MEP] adding exceptions to iccCloseLogicalSlot to sim access APIs

Updated exceptions iccCloseLogicalSlot to sim access APIs
Test: atest TelephonyManagerTest#testIccOpenLogicalChannelBySlotAndPort
Test: atest TelephonyManagerTest#testIccCloseLogicalChannelBySlotAndPort
Test: atest
TelephonyManagerTest#testIccTransmitApduLogicalChannelBySlotAndPort
Test: atest
TelephonyManagerTest#testIccTransmitApduBasicChannelBySlotAndPort
Bug: 208739934

Change-Id: I1310b4fd98839394ee819beabf8e62f9956b1448
diff --git a/src/com/android/phone/PhoneInterfaceManager.java b/src/com/android/phone/PhoneInterfaceManager.java
index abbdbdb..07d2c6d 100755
--- a/src/com/android/phone/PhoneInterfaceManager.java
+++ b/src/com/android/phone/PhoneInterfaceManager.java
@@ -33,6 +33,7 @@
 import android.app.PendingIntent;
 import android.app.compat.CompatChanges;
 import android.app.role.RoleManager;
+import android.compat.Compatibility;
 import android.compat.annotation.ChangeId;
 import android.compat.annotation.EnabledSince;
 import android.content.ComponentName;
@@ -411,6 +412,7 @@
             "reset_network_erase_modem_config_enabled";
 
     private static final int SET_NETWORK_SELECTION_MODE_AUTOMATIC_TIMEOUT_MS = 2000; // 2 seconds
+
     /**
      * With support for MEP(multiple enabled profile) in Android T, a SIM card can have more than
      * one ICCID active at the same time.
@@ -423,6 +425,14 @@
     public static final long GET_API_SIGNATURES_FROM_UICC_PORT_INFO = 202110963L;
 
     /**
+     * Apps targeting on Android T and beyond will get exception whenever icc close channel
+     * operation fails.
+     */
+    @ChangeId
+    @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+    public static final long ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE = 208739934L;
+
+    /**
      * A request object to use for transmitting data to an ICC.
      */
     private static final class IccAPDUArgument {
@@ -767,8 +777,7 @@
                     uiccPort = getUiccPortFromRequest(request);
                     if (uiccPort == null) {
                         loge("iccCloseLogicalChannel: No UICC");
-                        request.result = false;
-                        notifyRequester(request);
+                        throw new IllegalArgumentException("iccCloseLogicalChannel: No UICC");
                     } else {
                         onCompleted = obtainMessage(EVENT_CLOSE_CHANNEL_DONE, request);
                         uiccPort.iccCloseLogicalChannel((Integer) request.argument, onCompleted);
@@ -776,7 +785,34 @@
                     break;
 
                 case EVENT_CLOSE_CHANNEL_DONE:
-                    handleNullReturnEvent(msg, "iccCloseLogicalChannel");
+                    ar = (AsyncResult) msg.obj;
+                    request = (MainThreadRequest) ar.userObj;
+                    if (ar.exception == null) {
+                        request.result = true;
+                    } else {
+                        request.result = false;
+                        if (ar.exception instanceof CommandException) {
+                            loge("iccCloseLogicalChannel: CommandException: " + ar.exception);
+                            CommandException.Error error =
+                                    ((CommandException) (ar.exception)).getCommandError();
+                            // before this feature is enabled, this API should only return false if
+                            // the operation fails instead of throwing runtime exception for
+                            // backward-compatibility.
+                            if (Compatibility.isChangeEnabled(
+                                    ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE)
+                                    && error == CommandException.Error.INVALID_ARGUMENTS) {
+                                throw new IllegalArgumentException(
+                                        "iccCloseLogicalChannel: invalid argument ");
+                            }
+                        } else {
+                            loge("iccCloseLogicalChannel: Unknown exception");
+                        }
+                        if (Compatibility.isChangeEnabled(ICC_CLOSE_CHANNEL_EXCEPTION_ON_FAILURE)) {
+                            throw new IllegalStateException(
+                                    "exception from modem to close iccLogical Channel");
+                        }
+                    }
+                    notifyRequester(request);
                     break;
 
                 case CMD_NV_READ_ITEM:
@@ -5330,7 +5366,7 @@
         final long identity = Binder.clearCallingIdentity();
         try {
             if (request.channel < 0) {
-                return false;
+                throw new IllegalArgumentException("request.channel is less than 0");
             }
             Boolean success = (Boolean) sendRequest(CMD_CLOSE_CHANNEL, request.channel, phone,
                     null /* workSource */);