summaryrefslogtreecommitdiffstats
path: root/core/java/android/service/carrier
diff options
context:
space:
mode:
authorCheuksan Wang <edwang@google.com>2014-11-21 16:54:02 -0800
committerCheuksan Wang <edwang@google.com>2014-12-01 18:11:07 -0800
commitb72eb97e4bca1e4fd68e79f9d04e9a6a15aebd21 (patch)
tree34a04312d4d42e92d89af8fb96d8af52f76ecad8 /core/java/android/service/carrier
parent4cd3e47e584fb1508db8f0e559f1167ab07c68c3 (diff)
downloadframeworks_base-b72eb97e4bca1e4fd68e79f9d04e9a6a15aebd21.zip
frameworks_base-b72eb97e4bca1e4fd68e79f9d04e9a6a15aebd21.tar.gz
frameworks_base-b72eb97e4bca1e4fd68e79f9d04e9a6a15aebd21.tar.bz2
new SMS/MMS carrier app API
Changes based on api council review BUG: 18005911 Change-Id: I23bd207ce70f7fa201d6d964c1700cfc44cb009b
Diffstat (limited to 'core/java/android/service/carrier')
-rw-r--r--core/java/android/service/carrier/CarrierMessagingService.java417
-rw-r--r--core/java/android/service/carrier/ICarrierMessagingCallback.aidl30
-rw-r--r--core/java/android/service/carrier/ICarrierMessagingService.aidl110
-rw-r--r--core/java/android/service/carrier/MessagePdu.aidl19
-rw-r--r--core/java/android/service/carrier/MessagePdu.java97
5 files changed, 673 insertions, 0 deletions
diff --git a/core/java/android/service/carrier/CarrierMessagingService.java b/core/java/android/service/carrier/CarrierMessagingService.java
new file mode 100644
index 0000000..3d6ebca
--- /dev/null
+++ b/core/java/android/service/carrier/CarrierMessagingService.java
@@ -0,0 +1,417 @@
+/*
+ * Copyright (C) 2014 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.SdkConstant;
+import android.app.Service;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.RemoteException;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A service that receives calls from the system when new SMS and MMS are
+ * sent or received.
+ * <p>To extend this class, you must declare the service in your manifest file with
+ * the {@link android.Manifest.permission#BIND_CARRIER_MESSAGING_SERVICE} permission
+ * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
+ * <pre>
+ * &lt;service android:name=".MyMessagingService"
+ * android:label="&#64;string/service_name"
+ * android:permission="android.permission.BIND_CARRIER_MESSAGING_SERVICE">
+ * &lt;intent-filter>
+ * &lt;action android:name="android.service.carrier.CarrierMessagingService" />
+ * &lt;/intent-filter>
+ * &lt;/service></pre>
+ */
+public abstract class CarrierMessagingService extends Service {
+ /**
+ * The {@link android.content.Intent} that must be declared as handled by the service.
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
+ public static final String SERVICE_INTERFACE
+ = "android.service.carrier.CarrierMessagingService";
+
+ /**
+ * Indicates that an SMS or MMS message was successfully sent.
+ */
+ public static final int SEND_STATUS_OK = 0;
+
+ /**
+ * SMS/MMS sending failed. We should retry via the carrier network.
+ */
+ public static final int SEND_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
+
+ /**
+ * SMS/MMS sending failed. We should not retry via the carrier network.
+ */
+ public static final int SEND_STATUS_ERROR = 2;
+
+ /**
+ * Successfully downloaded an MMS message.
+ */
+ public static final int DOWNLOAD_STATUS_OK = 0;
+
+ /**
+ * MMS downloading failed. We should retry via the carrier network.
+ */
+ public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
+
+ /**
+ * MMS downloading failed. We should not retry via the carrier network.
+ */
+ public static final int DOWNLOAD_STATUS_ERROR = 2;
+
+ private final ICarrierMessagingWrapper mWrapper = new ICarrierMessagingWrapper();
+
+ /**
+ * Override this method to filter inbound SMS messages.
+ *
+ * @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 binary SMS, this will be -1 for text SMS
+ * @param subId SMS subscription ID of the SIM
+ * @param callback result callback. Call with {@code true} to keep an inbound SMS message and
+ * deliver to SMS apps, and {@code false} to drop the message.
+ */
+ public void onFilterSms(@NonNull MessagePdu pdu, @NonNull String format, int destPort,
+ int subId, @NonNull ResultCallback<Boolean> callback) {
+ // optional
+ try {
+ callback.onReceiveResult(true);
+ } catch (RemoteException ex) {
+ }
+ }
+
+ /**
+ * Override this method to intercept text SMSs sent from the device.
+ *
+ * @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 callback result callback. Call with a {@link SendSmsResult}.
+ */
+ public void onSendTextSms(
+ @NonNull String text, int subId, @NonNull String destAddress,
+ @NonNull ResultCallback<SendSmsResult> callback) {
+ // optional
+ try {
+ callback.onReceiveResult(new SendSmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0));
+ } catch (RemoteException ex) {
+ }
+ }
+
+ /**
+ * Override this method to intercept binary SMSs sent from the device.
+ *
+ * @param data the binary content
+ * @param subId SMS subscription ID of the SIM
+ * @param destAddress phone number of the recipient of the message
+ * @param destPort the destination port
+ * @param callback result callback. Call with a {@link SendSmsResult}.
+ */
+ public void onSendDataSms(@NonNull byte[] data, int subId,
+ @NonNull String destAddress, int destPort,
+ @NonNull ResultCallback<SendSmsResult> callback) {
+ // optional
+ try {
+ callback.onReceiveResult(new SendSmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0));
+ } catch (RemoteException ex) {
+ }
+ }
+
+ /**
+ * Override this method to intercept long SMSs sent from the device.
+ *
+ * @param parts a {@link List} of the message parts
+ * @param subId SMS subscription ID of the SIM
+ * @param destAddress phone number of the recipient of the message
+ * @param callback result callback. Call with a {@link SendMultipartSmsResult}.
+ */
+ public void onSendMultipartTextSms(@NonNull List<String> parts,
+ int subId, @NonNull String destAddress,
+ @NonNull ResultCallback<SendMultipartSmsResult> callback) {
+ // optional
+ try {
+ callback.onReceiveResult(
+ new SendMultipartSmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null));
+ } catch (RemoteException ex) {
+ }
+ }
+
+ /**
+ * Override this method to intercept MMSs sent from the device.
+ *
+ * @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 result callback. Call with a {@link SendMmsResult}.
+ */
+ public void onSendMms(@NonNull Uri pduUri, int subId,
+ @Nullable Uri location, @NonNull ResultCallback<SendMmsResult> callback) {
+ // optional
+ try {
+ callback.onReceiveResult(new SendMmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null));
+ } catch (RemoteException ex) {
+ }
+ }
+
+ /**
+ * Override this method to download MMSs received.
+ *
+ * @param contentUri 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 result callback. Call with a status code which is one of
+ * {@link #DOWNLOAD_STATUS_OK},
+ * {@link #DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK}, or {@link #DOWNLOAD_STATUS_ERROR}.
+ */
+ public void onDownloadMms(@NonNull Uri contentUri, int subId, @NonNull Uri location,
+ @NonNull ResultCallback<Integer> callback) {
+ // optional
+ try {
+ callback.onReceiveResult(DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK);
+ } catch (RemoteException ex) {
+ }
+ }
+
+ @Override
+ public @Nullable IBinder onBind(@NonNull Intent intent) {
+ if (!SERVICE_INTERFACE.equals(intent.getAction())) {
+ return null;
+ }
+ return mWrapper;
+ }
+
+ /**
+ * The result of sending an MMS.
+ */
+ public static final class SendMmsResult {
+ private int mSendStatus;
+ private byte[] mSendConfPdu;
+
+ /**
+ * Constructs a SendMmsResult with the MMS send result, and the SendConf PDU.
+ *
+ * @param sendStatus send status, one of {@link #SEND_STATUS_OK},
+ * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and
+ * {@link #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 #SEND_STATUS_OK}.
+ */
+ public SendMmsResult(int sendStatus, @Nullable byte[] sendConfPdu) {
+ mSendStatus = sendStatus;
+ mSendConfPdu = sendConfPdu;
+ }
+
+ /**
+ * Returns the send status of the just-sent MMS.
+ *
+ * @return the send status which is one of {@link #SEND_STATUS_OK},
+ * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}
+ */
+ public int getSendStatus() {
+ return mSendStatus;
+ }
+
+ /**
+ * Returns the SendConf PDU, which confirms that the message was sent.
+ *
+ * @return the SendConf PDU
+ */
+ public @Nullable byte[] getSendConfPdu() {
+ return mSendConfPdu;
+ }
+ }
+
+ /**
+ * The result of sending an SMS.
+ */
+ public static final class SendSmsResult {
+ private final int mSendStatus;
+ private final int mMessageRef;
+
+ /**
+ * Constructs a SendSmsResult with the send status and message reference for the
+ * just-sent SMS.
+ *
+ * @param sendStatus send status, one of {@link #SEND_STATUS_OK},
+ * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}.
+ * @param messageRef message reference of the just-sent SMS. This field is applicable only
+ * if send status is {@link #SEND_STATUS_OK}.
+ */
+ public SendSmsResult(int sendStatus, int messageRef) {
+ mSendStatus = sendStatus;
+ mMessageRef = messageRef;
+ }
+
+ /**
+ * Returns the message reference of the just-sent SMS.
+ *
+ * @return the message reference
+ */
+ public int getMessageRef() {
+ return mMessageRef;
+ }
+
+ /**
+ * Returns the send status of the just-sent SMS.
+ *
+ * @return the send status
+ */
+ public int getSendStatus() {
+ return mSendStatus;
+ }
+ }
+
+ /**
+ * The result of sending a multipart SMS.
+ */
+ public static final class SendMultipartSmsResult {
+ private final int mSendStatus;
+ private final int[] mMessageRefs;
+
+ /**
+ * Constructs a SendMultipartSmsResult with the send status and message references for the
+ * just-sent multipart SMS.
+ *
+ * @param sendStatus send status, one of {@link #SEND_STATUS_OK},
+ * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}.
+ * @param messageRefs an array of message references, one for each part of the
+ * multipart SMS. This field is applicable only if send status is
+ * {@link #SEND_STATUS_OK}.
+ */
+ public SendMultipartSmsResult(int sendStatus, @Nullable int[] messageRefs) {
+ mSendStatus = sendStatus;
+ mMessageRefs = messageRefs;
+ }
+
+ /**
+ * Returns the message references of the just-sent multipart SMS.
+ *
+ * @return the message references, one for each part of the multipart SMS
+ */
+ public @Nullable int[] getMessageRefs() {
+ return mMessageRefs;
+ }
+
+ /**
+ * Returns the send status of the just-sent SMS.
+ *
+ * @return the send status
+ */
+ public int getSendStatus() {
+ return mSendStatus;
+ }
+ }
+
+ /**
+ * A callback interface used to provide results asynchronously.
+ */
+ public interface ResultCallback<T> {
+ /**
+ * Invoked when the result is available.
+ *
+ * @param result the result
+ */
+ public void onReceiveResult(@NonNull T result) throws RemoteException;
+ };
+
+ /**
+ * A wrapper around ICarrierMessagingService to enable the carrier messaging app to implement
+ * methods it cares about in the {@link ICarrierMessagingService} interface.
+ */
+ private class ICarrierMessagingWrapper extends ICarrierMessagingService.Stub {
+ @Override
+ public void filterSms(MessagePdu pdu, String format, int destPort,
+ int subId, final ICarrierMessagingCallback callback) {
+ onFilterSms(pdu, format, destPort, subId, new ResultCallback<Boolean>() {
+ @Override
+ public void onReceiveResult(final Boolean result) throws RemoteException {
+ callback.onFilterComplete(result);
+ }
+ });
+ }
+
+ @Override
+ public void sendTextSms(String text, int subId, String destAddress,
+ final ICarrierMessagingCallback callback) {
+ onSendTextSms(text, subId, destAddress, new ResultCallback<SendSmsResult>() {
+ @Override
+ public void onReceiveResult(final SendSmsResult result) throws RemoteException {
+ callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef());
+ }
+ });
+ }
+
+ @Override
+ public void sendDataSms(byte[] data, int subId, String destAddress, int destPort,
+ final ICarrierMessagingCallback callback) {
+ onSendDataSms(data, subId, destAddress, destPort, new ResultCallback<SendSmsResult>() {
+ @Override
+ public void onReceiveResult(final SendSmsResult result) throws RemoteException {
+ callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef());
+ }
+ });
+ }
+
+ @Override
+ public void sendMultipartTextSms(List<String> parts, int subId, String destAddress,
+ final ICarrierMessagingCallback callback) {
+ onSendMultipartTextSms(parts, subId, destAddress,
+ new ResultCallback<SendMultipartSmsResult>() {
+ @Override
+ public void onReceiveResult(final SendMultipartSmsResult result)
+ throws RemoteException {
+ callback.onSendMultipartSmsComplete(
+ result.getSendStatus(), result.getMessageRefs());
+ }
+ });
+ }
+
+ @Override
+ public void sendMms(Uri pduUri, int subId, Uri location,
+ final ICarrierMessagingCallback callback) {
+ onSendMms(pduUri, subId, location, new ResultCallback<SendMmsResult>() {
+ @Override
+ public void onReceiveResult(final SendMmsResult result) throws RemoteException {
+ callback.onSendMmsComplete(result.getSendStatus(), result.getSendConfPdu());
+ }
+ });
+ }
+
+ @Override
+ public void downloadMms(Uri pduUri, int subId, Uri location,
+ final ICarrierMessagingCallback callback) {
+ onDownloadMms(pduUri, subId, location, new ResultCallback<Integer>() {
+ @Override
+ public void onReceiveResult(Integer result) throws RemoteException {
+ callback.onDownloadMmsComplete(result);
+ }
+ });
+ }
+ }
+}
diff --git a/core/java/android/service/carrier/ICarrierMessagingCallback.aidl b/core/java/android/service/carrier/ICarrierMessagingCallback.aidl
new file mode 100644
index 0000000..6118a20
--- /dev/null
+++ b/core/java/android/service/carrier/ICarrierMessagingCallback.aidl
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2014, 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;
+
+/**
+ * Callback interface definition for the Carrier Messaging Service client to get informed of the
+ * result of various API invocations.
+ * @hide
+ */
+oneway interface ICarrierMessagingCallback {
+ void onFilterComplete(boolean keepMessage);
+ void onSendSmsComplete(int result, int messageRef);
+ void onSendMultipartSmsComplete(int result, in int[] messageRefs);
+ void onSendMmsComplete(int result, in byte[] sendConfPdu);
+ void onDownloadMmsComplete(int result);
+}
diff --git a/core/java/android/service/carrier/ICarrierMessagingService.aidl b/core/java/android/service/carrier/ICarrierMessagingService.aidl
new file mode 100644
index 0000000..40a9047
--- /dev/null
+++ b/core/java/android/service/carrier/ICarrierMessagingService.aidl
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2014, 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.net.Uri;
+import android.service.carrier.ICarrierMessagingCallback;
+import android.service.carrier.MessagePdu;
+
+/**
+ * <p class="note"><strong>Note:</strong>
+ * This service can only be implemented by a carrier privileged app.
+ * @hide
+ */
+oneway interface ICarrierMessagingService {
+ /**
+ * 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
+ */
+ void filterSms(
+ in MessagePdu pdu, String format, int destPort, int subId,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * 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 callback the callback to notify upon completion
+ */
+ void sendTextSms(String text, int subId, String destAddress,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * 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 callback the callback to notify upon completion
+ */
+ void sendDataSms(in byte[] data, int subId, String destAddress, int destPort,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * 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 callback the callback to notify upon completion
+ */
+ void sendMultipartTextSms(in List<String> parts, int subId, String destAddress,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * 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
+ */
+ void sendMms(in Uri pduUri, int subId, in Uri location,
+ in ICarrierMessagingCallback callback);
+
+ /**
+ * 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
+ */
+ void downloadMms(in Uri pduUri, int subId, in Uri location,
+ in ICarrierMessagingCallback callback);
+}
+
diff --git a/core/java/android/service/carrier/MessagePdu.aidl b/core/java/android/service/carrier/MessagePdu.aidl
new file mode 100644
index 0000000..f0528a5
--- /dev/null
+++ b/core/java/android/service/carrier/MessagePdu.aidl
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2014, 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;
+
+parcelable MessagePdu;
diff --git a/core/java/android/service/carrier/MessagePdu.java b/core/java/android/service/carrier/MessagePdu.java
new file mode 100644
index 0000000..ca18e53
--- /dev/null
+++ b/core/java/android/service/carrier/MessagePdu.java
@@ -0,0 +1,97 @@
+/*
+ * Copyright (C) 2014 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.os.Parcel;
+import android.os.Parcelable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A parcelable list of PDUs representing contents of a possibly multi-part SMS.
+ */
+public final class MessagePdu implements Parcelable {
+ private static final int NULL_LENGTH = -1;
+
+ private final List<byte[]> mPduList;
+
+ /**
+ * Constructs a MessagePdu with the list of message PDUs.
+ *
+ * @param pduList the list of message PDUs
+ */
+ public MessagePdu(@NonNull List<byte[]> pduList) {
+ if (pduList == null || pduList.contains(null)) {
+ throw new IllegalArgumentException("pduList must not be null or contain nulls");
+ }
+ mPduList = pduList;
+ }
+
+ /**
+ * Returns the contents of a possibly multi-part SMS.
+ *
+ * @return the list of PDUs
+ */
+ public @NonNull List<byte[]> getPdus() {
+ return mPduList;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ if (mPduList == null) {
+ dest.writeInt(NULL_LENGTH);
+ } else {
+ dest.writeInt(mPduList.size());
+ for (byte[] messagePdu : mPduList) {
+ dest.writeByteArray(messagePdu);
+ }
+ }
+ }
+
+ /**
+ * Constructs a {@link MessagePdu} from a {@link Parcel}.
+ */
+ public static final Parcelable.Creator<MessagePdu> CREATOR
+ = new Parcelable.Creator<MessagePdu>() {
+ @Override
+ public MessagePdu createFromParcel(Parcel source) {
+ int size = source.readInt();
+ List<byte[]> pduList;
+ if (size == NULL_LENGTH) {
+ pduList = null;
+ } else {
+ pduList = new ArrayList<>(size);
+ for (int i = 0; i < size; i++) {
+ pduList.add(source.createByteArray());
+ }
+ }
+ return new MessagePdu(pduList);
+ }
+
+ @Override
+ public MessagePdu[] newArray(int size) {
+ return new MessagePdu[size];
+ }
+ };
+}