Expose CarrierMessagingServiceWrapper as System API.

Also adding Executor when callback, according to API council's
feedback.

Bug: 172087216
Test: build
Change-Id: Iaff6c75c1f92840424deeffbc4504a3ecf9bc1ee
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 5270d00..a49f71f 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -9093,6 +9093,26 @@
     method @NonNull @WorkerThread public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
   }
 
+  public final class CarrierMessagingServiceWrapper {
+    ctor public CarrierMessagingServiceWrapper();
+    method public boolean bindToCarrierMessagingService(@NonNull android.content.Context, @NonNull String, @NonNull java.util.concurrent.Executor, @NonNull Runnable);
+    method public void disposeConnection(@NonNull android.content.Context);
+    method public void downloadMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void receiveSms(@NonNull android.service.carrier.MessagePdu, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void sendDataSms(@NonNull byte[], int, @NonNull String, int, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void sendMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void sendMultipartTextSms(@NonNull java.util.List<java.lang.String>, int, @NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+    method public void sendTextSms(@NonNull String, int, @NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback);
+  }
+
+  public static interface CarrierMessagingServiceWrapper.CarrierMessagingCallback {
+    method public default void onDownloadMmsComplete(int);
+    method public default void onReceiveSmsComplete(int);
+    method public default void onSendMmsComplete(int, @Nullable byte[]);
+    method public default void onSendMultipartSmsComplete(int, @Nullable int[]);
+    method public default void onSendSmsComplete(int, int);
+  }
+
 }
 
 package android.service.contentcapture {
diff --git a/core/java/android/service/carrier/CarrierMessagingService.java b/core/java/android/service/carrier/CarrierMessagingService.java
index 88a78c3..61213e6 100644
--- a/core/java/android/service/carrier/CarrierMessagingService.java
+++ b/core/java/android/service/carrier/CarrierMessagingService.java
@@ -16,6 +16,7 @@
 
 package android.service.carrier;
 
+import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SdkConstant;
@@ -25,6 +26,8 @@
 import android.os.IBinder;
 import android.os.RemoteException;
 
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.List;
 
 /**
@@ -74,6 +77,15 @@
      */
     public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE = 0x2;
 
+    /** @hide */
+    @IntDef(flag = true, prefix = { "RECEIVE_OPTIONS_" }, value = {
+            RECEIVE_OPTIONS_DEFAULT,
+            RECEIVE_OPTIONS_DROP,
+            RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface FilterCompleteResult{}
+
     /**
      * Indicates that an SMS or MMS message was successfully sent.
      */
@@ -89,6 +101,15 @@
      */
     public static final int SEND_STATUS_ERROR = 2;
 
+    /** @hide */
+    @IntDef(prefix = { "SEND_STATUS_" }, value = {
+            SEND_STATUS_OK,
+            SEND_STATUS_RETRY_ON_CARRIER_NETWORK,
+            SEND_STATUS_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SendResult {}
+
     /**
      * Successfully downloaded an MMS message.
      */
@@ -104,10 +125,26 @@
      */
     public static final int DOWNLOAD_STATUS_ERROR = 2;
 
+    /** @hide */
+    @IntDef(prefix = { "DOWNLOAD_STATUS_" }, value = {
+            DOWNLOAD_STATUS_OK,
+            DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK,
+            DOWNLOAD_STATUS_ERROR
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface DownloadResult {}
+
     /**
      * Flag to request SMS delivery status report.
      */
-    public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 1;
+    public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 0x1;
+
+    /** @hide */
+    @IntDef(flag = true, prefix = { "SEND_FLAG_" }, value = {
+            SEND_FLAG_REQUEST_DELIVERY_STATUS
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface SendRequest {}
 
     private final ICarrierMessagingWrapper mWrapper = new ICarrierMessagingWrapper();
 
diff --git a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
index 4ffffc6..197c5a6 100644
--- a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
+++ b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
@@ -16,19 +16,25 @@
 
 package android.service.carrier;
 
+import android.annotation.CallbackExecutor;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
+import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.Context;
 import android.content.Intent;
 import android.content.ServiceConnection;
 import android.net.Uri;
+import android.os.Binder;
 import android.os.IBinder;
 import android.os.RemoteException;
+import android.telephony.SmsMessage;
 
 import com.android.internal.util.Preconditions;
 
 import java.util.List;
+import java.util.Objects;
+import java.util.concurrent.Executor;
 
 /**
  * Provides basic structure for platform to connect to the carrier messaging service.
@@ -46,6 +52,7 @@
  * CarrierMessagingService.
  * @hide
  */
+@SystemApi
 public final class CarrierMessagingServiceWrapper {
     // Populated by bindToCarrierMessagingService. bindToCarrierMessagingService must complete
     // prior to calling disposeConnection so that mCarrierMessagingServiceConnection is initialized.
@@ -53,6 +60,7 @@
 
     private volatile ICarrierMessagingService mICarrierMessagingService;
     private Runnable mOnServiceReadyCallback;
+    private Executor mServiceReadyCallbackExecutor;
 
     /**
      * Binds to the carrier messaging service under package {@code carrierPackageName}. This method
@@ -60,18 +68,27 @@
      *
      * @param context the context
      * @param carrierPackageName the carrier package name
+     * @param executor the executor to run the callback.
+     * @param onServiceReadyCallback the callback when service becomes ready.
      * @return true upon successfully binding to a carrier messaging service, false otherwise
      * @hide
      */
+    @SystemApi
     public boolean bindToCarrierMessagingService(@NonNull Context context,
             @NonNull String carrierPackageName,
+            @NonNull @CallbackExecutor Executor executor,
             @NonNull Runnable onServiceReadyCallback) {
         Preconditions.checkState(mCarrierMessagingServiceConnection == null);
+        Objects.requireNonNull(context);
+        Objects.requireNonNull(carrierPackageName);
+        Objects.requireNonNull(executor);
+        Objects.requireNonNull(onServiceReadyCallback);
 
         Intent intent = new Intent(CarrierMessagingService.SERVICE_INTERFACE);
         intent.setPackage(carrierPackageName);
         mCarrierMessagingServiceConnection = new CarrierMessagingServiceConnection();
         mOnServiceReadyCallback = onServiceReadyCallback;
+        mServiceReadyCallbackExecutor = executor;
         return context.bindService(intent, mCarrierMessagingServiceConnection,
                 Context.BIND_AUTO_CREATE);
     }
@@ -82,11 +99,13 @@
      * @param context the context
      * @hide
      */
+    @SystemApi
     public void disposeConnection(@NonNull Context context) {
         Preconditions.checkNotNull(mCarrierMessagingServiceConnection);
         context.unbindService(mCarrierMessagingServiceConnection);
         mCarrierMessagingServiceConnection = null;
         mOnServiceReadyCallback = null;
+        mServiceReadyCallbackExecutor = null;
     }
 
     /**
@@ -96,26 +115,38 @@
      */
     private void onServiceReady(ICarrierMessagingService carrierMessagingService) {
         mICarrierMessagingService = carrierMessagingService;
-        if (mOnServiceReadyCallback != null) mOnServiceReadyCallback.run();
+        if (mOnServiceReadyCallback != null && mServiceReadyCallbackExecutor != null) {
+            final long identity = Binder.clearCallingIdentity();
+            try {
+                mServiceReadyCallbackExecutor.execute(mOnServiceReadyCallback);
+            } finally {
+                Binder.restoreCallingIdentity(identity);
+            }
+        }
     }
 
     /**
-     * Request filtering an incoming SMS message.
+     * Request the CarrierMessagingService to process an incoming SMS text or data message.
      * The service will call callback.onFilterComplete with the filtering result.
      *
      * @param pdu the PDUs of the message
-     * @param format the format of the PDUs, typically "3gpp" or "3gpp2"
+     * @param format the format of the PDUs, typically "3gpp" or "3gpp2".
+     *               See {@link SmsMessage#FORMAT_3GPP} and {@link SmsMessage#FORMAT_3GPP2} for
+     *               more details.
      * @param destPort the destination port of a data SMS. It will be -1 for text SMS
      * @param subId SMS subscription ID of the SIM
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
-    public void filterSms(@NonNull MessagePdu pdu, @NonNull String format, int destPort,
-            int subId, @NonNull final CarrierMessagingCallback callback) {
+    @SystemApi
+    public void receiveSms(@NonNull MessagePdu pdu, @NonNull @SmsMessage.Format String format,
+            int destPort, int subId, @NonNull @CallbackExecutor final Executor executor,
+            @NonNull final CarrierMessagingCallback callback) {
         if (mICarrierMessagingService != null) {
             try {
                 mICarrierMessagingService.filterSms(pdu, format, destPort, subId,
-                        new CarrierMessagingCallbackInternal(callback));
+                        new CarrierMessagingCallbackInternal(callback, executor));
             } catch (RemoteException e) {
                 throw new RuntimeException(e);
             }
@@ -130,19 +161,23 @@
      * @param text the text to send
      * @param subId SMS subscription ID of the SIM
      * @param destAddress phone number of the recipient of the message
-     * @param sendSmsFlag flag for sending SMS
+     * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
+     *        {@link CarrierMessagingService#SEND_FLAG_REQUEST_DELIVERY_STATUS}.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void sendTextSms(@NonNull String text, int subId, @NonNull String destAddress,
-            int sendSmsFlag, @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.sendTextSms(text, subId, destAddress, sendSmsFlag,
-                        new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+            @CarrierMessagingService.SendRequest int sendSmsFlag,
+            @NonNull @CallbackExecutor final Executor executor,
+            @NonNull final CarrierMessagingCallback callback) {
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.sendTextSms(text, subId, destAddress, sendSmsFlag,
+                    new CarrierMessagingCallbackInternal(callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -155,20 +190,24 @@
      * @param subId SMS subscription ID of the SIM
      * @param destAddress phone number of the recipient of the message
      * @param destPort port number of the recipient of the message
-     * @param sendSmsFlag flag for sending SMS
+     * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
+     *        {@link CarrierMessagingService#SEND_FLAG_REQUEST_DELIVERY_STATUS}.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void sendDataSms(@NonNull byte[] data, int subId, @NonNull String destAddress,
-            int destPort, int sendSmsFlag,
+            int destPort, @CarrierMessagingService.SendRequest int sendSmsFlag,
+            @NonNull @CallbackExecutor final Executor executor,
             @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.sendDataSms(data, subId, destAddress, destPort,
-                        sendSmsFlag, new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.sendDataSms(data, subId, destAddress, destPort,
+                    sendSmsFlag, new CarrierMessagingCallbackInternal(
+                            callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -180,20 +219,24 @@
      * @param parts the parts of the multi-part text SMS to send
      * @param subId SMS subscription ID of the SIM
      * @param destAddress phone number of the recipient of the message
-     * @param sendSmsFlag flag for sending SMS
+     * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
+     *        {@link CarrierMessagingService#SEND_FLAG_REQUEST_DELIVERY_STATUS}.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void sendMultipartTextSms(@NonNull List<String> parts, int subId,
-            @NonNull String destAddress, int sendSmsFlag,
+            @NonNull String destAddress,
+            @CarrierMessagingService.SendRequest int sendSmsFlag,
+            @NonNull @CallbackExecutor final Executor executor,
             @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.sendMultipartTextSms(parts, subId, destAddress,
-                        sendSmsFlag, new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.sendMultipartTextSms(parts, subId, destAddress,
+                    sendSmsFlag, new CarrierMessagingCallbackInternal(callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -206,18 +249,20 @@
      * @param subId SMS subscription ID of the SIM
      * @param location the optional URI to send this MMS PDU. If this is {code null},
      *        the PDU should be sent to the default MMSC URL.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void sendMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
+            @NonNull @CallbackExecutor final Executor executor,
             @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.sendMms(pduUri, subId, location,
-                        new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.sendMms(pduUri, subId, location,
+                    new CarrierMessagingCallbackInternal(callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -229,18 +274,20 @@
      * @param pduUri the content provider URI of the PDU to be downloaded.
      * @param subId SMS subscription ID of the SIM
      * @param location the URI of the message to be downloaded.
+     * @param executor the executor to run the callback.
      * @param callback the callback to notify upon completion
      * @hide
      */
+    @SystemApi
     public void downloadMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
+            @NonNull @CallbackExecutor final Executor executor,
             @NonNull final CarrierMessagingCallback callback) {
-        if (mICarrierMessagingService != null) {
-            try {
-                mICarrierMessagingService.downloadMms(pduUri, subId, location,
-                        new CarrierMessagingCallbackInternal(callback));
-            } catch (RemoteException e) {
-                throw new RuntimeException(e);
-            }
+        Objects.requireNonNull(mICarrierMessagingService);
+        try {
+            mICarrierMessagingService.downloadMms(pduUri, subId, location,
+                    new CarrierMessagingCallbackInternal(callback, executor));
+        } catch (RemoteException e) {
+            throw new RuntimeException(e);
         }
     }
 
@@ -263,19 +310,19 @@
      * {@link CarrierMessagingServiceWrapper}.
      * @hide
      */
+    @SystemApi
     public interface CarrierMessagingCallback {
-
         /**
-         * Response callback for {@link CarrierMessagingServiceWrapper#filterSms}.
+         * Response callback for {@link CarrierMessagingServiceWrapper#receiveSms}.
          * @param result a bitmask integer to indicate how the incoming text SMS should be handled
          *               by the platform. Bits set can be
          *               {@link CarrierMessagingService#RECEIVE_OPTIONS_DROP} and
          *               {@link CarrierMessagingService#
          *               RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE}.
-         *               {@see CarrierMessagingService#onReceiveTextSms}.
-         * @hide
+         *               {@link CarrierMessagingService#onReceiveTextSms}.
          */
-        default void onFilterComplete(int result) {
+        default void onReceiveSmsComplete(
+                @CarrierMessagingService.FilterCompleteResult int result) {
 
         }
 
@@ -287,10 +334,9 @@
          *               and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
          * @param messageRef message reference of the just-sent message. This field is applicable
          *                   only if result is {@link CarrierMessagingService#SEND_STATUS_OK}.
-         * @hide
          */
-        default void onSendSmsComplete(int result, int messageRef) {
-
+        default void onSendSmsComplete(@CarrierMessagingService.SendResult
+                int result, int messageRef) {
         }
 
         /**
@@ -301,9 +347,9 @@
          * @param messageRefs an array of message references, one for each part of the
          *                    multipart SMS. This field is applicable only if result is
          *                    {@link CarrierMessagingService#SEND_STATUS_OK}.
-         * @hide
          */
-        default void onSendMultipartSmsComplete(int result, @Nullable int[] messageRefs) {
+        default void onSendMultipartSmsComplete(@CarrierMessagingService.SendResult
+                int result, @Nullable int[] messageRefs) {
 
         }
 
@@ -315,56 +361,62 @@
          * @param sendConfPdu a possibly {code null} SendConf PDU, which confirms that the message
          *                    was sent. sendConfPdu is ignored if the {@code result} is not
          *                    {@link CarrierMessagingService#SEND_STATUS_OK}.
-         * @hide
          */
-        default void onSendMmsComplete(int result, @Nullable byte[] sendConfPdu) {
+        default void onSendMmsComplete(@CarrierMessagingService.SendResult
+                int result, @Nullable byte[] sendConfPdu) {
 
         }
 
         /**
          * Response callback for {@link CarrierMessagingServiceWrapper#downloadMms}.
-         * @param result download status, one of {@link CarrierMessagingService#SEND_STATUS_OK},
-         *               {@link CarrierMessagingService#SEND_STATUS_RETRY_ON_CARRIER_NETWORK},
-         *               and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
-         * @hide
+         * @param result download status, one of {@link CarrierMessagingService#DOWNLOAD_STATUS_OK},
+         *               {@link CarrierMessagingService#DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK},
+         *               and {@link CarrierMessagingService#DOWNLOAD_STATUS_ERROR}.
          */
-        default void onDownloadMmsComplete(int result) {
+        default void onDownloadMmsComplete(@CarrierMessagingService.DownloadResult
+                int result) {
 
         }
     }
 
     private final class CarrierMessagingCallbackInternal
             extends ICarrierMessagingCallback.Stub {
-        CarrierMessagingCallback mCarrierMessagingCallback;
+        final CarrierMessagingCallback mCarrierMessagingCallback;
+        final Executor mExecutor;
 
-        CarrierMessagingCallbackInternal(CarrierMessagingCallback callback) {
+        CarrierMessagingCallbackInternal(CarrierMessagingCallback callback,
+                final Executor executor) {
             mCarrierMessagingCallback = callback;
+            mExecutor = executor;
         }
 
         @Override
         public void onFilterComplete(int result) throws RemoteException {
-            mCarrierMessagingCallback.onFilterComplete(result);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onReceiveSmsComplete(result));
         }
 
         @Override
         public void onSendSmsComplete(int result, int messageRef) throws RemoteException {
-            mCarrierMessagingCallback.onSendSmsComplete(result, messageRef);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onSendSmsComplete(
+                    result, messageRef));
         }
 
         @Override
         public void onSendMultipartSmsComplete(int result, int[] messageRefs)
                 throws RemoteException {
-            mCarrierMessagingCallback.onSendMultipartSmsComplete(result, messageRefs);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onSendMultipartSmsComplete(
+                    result, messageRefs));
         }
 
         @Override
         public void onSendMmsComplete(int result, byte[] sendConfPdu) throws RemoteException {
-            mCarrierMessagingCallback.onSendMmsComplete(result, sendConfPdu);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onSendMmsComplete(
+                    result, sendConfPdu));
         }
 
         @Override
         public void onDownloadMmsComplete(int result) throws RemoteException {
-            mCarrierMessagingCallback.onDownloadMmsComplete(result);
+            mExecutor.execute(() -> mCarrierMessagingCallback.onDownloadMmsComplete(result));
         }
     }
-}
\ No newline at end of file
+}
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index d6397f7..141b8cb 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -350,6 +350,9 @@
     <!-- Permissions required for CTS test - CtsContactsProviderTestCases -->
     <uses-permission android:name="android.contacts.permission.MANAGE_SIM_ACCOUNTS" />
 
+    <!-- Permissions required for CTS test - CarrierMessagingServiceWrapprTest -->
+    <uses-permission android:name="android.permission.BIND_CARRIER_SERVICES" />
+
     <!-- Allows overriding the system's device state from the shell -->
     <uses-permission android:name="android.permission.CONTROL_DEVICE_STATE"/>