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