Create @SystemApi CarrierMessagingServiceWrapper.

This is primarily a wrapper over ICarrierMessagingService
that to create a stable API to communicate with CarrierMessagingService.

Test: basic messaging sanity
Bug: 143609473
Merged-in: I67fda8bab3902b358c483f992633dbdfe3a8cda2
Change-Id: I67fda8bab3902b358c483f992633dbdfe3a8cda2
(cherry picked from commit 92642659e81b2358dce0969661003287564ace03)
diff --git a/api/system-current.txt b/api/system-current.txt
index 6134b94..a6c90c8 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -6374,6 +6374,28 @@
     method @NonNull @WorkerThread public abstract java.util.List<android.content.ContentValues> onRestoreApns(int);
   }
 
+  public abstract class CarrierMessagingServiceWrapper {
+    ctor public CarrierMessagingServiceWrapper();
+    method public boolean bindToCarrierMessagingService(@NonNull android.content.Context, @NonNull String);
+    method public void disposeConnection(@NonNull android.content.Context);
+    method public void downloadMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+    method public void filterSms(@NonNull android.service.carrier.MessagePdu, @NonNull String, int, int, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+    method public abstract void onServiceReady();
+    method public void sendDataSms(@NonNull byte[], int, @NonNull String, int, int, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+    method public void sendMms(@NonNull android.net.Uri, int, @NonNull android.net.Uri, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+    method public void sendMultipartTextSms(@NonNull java.util.List<java.lang.String>, int, @NonNull String, int, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+    method public void sendTextSms(@NonNull String, int, @NonNull String, int, @NonNull android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper);
+  }
+
+  public abstract static class CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper {
+    ctor public CarrierMessagingServiceWrapper.CarrierMessagingCallbackWrapper();
+    method public void onDownloadMmsComplete(int);
+    method public void onFilterComplete(int);
+    method public void onSendMmsComplete(int, @Nullable byte[]);
+    method public void onSendMultipartSmsComplete(int, @Nullable int[]);
+    method public void onSendSmsComplete(int, int);
+  }
+
 }
 
 package android.service.contentcapture {
diff --git a/config/hiddenapi-greylist-max-p.txt b/config/hiddenapi-greylist-max-p.txt
index 25d45b0..34339d7 100644
--- a/config/hiddenapi-greylist-max-p.txt
+++ b/config/hiddenapi-greylist-max-p.txt
@@ -47,7 +47,6 @@
 Landroid/os/WorkSource;->updateLocked(Landroid/os/WorkSource;ZZ)Z
 Landroid/service/carrier/ICarrierMessagingCallback$Stub;-><init>()V
 Landroid/service/carrier/ICarrierMessagingService;->filterSms(Landroid/service/carrier/MessagePdu;Ljava/lang/String;IILandroid/service/carrier/ICarrierMessagingCallback;)V
-Landroid/telephony/CarrierMessagingServiceManager;-><init>()V
 Landroid/view/IGraphicsStats$Stub$Proxy;-><init>(Landroid/os/IBinder;)V
 Landroid/view/IGraphicsStats$Stub;->asInterface(Landroid/os/IBinder;)Landroid/view/IGraphicsStats;
 Landroid/view/IWindowManager;->setInTouchMode(Z)V
diff --git a/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
new file mode 100644
index 0000000..de90b94
--- /dev/null
+++ b/core/java/android/service/carrier/CarrierMessagingServiceWrapper.java
@@ -0,0 +1,389 @@
+/*
+ * Copyright (C) 2019 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.service.carrier;
+
+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.IBinder;
+import android.os.RemoteException;
+
+import com.android.internal.util.Preconditions;
+
+import java.util.List;
+
+/**
+ * Provides basic structure for platform to connect to the carrier messaging service.
+ * <p>
+ * <code>
+ * CarrierMessagingServiceWrapper carrierMessagingServiceWrapper =
+ *     new CarrierMessagingServiceWrapperImpl();
+ * if (carrierMessagingServiceWrapper.bindToCarrierMessagingService(context, carrierPackageName)) {
+ *   // wait for onServiceReady callback
+ * } else {
+ *   // Unable to bind: handle error.
+ * }
+ * </code>
+ * <p> Upon completion {@link #disposeConnection} should be called to unbind the
+ * CarrierMessagingService.
+ * @hide
+ */
+@SystemApi
+public abstract class CarrierMessagingServiceWrapper {
+    // Populated by bindToCarrierMessagingService. bindToCarrierMessagingService must complete
+    // prior to calling disposeConnection so that mCarrierMessagingServiceConnection is initialized.
+    private volatile CarrierMessagingServiceConnection mCarrierMessagingServiceConnection;
+
+    private volatile ICarrierMessagingService mICarrierMessagingService;
+
+    /**
+     * Binds to the carrier messaging service under package {@code carrierPackageName}. This method
+     * should be called exactly once.
+     *
+     * @param context the context
+     * @param carrierPackageName the carrier package name
+     * @return true upon successfully binding to a carrier messaging service, false otherwise
+     * @hide
+     */
+    @SystemApi
+    public boolean bindToCarrierMessagingService(@NonNull Context context,
+            @NonNull String carrierPackageName) {
+        Preconditions.checkState(mCarrierMessagingServiceConnection == null);
+
+        Intent intent = new Intent(CarrierMessagingService.SERVICE_INTERFACE);
+        intent.setPackage(carrierPackageName);
+        mCarrierMessagingServiceConnection = new CarrierMessagingServiceConnection();
+        return context.bindService(intent, mCarrierMessagingServiceConnection,
+                Context.BIND_AUTO_CREATE);
+    }
+
+    /**
+     * Unbinds the carrier messaging service. This method should be called exactly once.
+     *
+     * @param context the context
+     * @hide
+     */
+    @SystemApi
+    public void disposeConnection(@NonNull Context context) {
+        Preconditions.checkNotNull(mCarrierMessagingServiceConnection);
+        context.unbindService(mCarrierMessagingServiceConnection);
+        mCarrierMessagingServiceConnection = null;
+    }
+
+    /**
+     * Implemented by subclasses to use the carrier messaging service once it is ready.
+     * @hide
+     */
+    @SystemApi
+    public abstract void onServiceReady();
+
+    /**
+     * Called when connection with service is established.
+     *
+     * @param carrierMessagingService the carrier messaing service interface
+     */
+    private void onServiceReady(ICarrierMessagingService carrierMessagingService) {
+        mICarrierMessagingService = carrierMessagingService;
+        onServiceReady();
+    }
+
+    /**
+     * Request filtering an incoming SMS 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 destPort the destination port of a data SMS. It will be -1 for text SMS
+     * @param subId SMS subscription ID of the SIM
+     * @param callback the callback to notify upon completion
+     * @hide
+     */
+    @SystemApi
+    public void filterSms(@NonNull MessagePdu pdu, @NonNull String format, int destPort,
+            int subId, @NonNull final CarrierMessagingCallbackWrapper callback) {
+        if (mICarrierMessagingService != null) {
+            try {
+                mICarrierMessagingService.filterSms(pdu, format, destPort, subId,
+                        new CarrierMessagingCallbackWrapperInternal(callback));
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Request sending a new text SMS from the device.
+     * The service will call {@link ICarrierMessagingCallback#onSendSmsComplete} with the send
+     * status.
+     *
+     * @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 callback the callback to notify upon completion
+     * @hide
+     */
+    @SystemApi
+    public void sendTextSms(@NonNull String text, int subId, @NonNull String destAddress,
+            int sendSmsFlag, @NonNull final CarrierMessagingCallbackWrapper callback) {
+        if (mICarrierMessagingService != null) {
+            try {
+                mICarrierMessagingService.sendTextSms(text, subId, destAddress, sendSmsFlag,
+                        new CarrierMessagingCallbackWrapperInternal(callback));
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Request sending a new data SMS from the device.
+     * The service will call {@link ICarrierMessagingCallback#onSendSmsComplete} with the send
+     * status.
+     *
+     * @param data the data to send
+     * @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 callback the callback to notify upon completion
+     * @hide
+     */
+    @SystemApi
+    public void sendDataSms(@NonNull byte[] data, int subId, @NonNull String destAddress,
+            int destPort, int sendSmsFlag,
+            @NonNull final CarrierMessagingCallbackWrapper callback) {
+        if (mICarrierMessagingService != null) {
+            try {
+                mICarrierMessagingService.sendDataSms(data, subId, destAddress, destPort,
+                        sendSmsFlag, new CarrierMessagingCallbackWrapperInternal(callback));
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Request sending a new multi-part text SMS from the device.
+     * The service will call {@link ICarrierMessagingCallback#onSendMultipartSmsComplete}
+     * with the send status.
+     *
+     * @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 callback the callback to notify upon completion
+     * @hide
+     */
+    @SystemApi
+    public void sendMultipartTextSms(@NonNull List<String> parts, int subId,
+            @NonNull String destAddress, int sendSmsFlag,
+            @NonNull final CarrierMessagingCallbackWrapper callback) {
+        if (mICarrierMessagingService != null) {
+            try {
+                mICarrierMessagingService.sendMultipartTextSms(parts, subId, destAddress,
+                        sendSmsFlag, new CarrierMessagingCallbackWrapperInternal(callback));
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Request sending a new MMS PDU from the device.
+     * The service will call {@link ICarrierMessagingCallback#onSendMmsComplete} with the send
+     * status.
+     *
+     * @param pduUri the content provider URI of the PDU to send
+     * @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 callback the callback to notify upon completion
+     * @hide
+     */
+    @SystemApi
+    public void sendMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
+            @NonNull final CarrierMessagingCallbackWrapper callback) {
+        if (mICarrierMessagingService != null) {
+            try {
+                mICarrierMessagingService.sendMms(pduUri, subId, location,
+                        new CarrierMessagingCallbackWrapperInternal(callback));
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * Request downloading a new MMS.
+     * The service will call {@link ICarrierMessagingCallback#onDownloadMmsComplete} with the
+     * download status.
+     *
+     * @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 callback the callback to notify upon completion
+     * @hide
+     */
+    @SystemApi
+    public void downloadMms(@NonNull Uri pduUri, int subId, @NonNull Uri location,
+            @NonNull final CarrierMessagingCallbackWrapper callback) {
+        if (mICarrierMessagingService != null) {
+            try {
+                mICarrierMessagingService.downloadMms(pduUri, subId, location,
+                        new CarrierMessagingCallbackWrapperInternal(callback));
+            } catch (RemoteException e) {
+                throw new RuntimeException(e);
+            }
+        }
+    }
+
+    /**
+     * A basic {@link ServiceConnection}.
+     */
+    private final class CarrierMessagingServiceConnection implements ServiceConnection {
+        @Override
+        public void onServiceConnected(ComponentName name, IBinder service) {
+            onServiceReady(ICarrierMessagingService.Stub.asInterface(service));
+        }
+
+        @Override
+        public void onServiceDisconnected(ComponentName name) {
+        }
+    }
+
+    /**
+     * Callback wrapper used for response to requests exposed by
+     * {@link CarrierMessagingServiceWrapper}.
+     * @hide
+     */
+    @SystemApi
+    public abstract static class CarrierMessagingCallbackWrapper {
+
+        /**
+         * Response callback for {@link CarrierMessagingServiceWrapper#filterSms}.
+         * @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
+         */
+        @SystemApi
+        public void onFilterComplete(int result) {
+
+        }
+
+        /**
+         * Response callback for {@link CarrierMessagingServiceWrapper#sendTextSms} and
+         * {@link CarrierMessagingServiceWrapper#sendDataSms}.
+         * @param result send status, one of {@link CarrierMessagingService#SEND_STATUS_OK},
+         *               {@link CarrierMessagingService#SEND_STATUS_RETRY_ON_CARRIER_NETWORK},
+         *               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
+         */
+        @SystemApi
+        public void onSendSmsComplete(int result, int messageRef) {
+
+        }
+
+        /**
+         * Response callback for {@link CarrierMessagingServiceWrapper#sendMultipartTextSms}.
+         * @param result send status, one of {@link CarrierMessagingService#SEND_STATUS_OK},
+         *               {@link CarrierMessagingService#SEND_STATUS_RETRY_ON_CARRIER_NETWORK},
+         *               and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
+         * @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
+         */
+        @SystemApi
+        public void onSendMultipartSmsComplete(int result, @Nullable int[] messageRefs) {
+
+        }
+
+        /**
+         * Response callback for {@link CarrierMessagingServiceWrapper#sendMms}.
+         * @param result send status, one of {@link CarrierMessagingService#SEND_STATUS_OK},
+         *               {@link CarrierMessagingService#SEND_STATUS_RETRY_ON_CARRIER_NETWORK},
+         *               and {@link CarrierMessagingService#SEND_STATUS_ERROR}.
+         * @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
+         */
+        @SystemApi
+        public void onSendMmsComplete(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
+         */
+        @SystemApi
+        public void onDownloadMmsComplete(int result) {
+
+        }
+    }
+
+    private final class CarrierMessagingCallbackWrapperInternal
+            extends ICarrierMessagingCallback.Stub {
+        CarrierMessagingCallbackWrapper mCarrierMessagingCallbackWrapper;
+
+        CarrierMessagingCallbackWrapperInternal(CarrierMessagingCallbackWrapper callback) {
+            mCarrierMessagingCallbackWrapper = callback;
+        }
+
+        @Override
+        public void onFilterComplete(int result) throws RemoteException {
+            mCarrierMessagingCallbackWrapper.onFilterComplete(result);
+        }
+
+        @Override
+        public void onSendSmsComplete(int result, int messageRef) throws RemoteException {
+            mCarrierMessagingCallbackWrapper.onSendSmsComplete(result, messageRef);
+        }
+
+        @Override
+        public void onSendMultipartSmsComplete(int result, int[] messageRefs)
+                throws RemoteException {
+            mCarrierMessagingCallbackWrapper.onSendMultipartSmsComplete(result, messageRefs);
+        }
+
+        @Override
+        public void onSendMmsComplete(int result, byte[] sendConfPdu) throws RemoteException {
+            mCarrierMessagingCallbackWrapper.onSendMmsComplete(result, sendConfPdu);
+        }
+
+        @Override
+        public void onDownloadMmsComplete(int result) throws RemoteException {
+            mCarrierMessagingCallbackWrapper.onDownloadMmsComplete(result);
+        }
+    }
+}