• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.service.carrier;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SdkConstant;
23 import android.app.Service;
24 import android.content.Intent;
25 import android.net.Uri;
26 import android.os.IBinder;
27 import android.os.RemoteException;
28 
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 import java.util.List;
32 
33 /**
34  * A service that receives calls from the system when new SMS and MMS are
35  * sent or received.
36  * <p>To extend this class, you must declare the service in your manifest file with
37  * the {@link android.Manifest.permission#BIND_CARRIER_SERVICES} permission
38  * and include an intent filter with the {@link #SERVICE_INTERFACE} action. For example:</p>
39  * <pre>
40  * &lt;service android:name=".MyMessagingService"
41  *          android:label="&#64;string/service_name"
42  *          android:permission="android.permission.BIND_CARRIER_SERVICES">
43  *     &lt;intent-filter>
44  *         &lt;action android:name="android.service.carrier.CarrierMessagingService" />
45  *     &lt;/intent-filter>
46  * &lt;/service></pre>
47  */
48 public abstract class CarrierMessagingService extends Service {
49     /**
50      * The {@link android.content.Intent} that must be declared as handled by the service.
51      */
52     @SdkConstant(SdkConstant.SdkConstantType.SERVICE_ACTION)
53     public static final String SERVICE_INTERFACE
54             = "android.service.carrier.CarrierMessagingService";
55 
56     /**
57      * The default bitmask value passed to the callback of {@link #onReceiveTextSms} with all
58      * {@code RECEIVE_OPTIONS_x} flags cleared to indicate that the message should be kept and a
59      * new message notification should be shown.
60      *
61      * @see #RECEIVE_OPTIONS_DROP
62      * @see #RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE
63      */
64     public static final int RECEIVE_OPTIONS_DEFAULT = 0;
65 
66     /**
67      * Used to set the flag in the bitmask passed to the callback of {@link #onReceiveTextSms} to
68      * indicate that the inbound SMS should be dropped.
69      */
70     public static final int RECEIVE_OPTIONS_DROP = 0x1;
71 
72     /**
73      * Used to set the flag in the bitmask passed to the callback of {@link #onReceiveTextSms} to
74      * indicate that a new message notification should not be shown to the user when the
75      * credential-encrypted storage of the device is not available before the user unlocks the
76      * phone. It is only applicable to devices that support file-based encryption.
77      */
78     public static final int RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE = 0x2;
79 
80     /** @hide */
81     @IntDef(flag = true, prefix = { "RECEIVE_OPTIONS_" }, value = {
82             RECEIVE_OPTIONS_DEFAULT,
83             RECEIVE_OPTIONS_DROP,
84             RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE
85     })
86     @Retention(RetentionPolicy.SOURCE)
87     public @interface FilterCompleteResult{}
88 
89     /**
90      * Indicates that an SMS or MMS message was successfully sent.
91      */
92     public static final int SEND_STATUS_OK = 0;
93 
94     /**
95      * SMS/MMS sending failed. We should retry via the carrier network.
96      */
97     public static final int SEND_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
98 
99     /**
100      * SMS/MMS sending failed. We should not retry via the carrier network.
101      */
102     public static final int SEND_STATUS_ERROR = 2;
103 
104     /** @hide */
105     @IntDef(prefix = { "SEND_STATUS_" }, value = {
106             SEND_STATUS_OK,
107             SEND_STATUS_RETRY_ON_CARRIER_NETWORK,
108             SEND_STATUS_ERROR
109     })
110     @Retention(RetentionPolicy.SOURCE)
111     public @interface SendResult {}
112 
113     /**
114      * Successfully downloaded an MMS message.
115      */
116     public static final int DOWNLOAD_STATUS_OK = 0;
117 
118     /**
119      * MMS downloading failed. We should retry via the carrier network.
120      */
121     public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1;
122 
123     /**
124      * MMS downloading failed. We should not retry via the carrier network.
125      */
126     public static final int DOWNLOAD_STATUS_ERROR = 2;
127 
128     /** @hide */
129     @IntDef(prefix = { "DOWNLOAD_STATUS_" }, value = {
130             DOWNLOAD_STATUS_OK,
131             DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK,
132             DOWNLOAD_STATUS_ERROR
133     })
134     @Retention(RetentionPolicy.SOURCE)
135     public @interface DownloadResult {}
136 
137     /**
138      * Flag to request SMS delivery status report.
139      */
140     public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 0x1;
141 
142     /** @hide */
143     @IntDef(flag = true, prefix = { "SEND_FLAG_" }, value = {
144             SEND_FLAG_REQUEST_DELIVERY_STATUS
145     })
146     @Retention(RetentionPolicy.SOURCE)
147     public @interface SendRequest {}
148 
149     private final ICarrierMessagingWrapper mWrapper = new ICarrierMessagingWrapper();
150 
151     /**
152      * Override this method to filter inbound SMS messages.
153      *
154      * @param pdu the PDUs of the message
155      * @param format the format of the PDUs, typically "3gpp" or "3gpp2"
156      * @param destPort the destination port of a binary SMS, this will be -1 for text SMS
157      * @param subId SMS subscription ID of the SIM
158      * @param callback result callback. Call with {@code true} to keep an inbound SMS message and
159      *        deliver to SMS apps, and {@code false} to drop the message.
160      * @deprecated Use {@link #onReceiveTextSms} instead.
161      */
162     @Deprecated
onFilterSms(@onNull MessagePdu pdu, @NonNull String format, int destPort, int subId, @NonNull ResultCallback<Boolean> callback)163     public void onFilterSms(@NonNull MessagePdu pdu, @NonNull String format, int destPort,
164             int subId, @NonNull ResultCallback<Boolean> callback) {
165         // optional
166         try {
167             callback.onReceiveResult(true);
168         } catch (RemoteException ex) {
169         }
170     }
171 
172     /**
173      * Override this method to filter inbound SMS messages.
174      *
175      * <p>This method will be called once for every incoming text SMS. You can invoke the callback
176      * with a bitmask to tell the platform how to handle the SMS. For a SMS received on a
177      * file-based encryption capable device while the credential-encrypted storage is not available,
178      * this method will be called for the second time when the credential-encrypted storage becomes
179      * available after the user unlocks the phone, if the bit {@link #RECEIVE_OPTIONS_DROP} is not
180      * set when invoking the callback.
181      *
182      * @param pdu the PDUs of the message
183      * @param format the format of the PDUs, typically "3gpp" or "3gpp2"
184      * @param destPort the destination port of a binary SMS, this will be -1 for text SMS
185      * @param subId SMS subscription ID of the SIM
186      * @param callback result callback. Call with a bitmask integer to indicate how the incoming
187      *        text SMS should be handled by the platform. Use {@link #RECEIVE_OPTIONS_DROP} and
188      *        {@link #RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE}
189      *        to set the flags in the bitmask.
190      */
onReceiveTextSms(@onNull MessagePdu pdu, @NonNull String format, int destPort, int subId, @NonNull final ResultCallback<Integer> callback)191     public void onReceiveTextSms(@NonNull MessagePdu pdu, @NonNull String format,
192             int destPort, int subId, @NonNull final ResultCallback<Integer> callback) {
193         onFilterSms(pdu, format, destPort, subId, new ResultCallback<Boolean>() {
194             @Override
195             public void onReceiveResult(Boolean result) throws RemoteException {
196                 callback.onReceiveResult(result ? RECEIVE_OPTIONS_DEFAULT : RECEIVE_OPTIONS_DROP
197                     | RECEIVE_OPTIONS_SKIP_NOTIFY_WHEN_CREDENTIAL_PROTECTED_STORAGE_UNAVAILABLE);
198             }
199         });
200     }
201 
202     /**
203      * Override this method to intercept text SMSs sent from the device.
204      * @deprecated Override {@link #onSendTextSms} below instead.
205      *
206      * @param text the text to send
207      * @param subId SMS subscription ID of the SIM
208      * @param destAddress phone number of the recipient of the message
209      * @param callback result callback. Call with a {@link SendSmsResult}.
210      */
211     @Deprecated
onSendTextSms( @onNull String text, int subId, @NonNull String destAddress, @NonNull ResultCallback<SendSmsResult> callback)212     public void onSendTextSms(
213             @NonNull String text, int subId, @NonNull String destAddress,
214             @NonNull ResultCallback<SendSmsResult> callback) {
215         // optional
216         try {
217             callback.onReceiveResult(new SendSmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0));
218         } catch (RemoteException ex) {
219         }
220     }
221 
222     /**
223      * Override this method to intercept text SMSs sent from the device.
224      *
225      * @param text the text to send
226      * @param subId SMS subscription ID of the SIM
227      * @param destAddress phone number of the recipient of the message
228      * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
229      *        {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}.
230      * @param callback result callback. Call with a {@link SendSmsResult}.
231      */
onSendTextSms( @onNull String text, int subId, @NonNull String destAddress, int sendSmsFlag, @NonNull ResultCallback<SendSmsResult> callback)232     public void onSendTextSms(
233             @NonNull String text, int subId, @NonNull String destAddress,
234             int sendSmsFlag, @NonNull ResultCallback<SendSmsResult> callback) {
235         // optional
236         onSendTextSms(text, subId, destAddress, callback);
237     }
238 
239     /**
240      * Override this method to intercept binary SMSs sent from the device.
241      * @deprecated Override {@link #onSendDataSms} below instead.
242      *
243      * @param data the binary content
244      * @param subId SMS subscription ID of the SIM
245      * @param destAddress phone number of the recipient of the message
246      * @param destPort the destination port
247      * @param callback result callback. Call with a {@link SendSmsResult}.
248      */
249     @Deprecated
onSendDataSms(@onNull byte[] data, int subId, @NonNull String destAddress, int destPort, @NonNull ResultCallback<SendSmsResult> callback)250     public void onSendDataSms(@NonNull byte[] data, int subId,
251             @NonNull String destAddress, int destPort,
252             @NonNull ResultCallback<SendSmsResult> callback) {
253         // optional
254         try {
255             callback.onReceiveResult(new SendSmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0));
256         } catch (RemoteException ex) {
257         }
258     }
259 
260     /**
261      * Override this method to intercept binary SMSs sent from the device.
262      *
263      * @param data the binary content
264      * @param subId SMS subscription ID of the SIM
265      * @param destAddress phone number of the recipient of the message
266      * @param destPort the destination port
267      * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
268      *        {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}.
269      * @param callback result callback. Call with a {@link SendSmsResult}.
270      */
onSendDataSms(@onNull byte[] data, int subId, @NonNull String destAddress, int destPort, int sendSmsFlag, @NonNull ResultCallback<SendSmsResult> callback)271     public void onSendDataSms(@NonNull byte[] data, int subId,
272             @NonNull String destAddress, int destPort, int sendSmsFlag,
273             @NonNull ResultCallback<SendSmsResult> callback) {
274         // optional
275         onSendDataSms(data, subId, destAddress, destPort, callback);
276     }
277 
278     /**
279      * Override this method to intercept long SMSs sent from the device.
280      * @deprecated Override {@link #onSendMultipartTextSms} below instead.
281      *
282      * @param parts a {@link List} of the message parts
283      * @param subId SMS subscription ID of the SIM
284      * @param destAddress phone number of the recipient of the message
285      * @param callback result callback. Call with a {@link SendMultipartSmsResult}.
286      */
287     @Deprecated
onSendMultipartTextSms(@onNull List<String> parts, int subId, @NonNull String destAddress, @NonNull ResultCallback<SendMultipartSmsResult> callback)288     public void onSendMultipartTextSms(@NonNull List<String> parts,
289             int subId, @NonNull String destAddress,
290             @NonNull ResultCallback<SendMultipartSmsResult> callback) {
291         // optional
292         try {
293             callback.onReceiveResult(
294                     new SendMultipartSmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null));
295         } catch (RemoteException ex) {
296         }
297     }
298 
299     /**
300      * Override this method to intercept long SMSs sent from the device.
301      *
302      * @param parts a {@link List} of the message parts
303      * @param subId SMS subscription ID of the SIM
304      * @param destAddress phone number of the recipient of the message
305      * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and
306      *        {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}.
307      * @param callback result callback. Call with a {@link SendMultipartSmsResult}.
308      */
onSendMultipartTextSms(@onNull List<String> parts, int subId, @NonNull String destAddress, int sendSmsFlag, @NonNull ResultCallback<SendMultipartSmsResult> callback)309     public void onSendMultipartTextSms(@NonNull List<String> parts,
310             int subId, @NonNull String destAddress, int sendSmsFlag,
311             @NonNull ResultCallback<SendMultipartSmsResult> callback) {
312         // optional
313         onSendMultipartTextSms(parts, subId, destAddress, callback);
314     }
315 
316     /**
317      * Override this method to intercept MMSs sent from the device.
318      *
319      * @param pduUri the content provider URI of the PDU to send
320      * @param subId SMS subscription ID of the SIM
321      * @param location the optional URI to send this MMS PDU. If this is {code null},
322      *        the PDU should be sent to the default MMSC URL.
323      * @param callback result callback. Call with a {@link SendMmsResult}.
324      */
onSendMms(@onNull Uri pduUri, int subId, @Nullable Uri location, @NonNull ResultCallback<SendMmsResult> callback)325     public void onSendMms(@NonNull Uri pduUri, int subId,
326             @Nullable Uri location, @NonNull ResultCallback<SendMmsResult> callback) {
327         // optional
328         try {
329             callback.onReceiveResult(new SendMmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null));
330         } catch (RemoteException ex) {
331         }
332     }
333 
334     /**
335      * Override this method to download MMSs received.
336      *
337      * @param contentUri the content provider URI of the PDU to be downloaded.
338      * @param subId SMS subscription ID of the SIM
339      * @param location the URI of the message to be downloaded.
340      * @param callback result callback. Call with a status code which is one of
341      *        {@link #DOWNLOAD_STATUS_OK},
342      *        {@link #DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK}, or {@link #DOWNLOAD_STATUS_ERROR}.
343      */
onDownloadMms(@onNull Uri contentUri, int subId, @NonNull Uri location, @NonNull ResultCallback<Integer> callback)344     public void onDownloadMms(@NonNull Uri contentUri, int subId, @NonNull Uri location,
345             @NonNull ResultCallback<Integer> callback) {
346         // optional
347         try {
348             callback.onReceiveResult(DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK);
349         } catch (RemoteException ex) {
350         }
351     }
352 
353     @Override
onBind(@onNull Intent intent)354     public @Nullable IBinder onBind(@NonNull Intent intent) {
355         if (!SERVICE_INTERFACE.equals(intent.getAction())) {
356             return null;
357         }
358         return mWrapper;
359     }
360 
361     /**
362      * The result of sending an MMS.
363      */
364     public static final class SendMmsResult {
365         private int mSendStatus;
366         private byte[] mSendConfPdu;
367 
368         /**
369          * Constructs a SendMmsResult with the MMS send result, and the SendConf PDU.
370          *
371          * @param sendStatus send status, one of {@link #SEND_STATUS_OK},
372          *        {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and
373          *        {@link #SEND_STATUS_ERROR}
374          * @param sendConfPdu a possibly {code null} SendConf PDU, which confirms that the message
375          *        was sent. sendConfPdu is ignored if the {@code result} is not
376          *        {@link #SEND_STATUS_OK}.
377          */
SendMmsResult(int sendStatus, @Nullable byte[] sendConfPdu)378         public SendMmsResult(int sendStatus, @Nullable byte[] sendConfPdu) {
379             mSendStatus = sendStatus;
380             mSendConfPdu = sendConfPdu;
381         }
382 
383         /**
384          * Returns the send status of the just-sent MMS.
385          *
386          * @return the send status which is one of {@link #SEND_STATUS_OK},
387          *         {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}
388          */
getSendStatus()389         public int getSendStatus() {
390             return mSendStatus;
391         }
392 
393         /**
394          * Returns the SendConf PDU, which confirms that the message was sent.
395          *
396          * @return the SendConf PDU
397          */
getSendConfPdu()398         public @Nullable byte[] getSendConfPdu() {
399             return mSendConfPdu;
400         }
401     }
402 
403     /**
404      * The result of sending an SMS.
405      */
406     public static final class SendSmsResult {
407         private final int mSendStatus;
408         private final int mMessageRef;
409 
410         /**
411          * Constructs a SendSmsResult with the send status and message reference for the
412          * just-sent SMS.
413          *
414          * @param sendStatus send status, one of {@link #SEND_STATUS_OK},
415          *        {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}.
416          * @param messageRef message reference of the just-sent SMS. This field is applicable only
417          *        if send status is {@link #SEND_STATUS_OK}.
418          */
SendSmsResult(int sendStatus, int messageRef)419         public SendSmsResult(int sendStatus, int messageRef) {
420             mSendStatus = sendStatus;
421             mMessageRef = messageRef;
422         }
423 
424         /**
425          * Returns the message reference of the just-sent SMS.
426          *
427          * @return the message reference
428          */
getMessageRef()429         public int getMessageRef() {
430             return mMessageRef;
431         }
432 
433         /**
434          * Returns the send status of the just-sent SMS.
435          *
436          * @return the send status
437          */
getSendStatus()438         public int getSendStatus() {
439             return mSendStatus;
440         }
441     }
442 
443     /**
444      * The result of sending a multipart SMS.
445      */
446     public static final class SendMultipartSmsResult {
447         private final int mSendStatus;
448         private final int[] mMessageRefs;
449 
450         /**
451          * Constructs a SendMultipartSmsResult with the send status and message references for the
452          * just-sent multipart SMS.
453          *
454          * @param sendStatus send status, one of {@link #SEND_STATUS_OK},
455          *        {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}.
456          * @param messageRefs an array of message references, one for each part of the
457          *        multipart SMS. This field is applicable only if send status is
458          *        {@link #SEND_STATUS_OK}.
459          */
SendMultipartSmsResult(int sendStatus, @Nullable int[] messageRefs)460         public SendMultipartSmsResult(int sendStatus, @Nullable int[] messageRefs) {
461             mSendStatus = sendStatus;
462             mMessageRefs = messageRefs;
463         }
464 
465         /**
466          * Returns the message references of the just-sent multipart SMS.
467          *
468          * @return the message references, one for each part of the multipart SMS
469          */
getMessageRefs()470         public @Nullable int[] getMessageRefs() {
471             return mMessageRefs;
472         }
473 
474         /**
475          * Returns the send status of the just-sent SMS.
476          *
477          * @return the send status
478          */
getSendStatus()479         public int getSendStatus() {
480             return mSendStatus;
481         }
482     }
483 
484     /**
485      * A callback interface used to provide results asynchronously.
486      */
487     public interface ResultCallback<T> {
488         /**
489          * Invoked when the result is available.
490          *
491          * @param result the result
492          */
onReceiveResult(@onNull T result)493         public void onReceiveResult(@NonNull T result) throws RemoteException;
494     };
495 
496     /**
497      * A wrapper around ICarrierMessagingService to enable the carrier messaging app to implement
498      * methods it cares about in the {@link ICarrierMessagingService} interface.
499      */
500     private class ICarrierMessagingWrapper extends ICarrierMessagingService.Stub {
501         @Override
filterSms(MessagePdu pdu, String format, int destPort, int subId, final ICarrierMessagingCallback callback)502         public void filterSms(MessagePdu pdu, String format, int destPort,
503                               int subId, final ICarrierMessagingCallback callback) {
504             onReceiveTextSms(pdu, format, destPort, subId,
505                 new ResultCallback<Integer>() {
506                     @Override
507                     public void onReceiveResult(Integer options) throws RemoteException {
508                         callback.onFilterComplete(options);
509                     }
510                 });
511         }
512 
513         @Override
sendTextSms(String text, int subId, String destAddress, int sendSmsFlag, final ICarrierMessagingCallback callback)514         public void sendTextSms(String text, int subId, String destAddress,
515                 int sendSmsFlag, final ICarrierMessagingCallback callback) {
516             onSendTextSms(text, subId, destAddress, sendSmsFlag,
517                     new ResultCallback<SendSmsResult>() {
518                     @Override
519                     public void onReceiveResult(final SendSmsResult result) throws RemoteException {
520                         callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef());
521                     }
522                 });
523         }
524 
525         @Override
sendDataSms(byte[] data, int subId, String destAddress, int destPort, int sendSmsFlag, final ICarrierMessagingCallback callback)526         public void sendDataSms(byte[] data, int subId, String destAddress, int destPort,
527                 int sendSmsFlag, final ICarrierMessagingCallback callback) {
528             onSendDataSms(data, subId, destAddress, destPort, sendSmsFlag,
529                     new ResultCallback<SendSmsResult>() {
530                     @Override
531                     public void onReceiveResult(final SendSmsResult result) throws RemoteException {
532                         callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef());
533                     }
534                 });
535         }
536 
537         @Override
sendMultipartTextSms(List<String> parts, int subId, String destAddress, int sendSmsFlag, final ICarrierMessagingCallback callback)538         public void sendMultipartTextSms(List<String> parts, int subId, String destAddress,
539                 int sendSmsFlag, final ICarrierMessagingCallback callback) {
540             onSendMultipartTextSms(parts, subId, destAddress, sendSmsFlag,
541                         new ResultCallback<SendMultipartSmsResult>() {
542                                 @Override
543                                 public void onReceiveResult(final SendMultipartSmsResult result)
544                                         throws RemoteException {
545                                     callback.onSendMultipartSmsComplete(
546                                             result.getSendStatus(), result.getMessageRefs());
547                                 }
548                             });
549         }
550 
551         @Override
sendMms(Uri pduUri, int subId, Uri location, final ICarrierMessagingCallback callback)552         public void sendMms(Uri pduUri, int subId, Uri location,
553                 final ICarrierMessagingCallback callback) {
554             onSendMms(pduUri, subId, location, new ResultCallback<SendMmsResult>() {
555                     @Override
556                     public void onReceiveResult(final SendMmsResult result) throws RemoteException {
557                         callback.onSendMmsComplete(result.getSendStatus(), result.getSendConfPdu());
558                     }
559                 });
560         }
561 
562         @Override
downloadMms(Uri pduUri, int subId, Uri location, final ICarrierMessagingCallback callback)563         public void downloadMms(Uri pduUri, int subId, Uri location,
564                 final ICarrierMessagingCallback callback) {
565             onDownloadMms(pduUri, subId, location, new ResultCallback<Integer>() {
566                     @Override
567                     public void onReceiveResult(Integer result) throws RemoteException {
568                         callback.onDownloadMmsComplete(result);
569                     }
570                 });
571         }
572     }
573 }
574