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 * <service android:name=".MyMessagingService" 41 * android:label="@string/service_name" 42 * android:permission="android.permission.BIND_CARRIER_SERVICES"> 43 * <intent-filter> 44 * <action android:name="android.service.carrier.CarrierMessagingService" /> 45 * </intent-filter> 46 * </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