CarrierMessagingService.java revision e87e4f077c8f5dc8dc7b1b5cd68cbe8ca51f2396
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 17package android.service.carrier; 18 19import android.annotation.NonNull; 20import android.annotation.Nullable; 21import android.annotation.SdkConstant; 22import android.app.Service; 23import android.content.Intent; 24import android.net.Uri; 25import android.os.IBinder; 26import android.os.Parcel; 27import android.os.Parcelable; 28import android.os.RemoteException; 29 30import java.util.ArrayList; 31import 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_MESSAGING_SERVICE} 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_MESSAGING_SERVICE"> 43 * <intent-filter> 44 * <action android:name="android.service.carrier.CarrierMessagingService" /> 45 * </intent-filter> 46 * </service></pre> 47 */ 48public 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 * Indicates that an SMS or MMS message was successfully sent. 58 */ 59 public static final int SEND_STATUS_OK = 0; 60 61 /** 62 * SMS/MMS sending failed. We should retry via the carrier network. 63 */ 64 public static final int SEND_STATUS_RETRY_ON_CARRIER_NETWORK = 1; 65 66 /** 67 * SMS/MMS sending failed. We should not retry via the carrier network. 68 */ 69 public static final int SEND_STATUS_ERROR = 2; 70 71 /** 72 * Successfully downloaded an MMS message. 73 */ 74 public static final int DOWNLOAD_STATUS_OK = 0; 75 76 /** 77 * MMS downloading failed. We should retry via the carrier network. 78 */ 79 public static final int DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK = 1; 80 81 /** 82 * MMS downloading failed. We should not retry via the carrier network. 83 */ 84 public static final int DOWNLOAD_STATUS_ERROR = 2; 85 86 /** 87 * Flag to request SMS delivery status report. 88 */ 89 public static final int SEND_FLAG_REQUEST_DELIVERY_STATUS = 1; 90 91 private final ICarrierMessagingWrapper mWrapper = new ICarrierMessagingWrapper(); 92 93 /** 94 * Override this method to filter inbound SMS messages. 95 * 96 * @param pdu the PDUs of the message 97 * @param format the format of the PDUs, typically "3gpp" or "3gpp2" 98 * @param destPort the destination port of a binary SMS, this will be -1 for text SMS 99 * @param subId SMS subscription ID of the SIM 100 * @param callback result callback. Call with {@code true} to keep an inbound SMS message and 101 * deliver to SMS apps, and {@code false} to drop the message. 102 */ 103 public void onFilterSms(@NonNull MessagePdu pdu, @NonNull String format, int destPort, 104 int subId, @NonNull ResultCallback<Boolean> callback) { 105 // optional 106 try { 107 callback.onReceiveResult(true); 108 } catch (RemoteException ex) { 109 } 110 } 111 112 /** 113 * Override this method to intercept text SMSs sent from the device. 114 * @deprecated Override {@link #onSendTextSms} below instead. 115 * 116 * @param text the text to send 117 * @param subId SMS subscription ID of the SIM 118 * @param destAddress phone number of the recipient of the message 119 * @param callback result callback. Call with a {@link SendSmsResult}. 120 */ 121 @Deprecated 122 public void onSendTextSms( 123 @NonNull String text, int subId, @NonNull String destAddress, 124 @NonNull ResultCallback<SendSmsResult> callback) { 125 // optional 126 try { 127 callback.onReceiveResult(new SendSmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0)); 128 } catch (RemoteException ex) { 129 } 130 } 131 132 /** 133 * Override this method to intercept text SMSs sent from the device. 134 * 135 * @param text the text to send 136 * @param subId SMS subscription ID of the SIM 137 * @param destAddress phone number of the recipient of the message 138 * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and 139 * {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}. 140 * @param callback result callback. Call with a {@link SendSmsResult}. 141 */ 142 public void onSendTextSms( 143 @NonNull String text, int subId, @NonNull String destAddress, 144 int sendSmsFlag, @NonNull ResultCallback<SendSmsResult> callback) { 145 // optional 146 onSendTextSms(text, subId, destAddress, callback); 147 } 148 149 /** 150 * Override this method to intercept binary SMSs sent from the device. 151 * @deprecated Override {@link #onSendDataSms} below instead. 152 * 153 * @param data the binary content 154 * @param subId SMS subscription ID of the SIM 155 * @param destAddress phone number of the recipient of the message 156 * @param destPort the destination port 157 * @param callback result callback. Call with a {@link SendSmsResult}. 158 */ 159 @Deprecated 160 public void onSendDataSms(@NonNull byte[] data, int subId, 161 @NonNull String destAddress, int destPort, 162 @NonNull ResultCallback<SendSmsResult> callback) { 163 // optional 164 try { 165 callback.onReceiveResult(new SendSmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, 0)); 166 } catch (RemoteException ex) { 167 } 168 } 169 170 /** 171 * Override this method to intercept binary SMSs sent from the device. 172 * 173 * @param data the binary content 174 * @param subId SMS subscription ID of the SIM 175 * @param destAddress phone number of the recipient of the message 176 * @param destPort the destination port 177 * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and 178 * {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}. 179 * @param callback result callback. Call with a {@link SendSmsResult}. 180 */ 181 public void onSendDataSms(@NonNull byte[] data, int subId, 182 @NonNull String destAddress, int destPort, int sendSmsFlag, 183 @NonNull ResultCallback<SendSmsResult> callback) { 184 // optional 185 onSendDataSms(data, subId, destAddress, destPort, callback); 186 } 187 188 /** 189 * Override this method to intercept long SMSs sent from the device. 190 * @deprecated Override {@link #onSendMultipartTextSms} below instead. 191 * 192 * @param parts a {@link List} of the message parts 193 * @param subId SMS subscription ID of the SIM 194 * @param destAddress phone number of the recipient of the message 195 * @param callback result callback. Call with a {@link SendMultipartSmsResult}. 196 */ 197 @Deprecated 198 public void onSendMultipartTextSms(@NonNull List<String> parts, 199 int subId, @NonNull String destAddress, 200 @NonNull ResultCallback<SendMultipartSmsResult> callback) { 201 // optional 202 try { 203 callback.onReceiveResult( 204 new SendMultipartSmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null)); 205 } catch (RemoteException ex) { 206 } 207 } 208 209 /** 210 * Override this method to intercept long SMSs sent from the device. 211 * 212 * @param parts a {@link List} of the message parts 213 * @param subId SMS subscription ID of the SIM 214 * @param destAddress phone number of the recipient of the message 215 * @param sendSmsFlag Flag for sending SMS. Acceptable values are 0 and 216 * {@link #SEND_FLAG_REQUEST_DELIVERY_STATUS}. 217 * @param callback result callback. Call with a {@link SendMultipartSmsResult}. 218 */ 219 public void onSendMultipartTextSms(@NonNull List<String> parts, 220 int subId, @NonNull String destAddress, int sendSmsFlag, 221 @NonNull ResultCallback<SendMultipartSmsResult> callback) { 222 // optional 223 onSendMultipartTextSms(parts, subId, destAddress, callback); 224 } 225 226 /** 227 * Override this method to intercept MMSs sent from the device. 228 * 229 * @param pduUri the content provider URI of the PDU to send 230 * @param subId SMS subscription ID of the SIM 231 * @param location the optional URI to send this MMS PDU. If this is {code null}, 232 * the PDU should be sent to the default MMSC URL. 233 * @param callback result callback. Call with a {@link SendMmsResult}. 234 */ 235 public void onSendMms(@NonNull Uri pduUri, int subId, 236 @Nullable Uri location, @NonNull ResultCallback<SendMmsResult> callback) { 237 // optional 238 try { 239 callback.onReceiveResult(new SendMmsResult(SEND_STATUS_RETRY_ON_CARRIER_NETWORK, null)); 240 } catch (RemoteException ex) { 241 } 242 } 243 244 /** 245 * Override this method to download MMSs received. 246 * 247 * @param contentUri the content provider URI of the PDU to be downloaded. 248 * @param subId SMS subscription ID of the SIM 249 * @param location the URI of the message to be downloaded. 250 * @param callback result callback. Call with a status code which is one of 251 * {@link #DOWNLOAD_STATUS_OK}, 252 * {@link #DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK}, or {@link #DOWNLOAD_STATUS_ERROR}. 253 */ 254 public void onDownloadMms(@NonNull Uri contentUri, int subId, @NonNull Uri location, 255 @NonNull ResultCallback<Integer> callback) { 256 // optional 257 try { 258 callback.onReceiveResult(DOWNLOAD_STATUS_RETRY_ON_CARRIER_NETWORK); 259 } catch (RemoteException ex) { 260 } 261 } 262 263 @Override 264 public @Nullable IBinder onBind(@NonNull Intent intent) { 265 if (!SERVICE_INTERFACE.equals(intent.getAction())) { 266 return null; 267 } 268 return mWrapper; 269 } 270 271 /** 272 * The result of sending an MMS. 273 */ 274 public static final class SendMmsResult { 275 private int mSendStatus; 276 private byte[] mSendConfPdu; 277 278 /** 279 * Constructs a SendMmsResult with the MMS send result, and the SendConf PDU. 280 * 281 * @param sendStatus send status, one of {@link #SEND_STATUS_OK}, 282 * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and 283 * {@link #SEND_STATUS_ERROR} 284 * @param sendConfPdu a possibly {code null} SendConf PDU, which confirms that the message 285 * was sent. sendConfPdu is ignored if the {@code result} is not 286 * {@link #SEND_STATUS_OK}. 287 */ 288 public SendMmsResult(int sendStatus, @Nullable byte[] sendConfPdu) { 289 mSendStatus = sendStatus; 290 mSendConfPdu = sendConfPdu; 291 } 292 293 /** 294 * Returns the send status of the just-sent MMS. 295 * 296 * @return the send status which is one of {@link #SEND_STATUS_OK}, 297 * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR} 298 */ 299 public int getSendStatus() { 300 return mSendStatus; 301 } 302 303 /** 304 * Returns the SendConf PDU, which confirms that the message was sent. 305 * 306 * @return the SendConf PDU 307 */ 308 public @Nullable byte[] getSendConfPdu() { 309 return mSendConfPdu; 310 } 311 } 312 313 /** 314 * The result of sending an SMS. 315 */ 316 public static final class SendSmsResult { 317 private final int mSendStatus; 318 private final int mMessageRef; 319 320 /** 321 * Constructs a SendSmsResult with the send status and message reference for the 322 * just-sent SMS. 323 * 324 * @param sendStatus send status, one of {@link #SEND_STATUS_OK}, 325 * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}. 326 * @param messageRef message reference of the just-sent SMS. This field is applicable only 327 * if send status is {@link #SEND_STATUS_OK}. 328 */ 329 public SendSmsResult(int sendStatus, int messageRef) { 330 mSendStatus = sendStatus; 331 mMessageRef = messageRef; 332 } 333 334 /** 335 * Returns the message reference of the just-sent SMS. 336 * 337 * @return the message reference 338 */ 339 public int getMessageRef() { 340 return mMessageRef; 341 } 342 343 /** 344 * Returns the send status of the just-sent SMS. 345 * 346 * @return the send status 347 */ 348 public int getSendStatus() { 349 return mSendStatus; 350 } 351 } 352 353 /** 354 * The result of sending a multipart SMS. 355 */ 356 public static final class SendMultipartSmsResult { 357 private final int mSendStatus; 358 private final int[] mMessageRefs; 359 360 /** 361 * Constructs a SendMultipartSmsResult with the send status and message references for the 362 * just-sent multipart SMS. 363 * 364 * @param sendStatus send status, one of {@link #SEND_STATUS_OK}, 365 * {@link #SEND_STATUS_RETRY_ON_CARRIER_NETWORK}, and {@link #SEND_STATUS_ERROR}. 366 * @param messageRefs an array of message references, one for each part of the 367 * multipart SMS. This field is applicable only if send status is 368 * {@link #SEND_STATUS_OK}. 369 */ 370 public SendMultipartSmsResult(int sendStatus, @Nullable int[] messageRefs) { 371 mSendStatus = sendStatus; 372 mMessageRefs = messageRefs; 373 } 374 375 /** 376 * Returns the message references of the just-sent multipart SMS. 377 * 378 * @return the message references, one for each part of the multipart SMS 379 */ 380 public @Nullable int[] getMessageRefs() { 381 return mMessageRefs; 382 } 383 384 /** 385 * Returns the send status of the just-sent SMS. 386 * 387 * @return the send status 388 */ 389 public int getSendStatus() { 390 return mSendStatus; 391 } 392 } 393 394 /** 395 * A callback interface used to provide results asynchronously. 396 */ 397 public interface ResultCallback<T> { 398 /** 399 * Invoked when the result is available. 400 * 401 * @param result the result 402 */ 403 public void onReceiveResult(@NonNull T result) throws RemoteException; 404 }; 405 406 /** 407 * A wrapper around ICarrierMessagingService to enable the carrier messaging app to implement 408 * methods it cares about in the {@link ICarrierMessagingService} interface. 409 */ 410 private class ICarrierMessagingWrapper extends ICarrierMessagingService.Stub { 411 @Override 412 public void filterSms(MessagePdu pdu, String format, int destPort, 413 int subId, final ICarrierMessagingCallback callback) { 414 onFilterSms(pdu, format, destPort, subId, new ResultCallback<Boolean>() { 415 @Override 416 public void onReceiveResult(final Boolean result) throws RemoteException { 417 callback.onFilterComplete(result); 418 } 419 }); 420 } 421 422 @Override 423 public void sendTextSms(String text, int subId, String destAddress, 424 int sendSmsFlag, final ICarrierMessagingCallback callback) { 425 onSendTextSms(text, subId, destAddress, sendSmsFlag, 426 new ResultCallback<SendSmsResult>() { 427 @Override 428 public void onReceiveResult(final SendSmsResult result) throws RemoteException { 429 callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef()); 430 } 431 }); 432 } 433 434 @Override 435 public void sendDataSms(byte[] data, int subId, String destAddress, int destPort, 436 int sendSmsFlag, final ICarrierMessagingCallback callback) { 437 onSendDataSms(data, subId, destAddress, destPort, sendSmsFlag, 438 new ResultCallback<SendSmsResult>() { 439 @Override 440 public void onReceiveResult(final SendSmsResult result) throws RemoteException { 441 callback.onSendSmsComplete(result.getSendStatus(), result.getMessageRef()); 442 } 443 }); 444 } 445 446 @Override 447 public void sendMultipartTextSms(List<String> parts, int subId, String destAddress, 448 int sendSmsFlag, final ICarrierMessagingCallback callback) { 449 onSendMultipartTextSms(parts, subId, destAddress, sendSmsFlag, 450 new ResultCallback<SendMultipartSmsResult>() { 451 @Override 452 public void onReceiveResult(final SendMultipartSmsResult result) 453 throws RemoteException { 454 callback.onSendMultipartSmsComplete( 455 result.getSendStatus(), result.getMessageRefs()); 456 } 457 }); 458 } 459 460 @Override 461 public void sendMms(Uri pduUri, int subId, Uri location, 462 final ICarrierMessagingCallback callback) { 463 onSendMms(pduUri, subId, location, new ResultCallback<SendMmsResult>() { 464 @Override 465 public void onReceiveResult(final SendMmsResult result) throws RemoteException { 466 callback.onSendMmsComplete(result.getSendStatus(), result.getSendConfPdu()); 467 } 468 }); 469 } 470 471 @Override 472 public void downloadMms(Uri pduUri, int subId, Uri location, 473 final ICarrierMessagingCallback callback) { 474 onDownloadMms(pduUri, subId, location, new ResultCallback<Integer>() { 475 @Override 476 public void onReceiveResult(Integer result) throws RemoteException { 477 callback.onDownloadMmsComplete(result); 478 } 479 }); 480 } 481 } 482} 483