1 /* 2 * Copyright (C) 2006 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 com.android.internal.telephony; 18 19 import static android.Manifest.permission.SEND_SMS_NO_CONFIRMATION; 20 21 import static com.android.internal.telephony.IccSmsInterfaceManager.SMS_MESSAGE_PERIOD_NOT_SPECIFIED; 22 import static com.android.internal.telephony.IccSmsInterfaceManager.SMS_MESSAGE_PRIORITY_NOT_SPECIFIED; 23 import static com.android.internal.telephony.SmsResponse.NO_ERROR_CODE; 24 25 import android.annotation.UserIdInt; 26 import android.app.Activity; 27 import android.app.AlertDialog; 28 import android.app.PendingIntent; 29 import android.app.PendingIntent.CanceledException; 30 import android.compat.annotation.UnsupportedAppUsage; 31 import android.content.ContentResolver; 32 import android.content.ContentValues; 33 import android.content.Context; 34 import android.content.DialogInterface; 35 import android.content.Intent; 36 import android.content.pm.ApplicationInfo; 37 import android.content.pm.PackageInfo; 38 import android.content.pm.PackageManager; 39 import android.content.res.Resources; 40 import android.database.ContentObserver; 41 import android.net.Uri; 42 import android.os.AsyncResult; 43 import android.os.Binder; 44 import android.os.Build; 45 import android.os.Handler; 46 import android.os.Looper; 47 import android.os.Message; 48 import android.os.PersistableBundle; 49 import android.os.Process; 50 import android.os.SystemClock; 51 import android.os.UserHandle; 52 import android.provider.Settings; 53 import android.provider.Telephony; 54 import android.provider.Telephony.Sms; 55 import android.service.carrier.CarrierMessagingService; 56 import android.service.carrier.CarrierMessagingServiceWrapper; 57 import android.service.carrier.CarrierMessagingServiceWrapper.CarrierMessagingCallback; 58 import android.telephony.AnomalyReporter; 59 import android.telephony.CarrierConfigManager; 60 import android.telephony.PhoneNumberUtils; 61 import android.telephony.ServiceState; 62 import android.telephony.SmsManager; 63 import android.telephony.TelephonyManager; 64 import android.text.Html; 65 import android.text.Spanned; 66 import android.text.TextUtils; 67 import android.util.EventLog; 68 import android.util.IndentingPrintWriter; 69 import android.util.LocalLog; 70 import android.view.LayoutInflater; 71 import android.view.View; 72 import android.view.ViewGroup; 73 import android.view.WindowManager; 74 import android.widget.Button; 75 import android.widget.CheckBox; 76 import android.widget.CompoundButton; 77 import android.widget.TextView; 78 79 import com.android.internal.R; 80 import com.android.internal.annotations.VisibleForTesting; 81 import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails; 82 import com.android.internal.telephony.cdma.sms.UserData; 83 import com.android.telephony.Rlog; 84 85 import java.io.FileDescriptor; 86 import java.io.PrintWriter; 87 import java.util.ArrayList; 88 import java.util.Arrays; 89 import java.util.HashMap; 90 import java.util.List; 91 import java.util.Random; 92 import java.util.UUID; 93 import java.util.concurrent.atomic.AtomicBoolean; 94 import java.util.concurrent.atomic.AtomicInteger; 95 96 public abstract class SMSDispatcher extends Handler { 97 static final String TAG = "SMSDispatcher"; // accessed from inner class 98 static final boolean DBG = false; 99 private static final String SEND_NEXT_MSG_EXTRA = "SendNextMsg"; 100 private static final String MESSAGE_ID_EXTRA = "MessageId"; 101 protected static final String MAP_KEY_PDU = "pdu"; 102 protected static final String MAP_KEY_SMSC = "smsc"; 103 protected static final String MAP_KEY_DEST_ADDR = "destAddr"; 104 protected static final String MAP_KEY_SC_ADDR = "scAddr"; 105 protected static final String MAP_KEY_DEST_PORT = "destPort"; 106 protected static final String MAP_KEY_DATA = "data"; 107 protected static final String MAP_KEY_TEXT = "text"; 108 109 private static final int PREMIUM_RULE_USE_SIM = 1; 110 private static final int PREMIUM_RULE_USE_NETWORK = 2; 111 private static final int PREMIUM_RULE_USE_BOTH = 3; 112 private final AtomicInteger mPremiumSmsRule = new AtomicInteger(PREMIUM_RULE_USE_SIM); 113 private final SettingsObserver mSettingsObserver; 114 115 /** SMS send complete. */ 116 protected static final int EVENT_SEND_SMS_COMPLETE = 2; 117 118 /** Retry sending a previously failed SMS message */ 119 protected static final int EVENT_SEND_RETRY = 3; 120 121 /** Confirmation required for sending a large number of messages. */ 122 private static final int EVENT_SEND_LIMIT_REACHED_CONFIRMATION = 4; 123 124 /** Send the user confirmed SMS */ 125 static final int EVENT_SEND_CONFIRMED_SMS = 5; // accessed from inner class 126 127 /** Don't send SMS (user did not confirm). */ 128 static final int EVENT_STOP_SENDING = 6; // accessed from inner class 129 130 /** Don't send SMS for this app (User had already denied eariler.) */ 131 static final int EVENT_SENDING_NOT_ALLOWED = 7; 132 133 /** Confirmation required for third-party apps sending to an SMS short code. */ 134 private static final int EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE = 8; 135 136 /** Confirmation required for third-party apps sending to an SMS short code. */ 137 private static final int EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE = 9; 138 139 /** New status report received. */ 140 protected static final int EVENT_NEW_SMS_STATUS_REPORT = 10; 141 142 // other 143 protected static final int EVENT_NEW_ICC_SMS = 14; 144 protected static final int EVENT_ICC_CHANGED = 15; 145 protected static final int EVENT_GET_IMS_SERVICE = 16; 146 147 @UnsupportedAppUsage 148 protected Phone mPhone; 149 @UnsupportedAppUsage 150 protected final Context mContext; 151 @UnsupportedAppUsage 152 protected final ContentResolver mResolver; 153 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 154 protected final CommandsInterface mCi; 155 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 156 protected final TelephonyManager mTelephonyManager; 157 protected final LocalLog mLocalLog = new LocalLog(16); 158 159 /** Maximum number of times to retry sending a failed SMS. */ 160 protected static final int MAX_SEND_RETRIES = 3; 161 /** Delay before next send attempt on a failed SMS, in milliseconds. */ 162 @VisibleForTesting 163 public static final int SEND_RETRY_DELAY = 2000; 164 /** Message sending queue limit */ 165 private static final int MO_MSG_QUEUE_LIMIT = 5; 166 /** SMS anomaly uuid -- CarrierMessagingService did not respond */ 167 private static final UUID sAnomalyNoResponseFromCarrierMessagingService = 168 UUID.fromString("279d9fbc-462d-4fc2-802c-bf21ddd9dd90"); 169 /** SMS anomaly uuid -- CarrierMessagingService unexpected callback */ 170 private static final UUID sAnomalyUnexpectedCallback = 171 UUID.fromString("0103b6d2-ad07-4d86-9102-14341b9074ef"); 172 173 /** 174 * Message reference for a CONCATENATED_8_BIT_REFERENCE or 175 * CONCATENATED_16_BIT_REFERENCE message set. Should be 176 * incremented for each set of concatenated messages. 177 * Static field shared by all dispatcher objects. 178 */ 179 private static int sConcatenatedRef = new Random().nextInt(256); 180 181 protected SmsDispatchersController mSmsDispatchersController; 182 183 /** Number of outgoing SmsTrackers waiting for user confirmation. */ 184 private int mPendingTrackerCount; 185 186 /* Flags indicating whether the current device allows sms service */ 187 protected boolean mSmsCapable = true; 188 protected boolean mSmsSendDisabled; 189 190 @VisibleForTesting 191 public int mCarrierMessagingTimeout = 10 * 60 * 1000; //10 minutes 192 193 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getNextConcatenatedRef()194 protected static int getNextConcatenatedRef() { 195 sConcatenatedRef += 1; 196 return sConcatenatedRef; 197 } 198 199 /** 200 * Create a new SMS dispatcher. 201 * @param phone the Phone to use 202 */ SMSDispatcher(Phone phone, SmsDispatchersController smsDispatchersController)203 protected SMSDispatcher(Phone phone, SmsDispatchersController smsDispatchersController) { 204 mPhone = phone; 205 mSmsDispatchersController = smsDispatchersController; 206 mContext = phone.getContext(); 207 mResolver = mContext.getContentResolver(); 208 mCi = phone.mCi; 209 mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE); 210 mSettingsObserver = new SettingsObserver(this, mPremiumSmsRule, mContext); 211 mContext.getContentResolver().registerContentObserver(Settings.Global.getUriFor( 212 Settings.Global.SMS_SHORT_CODE_RULE), false, mSettingsObserver); 213 214 mSmsCapable = mContext.getResources().getBoolean( 215 com.android.internal.R.bool.config_sms_capable); 216 mSmsSendDisabled = !mTelephonyManager.getSmsSendCapableForPhone( 217 mPhone.getPhoneId(), mSmsCapable); 218 Rlog.d(TAG, "SMSDispatcher: ctor mSmsCapable=" + mSmsCapable + " format=" + getFormat() 219 + " mSmsSendDisabled=" + mSmsSendDisabled); 220 } 221 222 /** 223 * Observe the secure setting for updated premium sms determination rules 224 */ 225 private static class SettingsObserver extends ContentObserver { 226 private final AtomicInteger mPremiumSmsRule; 227 private final Context mContext; SettingsObserver(Handler handler, AtomicInteger premiumSmsRule, Context context)228 SettingsObserver(Handler handler, AtomicInteger premiumSmsRule, Context context) { 229 super(handler); 230 mPremiumSmsRule = premiumSmsRule; 231 mContext = context; 232 onChange(false); // load initial value; 233 } 234 235 @Override onChange(boolean selfChange)236 public void onChange(boolean selfChange) { 237 mPremiumSmsRule.set(Settings.Global.getInt(mContext.getContentResolver(), 238 Settings.Global.SMS_SHORT_CODE_RULE, PREMIUM_RULE_USE_SIM)); 239 } 240 } 241 242 /** Unregister for incoming SMS events. */ 243 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) dispose()244 public void dispose() { 245 mContext.getContentResolver().unregisterContentObserver(mSettingsObserver); 246 } 247 248 /** 249 * The format of the message PDU in the associated broadcast intent. 250 * This will be either "3gpp" for GSM/UMTS/LTE messages in 3GPP format 251 * or "3gpp2" for CDMA/LTE messages in 3GPP2 format. 252 * 253 * Note: All applications which handle incoming SMS messages by processing the 254 * SMS_RECEIVED_ACTION broadcast intent MUST pass the "format" extra from the intent 255 * into the new methods in {@link android.telephony.SmsMessage} which take an 256 * extra format parameter. This is required in order to correctly decode the PDU on 257 * devices which require support for both 3GPP and 3GPP2 formats at the same time, 258 * such as CDMA/LTE devices and GSM/CDMA world phones. 259 * 260 * @return the format of the message PDU 261 */ getFormat()262 protected abstract String getFormat(); 263 264 /** 265 * Called when a status report is received. This should correspond to a previously successful 266 * SEND. 267 * 268 * @param o AsyncResult object including a byte array for 3GPP status report PDU or SmsMessage 269 * object for 3GPP2 status report. 270 */ handleStatusReport(Object o)271 protected void handleStatusReport(Object o) { 272 Rlog.d(TAG, "handleStatusReport() called with no subclass."); 273 } 274 275 /** 276 * Handles events coming from the phone stack. Overridden from handler. 277 * 278 * @param msg the message to handle 279 */ 280 @Override handleMessage(Message msg)281 public void handleMessage(Message msg) { 282 switch (msg.what) { 283 case EVENT_SEND_SMS_COMPLETE: 284 // An outbound SMS has been successfully transferred, or failed. 285 handleSendComplete((AsyncResult) msg.obj); 286 break; 287 288 case EVENT_SEND_RETRY: 289 Rlog.d(TAG, "SMS retry.."); 290 sendRetrySms((SmsTracker) msg.obj); 291 break; 292 293 case EVENT_SEND_LIMIT_REACHED_CONFIRMATION: 294 handleReachSentLimit((SmsTracker[]) (msg.obj)); 295 break; 296 297 case EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE: 298 handleConfirmShortCode(false, (SmsTracker[]) (msg.obj)); 299 break; 300 301 case EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE: 302 handleConfirmShortCode(true, (SmsTracker[]) (msg.obj)); 303 break; 304 305 case EVENT_SEND_CONFIRMED_SMS: 306 { 307 SmsTracker[] trackers = (SmsTracker[]) msg.obj; 308 for (SmsTracker tracker : trackers) { 309 sendSms(tracker); 310 } 311 mPendingTrackerCount--; 312 break; 313 } 314 315 case EVENT_SENDING_NOT_ALLOWED: 316 { 317 SmsTracker[] trackers = (SmsTracker[]) msg.obj; 318 Rlog.d(TAG, "SMSDispatcher: EVENT_SENDING_NOT_ALLOWED - " 319 + "sending SHORT_CODE_NEVER_ALLOWED error code."); 320 handleSmsTrackersFailure( 321 trackers, SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED, NO_ERROR_CODE); 322 break; 323 } 324 325 case EVENT_STOP_SENDING: 326 { 327 SmsTracker[] trackers = (SmsTracker[]) msg.obj; 328 int error; 329 if (msg.arg1 == ConfirmDialogListener.SHORT_CODE_MSG) { 330 if (msg.arg2 == ConfirmDialogListener.NEVER_ALLOW) { 331 error = SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED; 332 Rlog.d(TAG, "SMSDispatcher: EVENT_STOP_SENDING - " 333 + "sending SHORT_CODE_NEVER_ALLOWED error code."); 334 } else { 335 error = SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED; 336 Rlog.d(TAG, "SMSDispatcher: EVENT_STOP_SENDING - " 337 + "sending SHORT_CODE_NOT_ALLOWED error code."); 338 } 339 } else if (msg.arg1 == ConfirmDialogListener.RATE_LIMIT) { 340 error = SmsManager.RESULT_ERROR_LIMIT_EXCEEDED; 341 Rlog.d(TAG, "SMSDispatcher: EVENT_STOP_SENDING - " 342 + "sending LIMIT_EXCEEDED error code."); 343 } else { 344 error = SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING; 345 Rlog.e(TAG, "SMSDispatcher: EVENT_STOP_SENDING - unexpected cases."); 346 } 347 348 handleSmsTrackersFailure(trackers, error, NO_ERROR_CODE); 349 mPendingTrackerCount--; 350 break; 351 } 352 353 case EVENT_NEW_SMS_STATUS_REPORT: 354 handleStatusReport(msg.obj); 355 break; 356 357 default: 358 Rlog.e(TAG, "handleMessage() ignoring message of unexpected type " + msg.what); 359 } 360 } 361 362 /** 363 * Use the carrier messaging service to send a data or text SMS. 364 */ 365 protected abstract class SmsSender extends Handler { 366 private static final int EVENT_TIMEOUT = 1; 367 // Initialized in sendSmsByCarrierApp 368 protected volatile CarrierMessagingCallback mSenderCallback; 369 protected final CarrierMessagingServiceWrapper mCarrierMessagingServiceWrapper = 370 new CarrierMessagingServiceWrapper(); 371 private String mCarrierPackageName; 372 SmsSender()373 protected SmsSender() { 374 super(Looper.getMainLooper()); 375 } 376 377 /** 378 * Bind to carrierPackageName to send message through it 379 */ sendSmsByCarrierApp(String carrierPackageName, CarrierMessagingCallback senderCallback)380 public synchronized void sendSmsByCarrierApp(String carrierPackageName, 381 CarrierMessagingCallback senderCallback) { 382 mCarrierPackageName = carrierPackageName; 383 mSenderCallback = senderCallback; 384 if (!mCarrierMessagingServiceWrapper.bindToCarrierMessagingService( 385 mContext, carrierPackageName, runnable -> runnable.run(), 386 ()->onServiceReady())) { 387 Rlog.e(TAG, "bindService() for carrier messaging service failed"); 388 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK); 389 } else { 390 Rlog.d(TAG, "bindService() for carrier messaging service succeeded"); 391 sendMessageDelayed(obtainMessage(EVENT_TIMEOUT), mCarrierMessagingTimeout); 392 } 393 } 394 395 /** 396 * Callback received from mCarrierPackageName on binding to it is done. 397 * NOTE: the implementations of this method must be synchronized to make sure it does not 398 * get called before {@link #sendSmsByCarrierApp} completes and {@link #EVENT_TIMEOUT} is 399 * posted 400 */ onServiceReady()401 public abstract void onServiceReady(); 402 403 /** 404 * Method to call message send callback with passed in result and default parameters 405 */ onSendComplete(@arrierMessagingService.SendResult int result)406 public abstract void onSendComplete(@CarrierMessagingService.SendResult int result); 407 408 /** 409 * Used to get the SmsTracker for single part messages 410 */ getSmsTracker()411 public abstract SmsTracker getSmsTracker(); 412 413 /** 414 * Used to get the SmsTrackers for multi part messages 415 */ getSmsTrackers()416 public abstract SmsTracker[] getSmsTrackers(); 417 418 @Override handleMessage(Message msg)419 public void handleMessage(Message msg) { 420 if (msg.what == EVENT_TIMEOUT) { 421 logWithLocalLog("handleMessage: No response from " + mCarrierPackageName 422 + " for " + mCarrierMessagingTimeout + " ms"); 423 AnomalyReporter.reportAnomaly(sAnomalyNoResponseFromCarrierMessagingService, 424 "No response from " + mCarrierPackageName, mPhone.getCarrierId()); 425 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK); 426 } else { 427 logWithLocalLog("handleMessage: received unexpected message " + msg.what); 428 } 429 } 430 removeTimeout()431 public void removeTimeout() { 432 removeMessages(EVENT_TIMEOUT); 433 } 434 } 435 logWithLocalLog(String logStr)436 private void logWithLocalLog(String logStr) { 437 mLocalLog.log(logStr); 438 Rlog.d(TAG, logStr); 439 } 440 441 /** 442 * Use the carrier messaging service to send a text SMS. 443 */ 444 protected final class TextSmsSender extends SmsSender { 445 private final SmsTracker mTracker; TextSmsSender(SmsTracker tracker)446 public TextSmsSender(SmsTracker tracker) { 447 super(); 448 mTracker = tracker; 449 } 450 451 @Override onServiceReady()452 public synchronized void onServiceReady() { 453 Rlog.d(TAG, "TextSmsSender::onServiceReady"); 454 HashMap<String, Object> map = mTracker.getData(); 455 String text = (String) map.get(MAP_KEY_TEXT); 456 457 if (text != null) { 458 try { 459 mCarrierMessagingServiceWrapper.sendTextSms( 460 text, 461 getSubId(), 462 mTracker.mDestAddress, 463 (mTracker.mDeliveryIntent != null) 464 ? CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS 465 : 0, 466 runnable -> runnable.run(), 467 mSenderCallback); 468 } catch (RuntimeException e) { 469 Rlog.e(TAG, "TextSmsSender::onServiceReady: Exception sending the SMS: " 470 + e.getMessage()); 471 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK); 472 } 473 } else { 474 Rlog.d(TAG, "TextSmsSender::onServiceReady: text == null"); 475 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK); 476 } 477 } 478 479 @Override onSendComplete(int result)480 public void onSendComplete(int result) { 481 mSenderCallback.onSendSmsComplete(result, 0 /* messageRef */); 482 } 483 484 @Override getSmsTracker()485 public SmsTracker getSmsTracker() { 486 return mTracker; 487 } 488 489 @Override getSmsTrackers()490 public SmsTracker[] getSmsTrackers() { 491 Rlog.e(TAG, "getSmsTrackers: Unexpected call for TextSmsSender"); 492 return null; 493 } 494 } 495 496 /** 497 * Use the carrier messaging service to send a data SMS. 498 */ 499 protected final class DataSmsSender extends SmsSender { 500 private final SmsTracker mTracker; DataSmsSender(SmsTracker tracker)501 public DataSmsSender(SmsTracker tracker) { 502 super(); 503 mTracker = tracker; 504 } 505 506 @Override onServiceReady()507 public synchronized void onServiceReady() { 508 Rlog.d(TAG, "DataSmsSender::onServiceReady"); 509 HashMap<String, Object> map = mTracker.getData(); 510 byte[] data = (byte[]) map.get(MAP_KEY_DATA); 511 int destPort = (int) map.get(MAP_KEY_DEST_PORT); 512 513 if (data != null) { 514 try { 515 mCarrierMessagingServiceWrapper.sendDataSms( 516 data, 517 getSubId(), 518 mTracker.mDestAddress, 519 destPort, 520 (mTracker.mDeliveryIntent != null) 521 ? CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS 522 : 0, 523 runnable -> runnable.run(), 524 mSenderCallback); 525 } catch (RuntimeException e) { 526 Rlog.e(TAG, "DataSmsSender::onServiceReady: Exception sending the SMS: " 527 + e 528 + " " + SmsController.formatCrossStackMessageId(mTracker.mMessageId)); 529 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK); 530 } 531 } else { 532 Rlog.d(TAG, "DataSmsSender::onServiceReady: data == null"); 533 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK); 534 } 535 } 536 537 @Override onSendComplete(int result)538 public void onSendComplete(int result) { 539 mSenderCallback.onSendSmsComplete(result, 0 /* messageRef */); 540 } 541 542 @Override getSmsTracker()543 public SmsTracker getSmsTracker() { 544 return mTracker; 545 } 546 547 @Override getSmsTrackers()548 public SmsTracker[] getSmsTrackers() { 549 Rlog.e(TAG, "getSmsTrackers: Unexpected call for DataSmsSender"); 550 return null; 551 } 552 } 553 554 /** 555 * Callback for TextSmsSender and DataSmsSender from the carrier messaging service. 556 * Once the result is ready, the carrier messaging service connection is disposed. 557 */ 558 protected final class SmsSenderCallback implements CarrierMessagingCallback { 559 private final SmsSender mSmsSender; 560 private boolean mCallbackCalled = false; 561 SmsSenderCallback(SmsSender smsSender)562 public SmsSenderCallback(SmsSender smsSender) { 563 mSmsSender = smsSender; 564 } 565 566 /** 567 * This method should be called only once. 568 */ 569 @Override onSendSmsComplete(int result, int messageRef)570 public void onSendSmsComplete(int result, int messageRef) { 571 Rlog.d(TAG, "onSendSmsComplete: result=" + result + " messageRef=" + messageRef); 572 if (mCallbackCalled) { 573 logWithLocalLog("onSendSmsComplete: unexpected call"); 574 AnomalyReporter.reportAnomaly(sAnomalyUnexpectedCallback, 575 "Unexpected onSendSmsComplete", mPhone.getCarrierId()); 576 return; 577 } 578 mCallbackCalled = true; 579 final long identity = Binder.clearCallingIdentity(); 580 try { 581 mSmsSender.mCarrierMessagingServiceWrapper.disconnect(); 582 processSendSmsResponse(mSmsSender.getSmsTracker(), result, messageRef); 583 mSmsSender.removeTimeout(); 584 } finally { 585 Binder.restoreCallingIdentity(identity); 586 } 587 } 588 589 @Override onSendMultipartSmsComplete(int result, int[] messageRefs)590 public void onSendMultipartSmsComplete(int result, int[] messageRefs) { 591 Rlog.e(TAG, "Unexpected onSendMultipartSmsComplete call with result: " + result); 592 } 593 594 @Override onReceiveSmsComplete(int result)595 public void onReceiveSmsComplete(int result) { 596 Rlog.e(TAG, "Unexpected onReceiveSmsComplete call with result: " + result); 597 } 598 599 @Override onSendMmsComplete(int result, byte[] sendConfPdu)600 public void onSendMmsComplete(int result, byte[] sendConfPdu) { 601 Rlog.e(TAG, "Unexpected onSendMmsComplete call with result: " + result); 602 } 603 604 @Override onDownloadMmsComplete(int result)605 public void onDownloadMmsComplete(int result) { 606 Rlog.e(TAG, "Unexpected onDownloadMmsComplete call with result: " + result); 607 } 608 } 609 610 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) processSendSmsResponse(SmsTracker tracker, int result, int messageRef)611 private void processSendSmsResponse(SmsTracker tracker, int result, int messageRef) { 612 if (tracker == null) { 613 Rlog.e(TAG, "processSendSmsResponse: null tracker"); 614 return; 615 } 616 617 SmsResponse smsResponse = new SmsResponse(messageRef, null /* ackPdu */, NO_ERROR_CODE, 618 tracker.mMessageId); 619 620 switch (result) { 621 case CarrierMessagingService.SEND_STATUS_OK: 622 Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService " 623 + "succeeded. " 624 + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 625 sendMessage(obtainMessage(EVENT_SEND_SMS_COMPLETE, 626 new AsyncResult(tracker, 627 smsResponse, 628 null /* exception*/))); 629 break; 630 case CarrierMessagingService.SEND_STATUS_ERROR: 631 Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService" 632 + " failed. " 633 + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 634 sendMessage(obtainMessage(EVENT_SEND_SMS_COMPLETE, 635 new AsyncResult(tracker, smsResponse, 636 new CommandException(CommandException.Error.GENERIC_FAILURE)))); 637 break; 638 case CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK: 639 Rlog.d(TAG, "processSendSmsResponse: Sending SMS by CarrierMessagingService failed." 640 + " Retry on carrier network. " 641 + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 642 sendSubmitPdu(tracker); 643 break; 644 default: 645 Rlog.d(TAG, "processSendSmsResponse: Unknown result " + result + " Retry on carrier" 646 + " network. " 647 + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 648 sendSubmitPdu(tracker); 649 } 650 } 651 652 /** 653 * Use the carrier messaging service to send a multipart text SMS. 654 */ 655 private final class MultipartSmsSender extends SmsSender { 656 private final List<String> mParts; 657 public final SmsTracker[] mTrackers; 658 MultipartSmsSender(ArrayList<String> parts, SmsTracker[] trackers)659 MultipartSmsSender(ArrayList<String> parts, SmsTracker[] trackers) { 660 super(); 661 mParts = parts; 662 mTrackers = trackers; 663 } 664 665 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) sendSmsByCarrierApp(String carrierPackageName, MultipartSmsSenderCallback senderCallback)666 void sendSmsByCarrierApp(String carrierPackageName, 667 MultipartSmsSenderCallback senderCallback) { 668 super.sendSmsByCarrierApp(carrierPackageName, senderCallback); 669 } 670 671 @Override onServiceReady()672 public synchronized void onServiceReady() { 673 Rlog.d(TAG, "MultipartSmsSender::onServiceReady"); 674 boolean statusReportRequested = false; 675 for (SmsTracker tracker : mTrackers) { 676 if (tracker.mDeliveryIntent != null) { 677 statusReportRequested = true; 678 break; 679 } 680 } 681 682 try { 683 mCarrierMessagingServiceWrapper.sendMultipartTextSms( 684 mParts, 685 getSubId(), 686 mTrackers[0].mDestAddress, 687 statusReportRequested 688 ? CarrierMessagingService.SEND_FLAG_REQUEST_DELIVERY_STATUS 689 : 0, 690 runnable -> runnable.run(), 691 mSenderCallback); 692 } catch (RuntimeException e) { 693 Rlog.e(TAG, "MultipartSmsSender::onServiceReady: Exception sending the SMS: " + e); 694 onSendComplete(CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK); 695 } 696 } 697 698 @Override onSendComplete(int result)699 public void onSendComplete(int result) { 700 mSenderCallback.onSendMultipartSmsComplete(result, null /* messageRefs */); 701 } 702 703 @Override getSmsTracker()704 public SmsTracker getSmsTracker() { 705 Rlog.e(TAG, "getSmsTracker: Unexpected call for MultipartSmsSender"); 706 return null; 707 } 708 709 @Override getSmsTrackers()710 public SmsTracker[] getSmsTrackers() { 711 return mTrackers; 712 } 713 } 714 715 /** 716 * Callback for MultipartSmsSender from the carrier messaging service. 717 * Once the result is ready, the carrier messaging service connection is disposed. 718 */ 719 private final class MultipartSmsSenderCallback implements CarrierMessagingCallback { 720 private final MultipartSmsSender mSmsSender; 721 private boolean mCallbackCalled = false; 722 MultipartSmsSenderCallback(MultipartSmsSender smsSender)723 MultipartSmsSenderCallback(MultipartSmsSender smsSender) { 724 mSmsSender = smsSender; 725 } 726 727 @Override onSendSmsComplete(int result, int messageRef)728 public void onSendSmsComplete(int result, int messageRef) { 729 Rlog.e(TAG, "Unexpected onSendSmsComplete call with result: " + result); 730 } 731 732 /** 733 * This method should be called only once. 734 */ 735 @Override onSendMultipartSmsComplete(int result, int[] messageRefs)736 public void onSendMultipartSmsComplete(int result, int[] messageRefs) { 737 Rlog.d(TAG, "onSendMultipartSmsComplete: result=" + result + " messageRefs=" 738 + Arrays.toString(messageRefs)); 739 if (mCallbackCalled) { 740 logWithLocalLog("onSendMultipartSmsComplete: unexpected call"); 741 AnomalyReporter.reportAnomaly(sAnomalyUnexpectedCallback, 742 "Unexpected onSendMultipartSmsComplete", mPhone.getCarrierId()); 743 return; 744 } 745 mCallbackCalled = true; 746 mSmsSender.removeTimeout(); 747 mSmsSender.mCarrierMessagingServiceWrapper.disconnect(); 748 749 if (mSmsSender.mTrackers == null) { 750 Rlog.e(TAG, "Unexpected onSendMultipartSmsComplete call with null trackers."); 751 return; 752 } 753 754 final long identity = Binder.clearCallingIdentity(); 755 try { 756 processSendMultipartSmsResponse(mSmsSender.mTrackers, result, messageRefs); 757 } finally { 758 Binder.restoreCallingIdentity(identity); 759 } 760 } 761 762 @Override onReceiveSmsComplete(int result)763 public void onReceiveSmsComplete(int result) { 764 Rlog.e(TAG, "Unexpected onReceiveSmsComplete call with result: " + result); 765 } 766 767 @Override onSendMmsComplete(int result, byte[] sendConfPdu)768 public void onSendMmsComplete(int result, byte[] sendConfPdu) { 769 Rlog.e(TAG, "Unexpected onSendMmsComplete call with result: " + result); 770 } 771 772 @Override onDownloadMmsComplete(int result)773 public void onDownloadMmsComplete(int result) { 774 Rlog.e(TAG, "Unexpected onDownloadMmsComplete call with result: " + result); 775 } 776 } 777 processSendMultipartSmsResponse( SmsTracker[] trackers, int result, int[] messageRefs)778 private void processSendMultipartSmsResponse( 779 SmsTracker[] trackers, int result, int[] messageRefs) { 780 if (trackers == null) { 781 Rlog.e(TAG, "processSendMultipartSmsResponse: null trackers"); 782 return; 783 } 784 785 switch (result) { 786 case CarrierMessagingService.SEND_STATUS_OK: 787 Rlog.d(TAG, "processSendMultipartSmsResponse: Sending SMS by " 788 + "CarrierMessagingService succeeded. " 789 + SmsController.formatCrossStackMessageId(trackers[0].mMessageId)); 790 // Sending a multi-part SMS by CarrierMessagingService successfully completed. 791 // Send EVENT_SEND_SMS_COMPLETE for all the parts one by one. 792 for (int i = 0; i < trackers.length; i++) { 793 int messageRef = 0; 794 if (messageRefs != null && messageRefs.length > i) { 795 messageRef = messageRefs[i]; 796 } 797 sendMessage( 798 obtainMessage( 799 EVENT_SEND_SMS_COMPLETE, 800 new AsyncResult( 801 trackers[i], 802 new SmsResponse( 803 messageRef, null /* ackPdu */, NO_ERROR_CODE), 804 null /* exception */))); 805 } 806 break; 807 case CarrierMessagingService.SEND_STATUS_ERROR: 808 Rlog.d(TAG, "processSendMultipartSmsResponse: Sending SMS by " 809 + "CarrierMessagingService failed. " 810 + SmsController.formatCrossStackMessageId(trackers[0].mMessageId)); 811 // Sending a multi-part SMS by CarrierMessagingService failed. 812 // Send EVENT_SEND_SMS_COMPLETE with GENERIC_FAILURE for all the parts one by one. 813 for (int i = 0; i < trackers.length; i++) { 814 int messageRef = 0; 815 if (messageRefs != null && messageRefs.length > i) { 816 messageRef = messageRefs[i]; 817 } 818 sendMessage( 819 obtainMessage( 820 EVENT_SEND_SMS_COMPLETE, 821 new AsyncResult( 822 trackers[i], 823 new SmsResponse( 824 messageRef, null /* ackPdu */, NO_ERROR_CODE), 825 new CommandException( 826 CommandException.Error.GENERIC_FAILURE)))); 827 } 828 break; 829 case CarrierMessagingService.SEND_STATUS_RETRY_ON_CARRIER_NETWORK: 830 Rlog.d(TAG, "processSendMultipartSmsResponse: Sending SMS by " 831 + "CarrierMessagingService failed. Retry on carrier network. " 832 + SmsController.formatCrossStackMessageId(trackers[0].mMessageId)); 833 // All the parts for a multi-part SMS are handled together for retry. It helps to 834 // check user confirmation once also if needed. 835 sendSubmitPdu(trackers); 836 break; 837 default: 838 Rlog.d(TAG, "processSendMultipartSmsResponse: Unknown result " + result 839 + ". Retry on carrier network. " 840 + SmsController.formatCrossStackMessageId(trackers[0].mMessageId)); 841 sendSubmitPdu(trackers); 842 } 843 } 844 845 /** Send a single SMS PDU. */ 846 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) sendSubmitPdu(SmsTracker tracker)847 private void sendSubmitPdu(SmsTracker tracker) { 848 sendSubmitPdu(new SmsTracker[] {tracker}); 849 } 850 851 /** Send a multi-part SMS PDU. Usually just calls {@link sendRawPdu}. */ sendSubmitPdu(SmsTracker[] trackers)852 private void sendSubmitPdu(SmsTracker[] trackers) { 853 if (shouldBlockSmsForEcbm()) { 854 Rlog.d(TAG, "Block SMS in Emergency Callback mode"); 855 handleSmsTrackersFailure(trackers, SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY, 856 NO_ERROR_CODE); 857 } else { 858 sendRawPdu(trackers); 859 } 860 } 861 862 /** 863 * @return true if MO SMS should be blocked for Emergency Callback Mode. 864 */ shouldBlockSmsForEcbm()865 protected abstract boolean shouldBlockSmsForEcbm(); 866 867 /** 868 * Called when SMS send completes. Broadcasts a sentIntent on success. 869 * On failure, either sets up retries or broadcasts a sentIntent with 870 * the failure in the result code. 871 * 872 * @param ar AsyncResult passed into the message handler. ar.result should 873 * an SmsResponse instance if send was successful. ar.userObj 874 * should be an SmsTracker instance. 875 */ handleSendComplete(AsyncResult ar)876 protected void handleSendComplete(AsyncResult ar) { 877 SmsTracker tracker = (SmsTracker) ar.userObj; 878 PendingIntent sentIntent = tracker.mSentIntent; 879 SmsResponse smsResponse = (SmsResponse) ar.result; 880 881 if (smsResponse != null) { 882 tracker.mMessageRef = smsResponse.mMessageRef; 883 } else { 884 Rlog.d(TAG, "SmsResponse was null"); 885 } 886 887 if (ar.exception == null) { 888 if (DBG) { 889 Rlog.d(TAG, "SMS send complete. Broadcasting intent: " + sentIntent 890 + " " + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 891 } 892 893 if (tracker.mDeliveryIntent != null) { 894 // Expecting a status report. Put this tracker to the map. 895 mSmsDispatchersController.putDeliveryPendingTracker(tracker); 896 } 897 tracker.onSent(mContext); 898 mPhone.notifySmsSent(tracker.mDestAddress); 899 900 mPhone.getSmsStats().onOutgoingSms( 901 tracker.mImsRetry > 0 /* isOverIms */, 902 SmsConstants.FORMAT_3GPP2.equals(getFormat()), 903 false /* fallbackToCs */, 904 SmsManager.RESULT_ERROR_NONE, 905 tracker.mMessageId, 906 tracker.isFromDefaultSmsApplication(mContext), 907 tracker.getInterval()); 908 } else { 909 if (DBG) { 910 Rlog.d(TAG, "SMS send failed " 911 + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 912 } 913 914 int ss = mPhone.getServiceState().getState(); 915 int error = rilErrorToSmsManagerResult( 916 ((CommandException) (ar.exception)).getCommandError(), tracker); 917 918 if (tracker.mImsRetry > 0 && ss != ServiceState.STATE_IN_SERVICE) { 919 // This is retry after failure over IMS but voice is not available. 920 // Set retry to max allowed, so no retry is sent and cause 921 // SmsManager.RESULT_ERROR_GENERIC_FAILURE to be returned to app. 922 tracker.mRetryCount = MAX_SEND_RETRIES; 923 924 Rlog.d(TAG, "handleSendComplete: Skipping retry: " 925 + " isIms()=" + isIms() 926 + " mRetryCount=" + tracker.mRetryCount 927 + " mImsRetry=" + tracker.mImsRetry 928 + " mMessageRef=" + tracker.mMessageRef 929 + " SS= " + mPhone.getServiceState().getState() 930 + " " + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 931 } 932 933 // if sms over IMS is not supported on data and voice is not available... 934 if (!isIms() && ss != ServiceState.STATE_IN_SERVICE) { 935 tracker.onFailed(mContext, getNotInServiceError(ss), NO_ERROR_CODE); 936 mPhone.getSmsStats().onOutgoingSms( 937 tracker.mImsRetry > 0 /* isOverIms */, 938 SmsConstants.FORMAT_3GPP2.equals(getFormat()), 939 false /* fallbackToCs */, 940 getNotInServiceError(ss), 941 tracker.mMessageId, 942 tracker.isFromDefaultSmsApplication(mContext), 943 tracker.getInterval()); 944 } else if (error == SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY 945 && tracker.mRetryCount < MAX_SEND_RETRIES) { 946 // Retry after a delay if needed. 947 // TODO: According to TS 23.040, 9.2.3.6, we should resend 948 // with the same TP-MR as the failed message, and 949 // TP-RD set to 1. However, we don't have a means of 950 // knowing the MR for the failed message (EF_SMSstatus 951 // may or may not have the MR corresponding to this 952 // message, depending on the failure). Also, in some 953 // implementations this retry is handled by the baseband. 954 tracker.mRetryCount++; 955 int errorCode = (smsResponse != null) ? smsResponse.mErrorCode : NO_ERROR_CODE; 956 Message retryMsg = obtainMessage(EVENT_SEND_RETRY, tracker); 957 sendMessageDelayed(retryMsg, SEND_RETRY_DELAY); 958 mPhone.getSmsStats().onOutgoingSms( 959 tracker.mImsRetry > 0 /* isOverIms */, 960 SmsConstants.FORMAT_3GPP2.equals(getFormat()), 961 false /* fallbackToCs */, 962 SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY, 963 errorCode, 964 tracker.mMessageId, 965 tracker.isFromDefaultSmsApplication(mContext), 966 tracker.getInterval()); 967 } else { 968 int errorCode = (smsResponse != null) ? smsResponse.mErrorCode : NO_ERROR_CODE; 969 tracker.onFailed(mContext, error, errorCode); 970 mPhone.getSmsStats().onOutgoingSms( 971 tracker.mImsRetry > 0 /* isOverIms */, 972 SmsConstants.FORMAT_3GPP2.equals(getFormat()), 973 false /* fallbackToCs */, 974 error, 975 errorCode, 976 tracker.mMessageId, 977 tracker.isFromDefaultSmsApplication(mContext), 978 tracker.getInterval()); 979 } 980 } 981 } 982 983 @SmsManager.Result rilErrorToSmsManagerResult(CommandException.Error rilError, SmsTracker tracker)984 private static int rilErrorToSmsManagerResult(CommandException.Error rilError, 985 SmsTracker tracker) { 986 switch (rilError) { 987 case RADIO_NOT_AVAILABLE: 988 return SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE; 989 case SMS_FAIL_RETRY: 990 return SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY; 991 case NETWORK_REJECT: 992 return SmsManager.RESULT_RIL_NETWORK_REJECT; 993 case INVALID_STATE: 994 return SmsManager.RESULT_RIL_INVALID_STATE; 995 case INVALID_ARGUMENTS: 996 return SmsManager.RESULT_RIL_INVALID_ARGUMENTS; 997 case NO_MEMORY: 998 return SmsManager.RESULT_RIL_NO_MEMORY; 999 case REQUEST_RATE_LIMITED: 1000 return SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED; 1001 case INVALID_SMS_FORMAT: 1002 return SmsManager.RESULT_RIL_INVALID_SMS_FORMAT; 1003 case SYSTEM_ERR: 1004 return SmsManager.RESULT_RIL_SYSTEM_ERR; 1005 case ENCODING_ERR: 1006 return SmsManager.RESULT_RIL_ENCODING_ERR; 1007 case MODEM_ERR: 1008 return SmsManager.RESULT_RIL_MODEM_ERR; 1009 case NETWORK_ERR: 1010 return SmsManager.RESULT_RIL_NETWORK_ERR; 1011 case INTERNAL_ERR: 1012 return SmsManager.RESULT_RIL_INTERNAL_ERR; 1013 case REQUEST_NOT_SUPPORTED: 1014 return SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED; 1015 case INVALID_MODEM_STATE: 1016 return SmsManager.RESULT_RIL_INVALID_MODEM_STATE; 1017 case NETWORK_NOT_READY: 1018 return SmsManager.RESULT_RIL_NETWORK_NOT_READY; 1019 case OPERATION_NOT_ALLOWED: 1020 return SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED; 1021 case NO_RESOURCES: 1022 return SmsManager.RESULT_RIL_NO_RESOURCES; 1023 case REQUEST_CANCELLED: 1024 return SmsManager.RESULT_RIL_CANCELLED; 1025 case SIM_ABSENT: 1026 return SmsManager.RESULT_RIL_SIM_ABSENT; 1027 case FDN_CHECK_FAILURE: 1028 return SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE; 1029 case SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED: 1030 return SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED; 1031 case ACCESS_BARRED: 1032 return SmsManager.RESULT_RIL_ACCESS_BARRED; 1033 case BLOCKED_DUE_TO_CALL: 1034 return SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL; 1035 default: 1036 Rlog.d(TAG, "rilErrorToSmsManagerResult: " + rilError + " " 1037 + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 1038 return SmsManager.RESULT_RIL_GENERIC_ERROR; 1039 } 1040 } 1041 1042 /** 1043 * @param ss service state 1044 * @return The result error based on input service state for not in service error 1045 */ 1046 @SmsManager.Result getNotInServiceError(int ss)1047 protected static int getNotInServiceError(int ss) { 1048 if (ss == ServiceState.STATE_POWER_OFF) { 1049 return SmsManager.RESULT_ERROR_RADIO_OFF; 1050 } 1051 return SmsManager.RESULT_ERROR_NO_SERVICE; 1052 } 1053 1054 /** 1055 * Send a data based SMS to a specific application port. 1056 * 1057 * @param callingPackage the package name of the calling app 1058 * @param destAddr the address to send the message to 1059 * @param scAddr is the service center address or null to use 1060 * the current default SMSC 1061 * @param destPort the port to deliver the message to 1062 * @param data the body of the message to send 1063 * @param sentIntent if not NULL this <code>PendingIntent</code> is 1064 * broadcast when the message is successfully sent, or failed. 1065 * The result code will be <code>Activity.RESULT_OK<code> for success, 1066 * or one of these errors:<br> 1067 * <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br> 1068 * <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br> 1069 * <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br> 1070 * <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br> 1071 * <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br> 1072 * <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br> 1073 * <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br> 1074 * <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br> 1075 * <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br> 1076 * <code>SmsManager.RESULT_NETWORK_REJECT</code><br> 1077 * <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br> 1078 * <code>SmsManager.RESULT_INVALID_STATE</code><br> 1079 * <code>SmsManager.RESULT_NO_MEMORY</code><br> 1080 * <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br> 1081 * <code>SmsManager.RESULT_SYSTEM_ERROR</code><br> 1082 * <code>SmsManager.RESULT_MODEM_ERROR</code><br> 1083 * <code>SmsManager.RESULT_NETWORK_ERROR</code><br> 1084 * <code>SmsManager.RESULT_ENCODING_ERROR</code><br> 1085 * <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br> 1086 * <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br> 1087 * <code>SmsManager.RESULT_INTERNAL_ERROR</code><br> 1088 * <code>SmsManager.RESULT_NO_RESOURCES</code><br> 1089 * <code>SmsManager.RESULT_CANCELLED</code><br> 1090 * <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br> 1091 * <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br> 1092 * <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br> 1093 * <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br> 1094 * <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br> 1095 * <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br> 1096 * <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br> 1097 * <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br> 1098 * <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br> 1099 * <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br> 1100 * <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br> 1101 * <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br> 1102 * <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br> 1103 * <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br> 1104 * <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br> 1105 * <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br> 1106 * <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br> 1107 * <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br> 1108 * <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br> 1109 * <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br> 1110 * <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br> 1111 * <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br> 1112 * <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br> 1113 * <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br> 1114 * <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br> 1115 * <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br> 1116 * <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br> 1117 * <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br> 1118 * <code>SmsManager.RESULT_RIL_CANCELLED</code><br> 1119 * <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br> 1120 * <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br> 1121 * <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br> 1122 * <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br> 1123 * For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors, 1124 * the sentIntent may include the extra "errorCode" containing a radio technology specific 1125 * value, generally only useful for troubleshooting.<br> 1126 * The per-application based SMS control checks sentIntent. If sentIntent 1127 * is NULL the caller will be checked against all unknown applications, 1128 * which cause smaller number of SMS to be sent in checking period. 1129 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 1130 * broadcast when the message is delivered to the recipient. The 1131 * raw pdu of the status report is in the extended data ("pdu"). 1132 */ 1133 @UnsupportedAppUsage sendData(String callingPackage, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm)1134 protected void sendData(String callingPackage, String destAddr, String scAddr, int destPort, 1135 byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm) { 1136 SmsMessageBase.SubmitPduBase pdu = getSubmitPdu( 1137 scAddr, destAddr, destPort, data, (deliveryIntent != null)); 1138 if (pdu != null) { 1139 HashMap map = getSmsTrackerMap(destAddr, scAddr, destPort, data, pdu); 1140 SmsTracker tracker = getSmsTracker(callingPackage, map, sentIntent, deliveryIntent, 1141 getFormat(), null /*messageUri*/, false /*expectMore*/, 1142 null /*fullMessageText*/, false /*isText*/, 1143 true /*persistMessage*/, isForVvm, 0L /* messageId */); 1144 1145 if (!sendSmsByCarrierApp(true /* isDataSms */, tracker)) { 1146 sendSubmitPdu(tracker); 1147 } 1148 } else { 1149 Rlog.e(TAG, "SMSDispatcher.sendData(): getSubmitPdu() returned null"); 1150 triggerSentIntentForFailure(sentIntent); 1151 } 1152 } 1153 1154 /** 1155 * Send a text based SMS. 1156 * 1157 * @param destAddr the address to send the message to 1158 * @param scAddr is the service center address or null to use 1159 * the current default SMSC 1160 * @param text the body of the message to send 1161 * @param sentIntent if not NULL this <code>PendingIntent</code> is 1162 * broadcast when the message is successfully sent, or failed. 1163 * The result code will be <code>Activity.RESULT_OK<code> for success, 1164 * or one of these errors:<br> 1165 * <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br> 1166 * <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br> 1167 * <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br> 1168 * <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br> 1169 * <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br> 1170 * <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br> 1171 * <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br> 1172 * <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br> 1173 * <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br> 1174 * <code>SmsManager.RESULT_NETWORK_REJECT</code><br> 1175 * <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br> 1176 * <code>SmsManager.RESULT_INVALID_STATE</code><br> 1177 * <code>SmsManager.RESULT_NO_MEMORY</code><br> 1178 * <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br> 1179 * <code>SmsManager.RESULT_SYSTEM_ERROR</code><br> 1180 * <code>SmsManager.RESULT_MODEM_ERROR</code><br> 1181 * <code>SmsManager.RESULT_NETWORK_ERROR</code><br> 1182 * <code>SmsManager.RESULT_ENCODING_ERROR</code><br> 1183 * <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br> 1184 * <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br> 1185 * <code>SmsManager.RESULT_INTERNAL_ERROR</code><br> 1186 * <code>SmsManager.RESULT_NO_RESOURCES</code><br> 1187 * <code>SmsManager.RESULT_CANCELLED</code><br> 1188 * <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br> 1189 * <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br> 1190 * <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br> 1191 * <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br> 1192 * <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br> 1193 * <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br> 1194 * <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br> 1195 * <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br> 1196 * <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br> 1197 * <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br> 1198 * <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br> 1199 * <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br> 1200 * <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br> 1201 * <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br> 1202 * <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br> 1203 * <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br> 1204 * <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br> 1205 * <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br> 1206 * <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br> 1207 * <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br> 1208 * <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br> 1209 * <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br> 1210 * <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br> 1211 * <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br> 1212 * <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br> 1213 * <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br> 1214 * <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br> 1215 * <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br> 1216 * <code>SmsManager.RESULT_RIL_CANCELLED</code><br> 1217 * <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br> 1218 * <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br> 1219 * <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br> 1220 * <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br> 1221 * For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors, 1222 * the sentIntent may include the extra "errorCode" containing a radio technology specific 1223 * value, generally only useful for troubleshooting.<br> 1224 * The per-application based SMS control checks sentIntent. If sentIntent 1225 * is NULL the caller will be checked against all unknown applications, 1226 * which cause smaller number of SMS to be sent in checking period. 1227 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 1228 * broadcast when the message is delivered to the recipient. The 1229 * @param messageUri optional URI of the message if it is already stored in the system 1230 * @param callingPkg the calling package name 1231 * @param persistMessage whether to save the sent message into SMS DB for a 1232 * non-default SMS app. 1233 * 1234 * @param priority Priority level of the message 1235 * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 1236 * --------------------------------- 1237 * PRIORITY | Level of Priority 1238 * --------------------------------- 1239 * '00' | Normal 1240 * '01' | Interactive 1241 * '10' | Urgent 1242 * '11' | Emergency 1243 * ---------------------------------- 1244 * Any Other values included Negative considered as Invalid Priority Indicator of the message. 1245 * @param expectMore is a boolean to indicate the sending messages through same link or not. 1246 * @param validityPeriod Validity Period of the message in mins. 1247 * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. 1248 * Validity Period(Minimum) -> 5 mins 1249 * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). 1250 * Any Other values included Negative considered as Invalid Validity Period of the message. 1251 * @param messageId An id that uniquely identifies the message requested to be sent. 1252 * Used for logging and diagnostics purposes. The id may be NULL. 1253 */ sendText(String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri, String callingPkg, boolean persistMessage, int priority, boolean expectMore, int validityPeriod, boolean isForVvm, long messageId)1254 public void sendText(String destAddr, String scAddr, String text, 1255 PendingIntent sentIntent, PendingIntent deliveryIntent, Uri messageUri, 1256 String callingPkg, boolean persistMessage, int priority, 1257 boolean expectMore, int validityPeriod, boolean isForVvm, 1258 long messageId) { 1259 Rlog.d(TAG, "sendText id: " + SmsController.formatCrossStackMessageId(messageId)); 1260 SmsMessageBase.SubmitPduBase pdu = getSubmitPdu( 1261 scAddr, destAddr, text, (deliveryIntent != null), null, priority, validityPeriod); 1262 if (pdu != null) { 1263 HashMap map = getSmsTrackerMap(destAddr, scAddr, text, pdu); 1264 SmsTracker tracker = getSmsTracker(callingPkg, map, sentIntent, deliveryIntent, 1265 getFormat(), messageUri, expectMore, text, true /*isText*/, 1266 persistMessage, priority, validityPeriod, isForVvm, messageId); 1267 1268 if (!sendSmsByCarrierApp(false /* isDataSms */, tracker)) { 1269 sendSubmitPdu(tracker); 1270 } 1271 } else { 1272 Rlog.e(TAG, "SmsDispatcher.sendText(): getSubmitPdu() returned null " 1273 + SmsController.formatCrossStackMessageId(messageId)); 1274 triggerSentIntentForFailure(sentIntent); 1275 } 1276 } 1277 triggerSentIntentForFailure(PendingIntent sentIntent)1278 private void triggerSentIntentForFailure(PendingIntent sentIntent) { 1279 if (sentIntent != null) { 1280 try { 1281 sentIntent.send(SmsManager.RESULT_ERROR_GENERIC_FAILURE); 1282 } catch (CanceledException ex) { 1283 Rlog.e(TAG, "Intent has been canceled!"); 1284 } 1285 } 1286 } 1287 triggerSentIntentForFailure(List<PendingIntent> sentIntents)1288 private void triggerSentIntentForFailure(List<PendingIntent> sentIntents) { 1289 if (sentIntents == null) { 1290 return; 1291 } 1292 1293 for (PendingIntent sentIntent : sentIntents) { 1294 triggerSentIntentForFailure(sentIntent); 1295 } 1296 } 1297 sendSmsByCarrierApp(boolean isDataSms, SmsTracker tracker )1298 private boolean sendSmsByCarrierApp(boolean isDataSms, SmsTracker tracker ) { 1299 String carrierPackage = getCarrierAppPackageName(); 1300 if (carrierPackage != null) { 1301 Rlog.d(TAG, "Found carrier package " + carrierPackage); 1302 SmsSender smsSender; 1303 if (isDataSms) { 1304 smsSender = new DataSmsSender(tracker); 1305 } else { 1306 smsSender = new TextSmsSender(tracker); 1307 } 1308 smsSender.sendSmsByCarrierApp(carrierPackage, new SmsSenderCallback(smsSender)); 1309 return true; 1310 } 1311 1312 return false; 1313 } 1314 getSubmitPdu(String scAddr, String destAddr, String message, boolean statusReportRequested, SmsHeader smsHeader, int priority, int validityPeriod)1315 protected abstract SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr, 1316 String message, boolean statusReportRequested, SmsHeader smsHeader, 1317 int priority, int validityPeriod); 1318 getSubmitPdu(String scAddr, String destAddr, int destPort, byte[] message, boolean statusReportRequested)1319 protected abstract SmsMessageBase.SubmitPduBase getSubmitPdu(String scAddr, String destAddr, 1320 int destPort, byte[] message, boolean statusReportRequested); 1321 1322 /** 1323 * Calculate the number of septets needed to encode the message. This function should only be 1324 * called for individual segments of multipart message. 1325 * 1326 * @param messageBody the message to encode 1327 * @param use7bitOnly ignore (but still count) illegal characters if true 1328 * @return TextEncodingDetails 1329 */ 1330 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) calculateLength(CharSequence messageBody, boolean use7bitOnly)1331 protected abstract TextEncodingDetails calculateLength(CharSequence messageBody, 1332 boolean use7bitOnly); 1333 1334 /** 1335 * Send a multi-part text based SMS. 1336 * 1337 * @param destAddr the address to send the message to 1338 * @param scAddr is the service center address or null to use 1339 * the current default SMSC 1340 * @param parts an <code>ArrayList</code> of strings that, in order, 1341 * comprise the original message 1342 * @param sentIntents if not null, an <code>ArrayList</code> of 1343 * <code>PendingIntent</code>s (one for each message part) that is 1344 * broadcast when the corresponding message part has been sent. 1345 * The result code will be <code>Activity.RESULT_OK<code> for success, 1346 * or one of these errors: 1347 * <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br> 1348 * <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br> 1349 * <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br> 1350 * <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br> 1351 * <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br> 1352 * <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br> 1353 * <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br> 1354 * <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br> 1355 * <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br> 1356 * <code>SmsManager.RESULT_NETWORK_REJECT</code><br> 1357 * <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br> 1358 * <code>SmsManager.RESULT_INVALID_STATE</code><br> 1359 * <code>SmsManager.RESULT_NO_MEMORY</code><br> 1360 * <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br> 1361 * <code>SmsManager.RESULT_SYSTEM_ERROR</code><br> 1362 * <code>SmsManager.RESULT_MODEM_ERROR</code><br> 1363 * <code>SmsManager.RESULT_NETWORK_ERROR</code><br> 1364 * <code>SmsManager.RESULT_ENCODING_ERROR</code><br> 1365 * <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br> 1366 * <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br> 1367 * <code>SmsManager.RESULT_INTERNAL_ERROR</code><br> 1368 * <code>SmsManager.RESULT_NO_RESOURCES</code><br> 1369 * <code>SmsManager.RESULT_CANCELLED</code><br> 1370 * <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br> 1371 * <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br> 1372 * <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br> 1373 * <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br> 1374 * <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br> 1375 * <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br> 1376 * <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br> 1377 * <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br> 1378 * <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br> 1379 * <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br> 1380 * <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br> 1381 * <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br> 1382 * <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br> 1383 * <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br> 1384 * <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br> 1385 * <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br> 1386 * <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br> 1387 * <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br> 1388 * <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br> 1389 * <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br> 1390 * <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br> 1391 * <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br> 1392 * <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br> 1393 * <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br> 1394 * <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br> 1395 * <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br> 1396 * <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br> 1397 * <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br> 1398 * <code>SmsManager.RESULT_RIL_CANCELLED</code><br> 1399 * <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br> 1400 * <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br> 1401 * <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br> 1402 * <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br> 1403 * For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors, 1404 * the sentIntent may include the extra "errorCode" containing a radio technology specific 1405 * value, generally only useful for troubleshooting.<br> 1406 * The per-application based SMS control checks sentIntent. If sentIntent 1407 * is NULL the caller will be checked against all unknown applications, 1408 * which cause smaller number of SMS to be sent in checking period. 1409 * @param deliveryIntents if not null, an <code>ArrayList</code> of 1410 * <code>PendingIntent</code>s (one for each message part) that is 1411 * broadcast when the corresponding message part has been delivered 1412 * to the recipient. The raw pdu of the status report is in the 1413 * @param messageUri optional URI of the message if it is already stored in the system 1414 * @param callingPkg the calling package name 1415 * @param persistMessage whether to save the sent message into SMS DB for a 1416 * non-default SMS app. 1417 * @param priority Priority level of the message 1418 * Refer specification See 3GPP2 C.S0015-B, v2.0, table 4.5.9-1 1419 * --------------------------------- 1420 * PRIORITY | Level of Priority 1421 * --------------------------------- 1422 * '00' | Normal 1423 * '01' | Interactive 1424 * '10' | Urgent 1425 * '11' | Emergency 1426 * ---------------------------------- 1427 * Any Other values included Negative considered as Invalid Priority Indicator of the message. 1428 * @param expectMore is a boolean to indicate the sending messages through same link or not. 1429 * @param validityPeriod Validity Period of the message in mins. 1430 * Refer specification 3GPP TS 23.040 V6.8.1 section 9.2.3.12.1. 1431 * Validity Period(Minimum) -> 5 mins 1432 * Validity Period(Maximum) -> 635040 mins(i.e.63 weeks). 1433 * Any Other values included Negative considered as Invalid Validity Period of the message. 1434 */ 1435 @VisibleForTesting(visibility = VisibleForTesting.Visibility.PROTECTED) sendMultipartText(String destAddr, String scAddr, ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, ArrayList<PendingIntent> deliveryIntents, Uri messageUri, String callingPkg, boolean persistMessage, int priority, boolean expectMore, int validityPeriod, long messageId)1436 public void sendMultipartText(String destAddr, String scAddr, 1437 ArrayList<String> parts, ArrayList<PendingIntent> sentIntents, 1438 ArrayList<PendingIntent> deliveryIntents, Uri messageUri, String callingPkg, 1439 boolean persistMessage, int priority, boolean expectMore, int validityPeriod, 1440 long messageId) { 1441 final String fullMessageText = getMultipartMessageText(parts); 1442 int refNumber = getNextConcatenatedRef() & 0x00FF; 1443 int encoding = SmsConstants.ENCODING_UNKNOWN; 1444 int msgCount = parts.size(); 1445 if (msgCount < 1) { 1446 triggerSentIntentForFailure(sentIntents); 1447 return; 1448 } 1449 1450 TextEncodingDetails[] encodingForParts = new TextEncodingDetails[msgCount]; 1451 for (int i = 0; i < msgCount; i++) { 1452 TextEncodingDetails details = calculateLength(parts.get(i), false); 1453 if (encoding != details.codeUnitSize 1454 && (encoding == SmsConstants.ENCODING_UNKNOWN 1455 || encoding == SmsConstants.ENCODING_7BIT)) { 1456 encoding = details.codeUnitSize; 1457 } 1458 encodingForParts[i] = details; 1459 } 1460 1461 SmsTracker[] trackers = new SmsTracker[msgCount]; 1462 1463 // States to track at the message level (for all parts) 1464 final AtomicInteger unsentPartCount = new AtomicInteger(msgCount); 1465 final AtomicBoolean anyPartFailed = new AtomicBoolean(false); 1466 1467 for (int i = 0; i < msgCount; i++) { 1468 SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef(); 1469 concatRef.refNumber = refNumber; 1470 concatRef.seqNumber = i + 1; // 1-based sequence 1471 concatRef.msgCount = msgCount; 1472 // TODO: We currently set this to true since our messaging app will never 1473 // send more than 255 parts (it converts the message to MMS well before that). 1474 // However, we should support 3rd party messaging apps that might need 16-bit 1475 // references 1476 // Note: It's not sufficient to just flip this bit to true; it will have 1477 // ripple effects (several calculations assume 8-bit ref). 1478 concatRef.isEightBits = true; 1479 SmsHeader smsHeader = new SmsHeader(); 1480 smsHeader.concatRef = concatRef; 1481 1482 // Set the national language tables for 3GPP 7-bit encoding, if enabled. 1483 if (encoding == SmsConstants.ENCODING_7BIT) { 1484 smsHeader.languageTable = encodingForParts[i].languageTable; 1485 smsHeader.languageShiftTable = encodingForParts[i].languageShiftTable; 1486 } 1487 1488 PendingIntent sentIntent = null; 1489 if (sentIntents != null && sentIntents.size() > i) { 1490 sentIntent = sentIntents.get(i); 1491 } 1492 1493 PendingIntent deliveryIntent = null; 1494 if (deliveryIntents != null && deliveryIntents.size() > i) { 1495 deliveryIntent = deliveryIntents.get(i); 1496 } 1497 1498 trackers[i] = 1499 getNewSubmitPduTracker(callingPkg, destAddr, scAddr, parts.get(i), smsHeader, 1500 encoding, sentIntent, deliveryIntent, (i == (msgCount - 1)), 1501 unsentPartCount, anyPartFailed, messageUri, 1502 fullMessageText, priority, expectMore, validityPeriod, messageId); 1503 if (trackers[i] == null) { 1504 triggerSentIntentForFailure(sentIntents); 1505 return; 1506 } 1507 trackers[i].mPersistMessage = persistMessage; 1508 } 1509 1510 String carrierPackage = getCarrierAppPackageName(); 1511 if (carrierPackage != null) { 1512 Rlog.d(TAG, "Found carrier package " + carrierPackage 1513 + " " 1514 + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers))); 1515 MultipartSmsSender smsSender = new MultipartSmsSender(parts, trackers); 1516 smsSender.sendSmsByCarrierApp(carrierPackage, 1517 new MultipartSmsSenderCallback(smsSender)); 1518 } else { 1519 Rlog.v(TAG, "No carrier package. " 1520 + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers))); 1521 sendSubmitPdu(trackers); 1522 } 1523 } 1524 getMultiTrackermessageId(SmsTracker[] trackers)1525 private long getMultiTrackermessageId(SmsTracker[] trackers) { 1526 if (trackers.length == 0) { 1527 return 0L; 1528 } 1529 return trackers[0].mMessageId; 1530 } 1531 1532 /** 1533 * Create a new SubmitPdu and return the SMS tracker. 1534 */ getNewSubmitPduTracker(String callingPackage, String destinationAddress, String scAddress, String message, SmsHeader smsHeader, int encoding, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart, AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri, String fullMessageText, int priority, boolean expectMore, int validityPeriod, long messageId)1535 private SmsTracker getNewSubmitPduTracker(String callingPackage, String destinationAddress, 1536 String scAddress, String message, SmsHeader smsHeader, int encoding, 1537 PendingIntent sentIntent, PendingIntent deliveryIntent, boolean lastPart, 1538 AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri, 1539 String fullMessageText, int priority, boolean expectMore, int validityPeriod, 1540 long messageId) { 1541 if (isCdmaMo()) { 1542 UserData uData = new UserData(); 1543 uData.payloadStr = message; 1544 uData.userDataHeader = smsHeader; 1545 if (encoding == SmsConstants.ENCODING_7BIT) { 1546 uData.msgEncoding = isAscii7bitSupportedForLongMessage() 1547 ? UserData.ENCODING_7BIT_ASCII : UserData.ENCODING_GSM_7BIT_ALPHABET; 1548 Rlog.d(TAG, "Message encoding for proper 7 bit: " + uData.msgEncoding); 1549 } else { // assume UTF-16 1550 uData.msgEncoding = UserData.ENCODING_UNICODE_16; 1551 } 1552 uData.msgEncodingSet = true; 1553 1554 /* By setting the statusReportRequested bit only for the 1555 * last message fragment, this will result in only one 1556 * callback to the sender when that last fragment delivery 1557 * has been acknowledged. */ 1558 //TODO FIX 1559 SmsMessageBase.SubmitPduBase submitPdu = 1560 com.android.internal.telephony.cdma.SmsMessage.getSubmitPdu(destinationAddress, 1561 uData, (deliveryIntent != null) && lastPart, priority); 1562 1563 if (submitPdu != null) { 1564 HashMap map = getSmsTrackerMap(destinationAddress, scAddress, 1565 message, submitPdu); 1566 return getSmsTracker(callingPackage, map, sentIntent, deliveryIntent, 1567 getFormat(), unsentPartCount, anyPartFailed, messageUri, smsHeader, 1568 (!lastPart || expectMore), fullMessageText, true /*isText*/, 1569 true /*persistMessage*/, priority, validityPeriod, false /* isForVvm */, 1570 messageId); 1571 } else { 1572 Rlog.e(TAG, "CdmaSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned " 1573 + "null " + SmsController.formatCrossStackMessageId(messageId)); 1574 return null; 1575 } 1576 } else { 1577 SmsMessageBase.SubmitPduBase pdu = 1578 com.android.internal.telephony.gsm.SmsMessage.getSubmitPdu(scAddress, 1579 destinationAddress, message, deliveryIntent != null, 1580 SmsHeader.toByteArray(smsHeader), encoding, smsHeader.languageTable, 1581 smsHeader.languageShiftTable, validityPeriod); 1582 if (pdu != null) { 1583 HashMap map = getSmsTrackerMap(destinationAddress, scAddress, 1584 message, pdu); 1585 return getSmsTracker(callingPackage, map, sentIntent, 1586 deliveryIntent, getFormat(), unsentPartCount, anyPartFailed, messageUri, 1587 smsHeader, (!lastPart || expectMore), fullMessageText, true /*isText*/, 1588 false /*persistMessage*/, priority, validityPeriod, false /* isForVvm */, 1589 messageId); 1590 } else { 1591 Rlog.e(TAG, "GsmSMSDispatcher.getNewSubmitPduTracker(): getSubmitPdu() returned " 1592 + "null " + SmsController.formatCrossStackMessageId(messageId)); 1593 return null; 1594 } 1595 } 1596 } 1597 1598 /** 1599 * Send a single or a multi-part SMS 1600 * 1601 * @param trackers each tracker will contain: 1602 * -smsc the SMSC to send the message through, or NULL for the 1603 * default SMSC 1604 * -pdu the raw PDU to send 1605 * -sentIntent if not NULL this <code>Intent</code> is 1606 * broadcast when the message is successfully sent, or failed. 1607 * The result code will be <code>Activity.RESULT_OK<code> for success, 1608 * or one of these errors: 1609 * <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code><br> 1610 * <code>SmsManager.RESULT_ERROR_RADIO_OFF</code><br> 1611 * <code>SmsManager.RESULT_ERROR_NULL_PDU</code><br> 1612 * <code>SmsManager.RESULT_ERROR_NO_SERVICE</code><br> 1613 * <code>SmsManager.RESULT_ERROR_LIMIT_EXCEEDED</code><br> 1614 * <code>SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE</code><br> 1615 * <code>SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED</code><br> 1616 * <code>SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED</code><br> 1617 * <code>SmsManager.RESULT_RADIO_NOT_AVAILABLE</code><br> 1618 * <code>SmsManager.RESULT_NETWORK_REJECT</code><br> 1619 * <code>SmsManager.RESULT_INVALID_ARGUMENTS</code><br> 1620 * <code>SmsManager.RESULT_INVALID_STATE</code><br> 1621 * <code>SmsManager.RESULT_NO_MEMORY</code><br> 1622 * <code>SmsManager.RESULT_INVALID_SMS_FORMAT</code><br> 1623 * <code>SmsManager.RESULT_SYSTEM_ERROR</code><br> 1624 * <code>SmsManager.RESULT_MODEM_ERROR</code><br> 1625 * <code>SmsManager.RESULT_NETWORK_ERROR</code><br> 1626 * <code>SmsManager.RESULT_ENCODING_ERROR</code><br> 1627 * <code>SmsManager.RESULT_INVALID_SMSC_ADDRESS</code><br> 1628 * <code>SmsManager.RESULT_OPERATION_NOT_ALLOWED</code><br> 1629 * <code>SmsManager.RESULT_INTERNAL_ERROR</code><br> 1630 * <code>SmsManager.RESULT_NO_RESOURCES</code><br> 1631 * <code>SmsManager.RESULT_CANCELLED</code><br> 1632 * <code>SmsManager.RESULT_REQUEST_NOT_SUPPORTED</code><br> 1633 * <code>SmsManager.RESULT_NO_BLUETOOTH_SERVICE</code><br> 1634 * <code>SmsManager.RESULT_INVALID_BLUETOOTH_ADDRESS</code><br> 1635 * <code>SmsManager.RESULT_BLUETOOTH_DISCONNECTED</code><br> 1636 * <code>SmsManager.RESULT_UNEXPECTED_EVENT_STOP_SENDING</code><br> 1637 * <code>SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY</code><br> 1638 * <code>SmsManager.RESULT_SMS_SEND_RETRY_FAILED</code><br> 1639 * <code>SmsManager.RESULT_REMOTE_EXCEPTION</code><br> 1640 * <code>SmsManager.RESULT_NO_DEFAULT_SMS_APP</code><br> 1641 * <code>SmsManager.RESULT_RIL_RADIO_NOT_AVAILABLE</code><br> 1642 * <code>SmsManager.RESULT_RIL_SMS_SEND_FAIL_RETRY</code><br> 1643 * <code>SmsManager.RESULT_RIL_NETWORK_REJECT</code><br> 1644 * <code>SmsManager.RESULT_RIL_INVALID_STATE</code><br> 1645 * <code>SmsManager.RESULT_RIL_INVALID_ARGUMENTS</code><br> 1646 * <code>SmsManager.RESULT_RIL_NO_MEMORY</code><br> 1647 * <code>SmsManager.RESULT_RIL_REQUEST_RATE_LIMITED</code><br> 1648 * <code>SmsManager.RESULT_RIL_INVALID_SMS_FORMAT</code><br> 1649 * <code>SmsManager.RESULT_RIL_SYSTEM_ERR</code><br> 1650 * <code>SmsManager.RESULT_RIL_ENCODING_ERR</code><br> 1651 * <code>SmsManager.RESULT_RIL_INVALID_SMSC_ADDRESS</code><br> 1652 * <code>SmsManager.RESULT_RIL_MODEM_ERR</code><br> 1653 * <code>SmsManager.RESULT_RIL_NETWORK_ERR</code><br> 1654 * <code>SmsManager.RESULT_RIL_INTERNAL_ERR</code><br> 1655 * <code>SmsManager.RESULT_RIL_REQUEST_NOT_SUPPORTED</code><br> 1656 * <code>SmsManager.RESULT_RIL_INVALID_MODEM_STATE</code><br> 1657 * <code>SmsManager.RESULT_RIL_NETWORK_NOT_READY</code><br> 1658 * <code>SmsManager.RESULT_RIL_OPERATION_NOT_ALLOWED</code><br> 1659 * <code>SmsManager.RESULT_RIL_NO_RESOURCES</code><br> 1660 * <code>SmsManager.RESULT_RIL_CANCELLED</code><br> 1661 * <code>SmsManager.RESULT_RIL_SIM_ABSENT</code><br> 1662 * <code>SmsManager.RESULT_RIL_SIMULTANEOUS_SMS_AND_CALL_NOT_ALLOWED</code><br> 1663 * <code>SmsManager.RESULT_RIL_ACCESS_BARRED</code><br> 1664 * <code>SmsManager.RESULT_RIL_BLOCKED_DUE_TO_CALL</code><br> 1665 * For <code>SmsManager.RESULT_ERROR_GENERIC_FAILURE</code> or any of the RESULT_RIL errors, 1666 * the sentIntent may include the extra "errorCode" containing a radio technology specific 1667 * value, generally only useful for troubleshooting.<br> 1668 * The per-application based SMS control checks sentIntent. If sentIntent 1669 * is NULL the caller will be checked against all unknown applications, 1670 * which cause smaller number of SMS to be sent in checking period. 1671 * -deliveryIntent if not NULL this <code>Intent</code> is 1672 * broadcast when the message is delivered to the recipient. The 1673 * raw pdu of the status report is in the extended data ("pdu"). 1674 * -param destAddr the destination phone number (for short code confirmation) 1675 */ 1676 @VisibleForTesting sendRawPdu(SmsTracker[] trackers)1677 public void sendRawPdu(SmsTracker[] trackers) { 1678 @SmsManager.Result int error = SmsManager.RESULT_ERROR_NONE; 1679 PackageInfo appInfo = null; 1680 if (mSmsSendDisabled) { 1681 Rlog.e(TAG, "Device does not support sending sms."); 1682 error = SmsManager.RESULT_ERROR_NO_SERVICE; 1683 } else { 1684 for (SmsTracker tracker : trackers) { 1685 if (tracker.getData().get(MAP_KEY_PDU) == null) { 1686 Rlog.e(TAG, "Empty PDU"); 1687 error = SmsManager.RESULT_ERROR_NULL_PDU; 1688 break; 1689 } 1690 } 1691 1692 if (error == SmsManager.RESULT_ERROR_NONE) { 1693 UserHandle userHandle = UserHandle.of(trackers[0].mUserId); 1694 PackageManager pm = mContext.createContextAsUser(userHandle, 0).getPackageManager(); 1695 1696 try { 1697 // Get package info via packagemanager 1698 appInfo = 1699 pm.getPackageInfo( 1700 trackers[0].getAppPackageName(), 1701 PackageManager.GET_SIGNATURES); 1702 } catch (PackageManager.NameNotFoundException e) { 1703 Rlog.e(TAG, "Can't get calling app package info: refusing to send SMS " 1704 + SmsController.formatCrossStackMessageId( 1705 getMultiTrackermessageId(trackers))); 1706 error = SmsManager.RESULT_ERROR_GENERIC_FAILURE; 1707 } 1708 } 1709 } 1710 1711 if (error != SmsManager.RESULT_ERROR_NONE) { 1712 handleSmsTrackersFailure(trackers, error, NO_ERROR_CODE); 1713 return; 1714 } 1715 1716 // checkDestination() returns true if the destination is not a premium short code or the 1717 // sending app is approved to send to short codes. Otherwise, a message is sent to our 1718 // handler with the SmsTracker to request user confirmation before sending. 1719 if (checkDestination(trackers)) { 1720 // check for excessive outgoing SMS usage by this app 1721 if (!mSmsDispatchersController 1722 .getUsageMonitor() 1723 .check(appInfo.packageName, trackers.length)) { 1724 sendMessage(obtainMessage(EVENT_SEND_LIMIT_REACHED_CONFIRMATION, trackers)); 1725 return; 1726 } 1727 1728 for (SmsTracker tracker : trackers) { 1729 sendSms(tracker); 1730 } 1731 } 1732 1733 if (mTelephonyManager.isEmergencyNumber(trackers[0].mDestAddress)) { 1734 new AsyncEmergencyContactNotifier(mContext).execute(); 1735 } 1736 } 1737 1738 /** 1739 * Check if destination is a potential premium short code and sender is not pre-approved to send 1740 * to short codes. 1741 * 1742 * @param trackers the trackers for a single or a multi-part SMS to send 1743 * @return true if the destination is approved; false if user confirmation event was sent 1744 */ checkDestination(SmsTracker[] trackers)1745 boolean checkDestination(SmsTracker[] trackers) { 1746 if (mContext.checkCallingOrSelfPermission(SEND_SMS_NO_CONFIRMATION) 1747 == PackageManager.PERMISSION_GRANTED || trackers[0].mIsForVvm) { 1748 return true; // app is pre-approved to send to short codes 1749 } else { 1750 int rule = mPremiumSmsRule.get(); 1751 int smsCategory = SmsManager.SMS_CATEGORY_NOT_SHORT_CODE; 1752 if (rule == PREMIUM_RULE_USE_SIM || rule == PREMIUM_RULE_USE_BOTH) { 1753 String simCountryIso = 1754 mTelephonyManager.getSimCountryIsoForPhone(mPhone.getPhoneId()); 1755 if (simCountryIso == null || simCountryIso.length() != 2) { 1756 Rlog.e(TAG, "Can't get SIM country Iso: trying network country Iso " 1757 + SmsController.formatCrossStackMessageId( 1758 getMultiTrackermessageId(trackers))); 1759 simCountryIso = 1760 mTelephonyManager.getNetworkCountryIso(mPhone.getPhoneId()); 1761 } 1762 1763 smsCategory = 1764 mSmsDispatchersController 1765 .getUsageMonitor() 1766 .checkDestination(trackers[0].mDestAddress, simCountryIso); 1767 } 1768 if (rule == PREMIUM_RULE_USE_NETWORK || rule == PREMIUM_RULE_USE_BOTH) { 1769 String networkCountryIso = 1770 mTelephonyManager.getNetworkCountryIso(mPhone.getPhoneId()); 1771 if (networkCountryIso == null || networkCountryIso.length() != 2) { 1772 Rlog.e(TAG, "Can't get Network country Iso: trying SIM country Iso " 1773 + SmsController.formatCrossStackMessageId( 1774 getMultiTrackermessageId(trackers))); 1775 networkCountryIso = 1776 mTelephonyManager.getSimCountryIsoForPhone(mPhone.getPhoneId()); 1777 } 1778 1779 smsCategory = 1780 SmsUsageMonitor.mergeShortCodeCategories( 1781 smsCategory, 1782 mSmsDispatchersController 1783 .getUsageMonitor() 1784 .checkDestination( 1785 trackers[0].mDestAddress, networkCountryIso)); 1786 } 1787 1788 if (smsCategory == SmsManager.SMS_CATEGORY_NOT_SHORT_CODE 1789 || smsCategory == SmsManager.SMS_CATEGORY_FREE_SHORT_CODE 1790 || smsCategory == SmsManager.SMS_CATEGORY_STANDARD_SHORT_CODE) { 1791 return true; // not a premium short code 1792 } 1793 1794 // Do not allow any premium sms during SuW 1795 if (Settings.Global.getInt(mResolver, Settings.Global.DEVICE_PROVISIONED, 0) == 0) { 1796 Rlog.e(TAG, "Can't send premium sms during Setup Wizard " 1797 + SmsController.formatCrossStackMessageId( 1798 getMultiTrackermessageId(trackers))); 1799 return false; 1800 } 1801 1802 // Wait for user confirmation unless the user has set permission to always allow/deny 1803 int premiumSmsPermission = 1804 mSmsDispatchersController 1805 .getUsageMonitor() 1806 .getPremiumSmsPermission(trackers[0].getAppPackageName()); 1807 if (premiumSmsPermission == SmsUsageMonitor.PREMIUM_SMS_PERMISSION_UNKNOWN) { 1808 // First time trying to send to premium SMS. 1809 premiumSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER; 1810 } 1811 1812 switch (premiumSmsPermission) { 1813 case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW: 1814 Rlog.d(TAG, "User approved this app to send to premium SMS " 1815 + SmsController.formatCrossStackMessageId( 1816 getMultiTrackermessageId(trackers))); 1817 return true; 1818 1819 case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW: 1820 Rlog.w(TAG, "User denied this app from sending to premium SMS " 1821 + SmsController.formatCrossStackMessageId( 1822 getMultiTrackermessageId(trackers))); 1823 Message msg = obtainMessage(EVENT_SENDING_NOT_ALLOWED, trackers); 1824 sendMessage(msg); 1825 return false; // reject this message 1826 1827 case SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER: 1828 default: 1829 int event; 1830 if (smsCategory == SmsManager.SMS_CATEGORY_POSSIBLE_PREMIUM_SHORT_CODE) { 1831 event = EVENT_CONFIRM_SEND_TO_POSSIBLE_PREMIUM_SHORT_CODE; 1832 } else { 1833 event = EVENT_CONFIRM_SEND_TO_PREMIUM_SHORT_CODE; 1834 } 1835 sendMessage(obtainMessage(event, trackers)); 1836 return false; // wait for user confirmation 1837 } 1838 } 1839 } 1840 1841 /** 1842 * Deny sending a single or a multi-part SMS if the outgoing queue limit is reached. Used when 1843 * the message must be confirmed by the user due to excessive usage or potential premium SMS 1844 * detected. 1845 * 1846 * @param trackers the SmsTracker array for the message to send 1847 * @return true if the message was denied; false to continue with send confirmation 1848 */ denyIfQueueLimitReached(SmsTracker[] trackers)1849 private boolean denyIfQueueLimitReached(SmsTracker[] trackers) { 1850 // one SmsTracker array is treated as one message for checking queue limit. 1851 if (mPendingTrackerCount >= MO_MSG_QUEUE_LIMIT) { 1852 // Deny sending message when the queue limit is reached. 1853 Rlog.e(TAG, "Denied because queue limit reached " 1854 + SmsController.formatCrossStackMessageId(getMultiTrackermessageId(trackers))); 1855 handleSmsTrackersFailure( 1856 trackers, SmsManager.RESULT_ERROR_LIMIT_EXCEEDED, NO_ERROR_CODE); 1857 return true; 1858 } 1859 mPendingTrackerCount++; 1860 return false; 1861 } 1862 1863 /** 1864 * Returns the label for the specified app package name. 1865 * @param appPackage the package name of the app requesting to send an SMS 1866 * @return the label for the specified app, or the package name if getApplicationInfo() fails 1867 */ getAppLabel(String appPackage, @UserIdInt int userId)1868 private CharSequence getAppLabel(String appPackage, @UserIdInt int userId) { 1869 PackageManager pm = mContext.getPackageManager(); 1870 try { 1871 ApplicationInfo appInfo = pm.getApplicationInfoAsUser(appPackage, 0, 1872 UserHandle.of(userId)); 1873 return appInfo.loadSafeLabel(pm); 1874 } catch (PackageManager.NameNotFoundException e) { 1875 Rlog.e(TAG, "PackageManager Name Not Found for package " + appPackage); 1876 return appPackage; // fall back to package name if we can't get app label 1877 } 1878 } 1879 1880 /** 1881 * Post an alert when SMS needs confirmation due to excessive usage. 1882 * 1883 * @param trackers the SmsTracker array for the current message. 1884 */ handleReachSentLimit(SmsTracker[] trackers)1885 protected void handleReachSentLimit(SmsTracker[] trackers) { 1886 if (denyIfQueueLimitReached(trackers)) { 1887 return; // queue limit reached; error was returned to caller 1888 } 1889 1890 CharSequence appLabel = getAppLabel(trackers[0].getAppPackageName(), trackers[0].mUserId); 1891 Resources r = Resources.getSystem(); 1892 Spanned messageText = Html.fromHtml(r.getString(R.string.sms_control_message, appLabel)); 1893 1894 // Construct ConfirmDialogListenter for Rate Limit handling 1895 ConfirmDialogListener listener = 1896 new ConfirmDialogListener(trackers, null, ConfirmDialogListener.RATE_LIMIT); 1897 1898 AlertDialog d = new AlertDialog.Builder(mContext) 1899 .setTitle(R.string.sms_control_title) 1900 .setIcon(R.drawable.stat_sys_warning) 1901 .setMessage(messageText) 1902 .setPositiveButton(r.getString(R.string.sms_control_yes), listener) 1903 .setNegativeButton(r.getString(R.string.sms_control_no), listener) 1904 .setOnCancelListener(listener) 1905 .create(); 1906 1907 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 1908 d.show(); 1909 } 1910 1911 /** 1912 * Post an alert for user confirmation when sending to a potential short code. 1913 * 1914 * @param isPremium true if the destination is known to be a premium short code 1915 * @param trackers the SmsTracker array for the current message. 1916 */ 1917 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) handleConfirmShortCode(boolean isPremium, SmsTracker[] trackers)1918 protected void handleConfirmShortCode(boolean isPremium, SmsTracker[] trackers) { 1919 if (denyIfQueueLimitReached(trackers)) { 1920 return; // queue limit reached; error was returned to caller 1921 } 1922 1923 int detailsId; 1924 if (isPremium) { 1925 detailsId = R.string.sms_premium_short_code_details; 1926 } else { 1927 detailsId = R.string.sms_short_code_details; 1928 } 1929 1930 CharSequence appLabel = getAppLabel(trackers[0].getAppPackageName(), trackers[0].mUserId); 1931 Resources r = Resources.getSystem(); 1932 Spanned messageText = 1933 Html.fromHtml( 1934 r.getString( 1935 R.string.sms_short_code_confirm_message, 1936 appLabel, 1937 trackers[0].mDestAddress)); 1938 1939 LayoutInflater inflater = (LayoutInflater) mContext.getSystemService( 1940 Context.LAYOUT_INFLATER_SERVICE); 1941 View layout = inflater.inflate(R.layout.sms_short_code_confirmation_dialog, null); 1942 1943 // Construct ConfirmDialogListenter for short code message sending 1944 ConfirmDialogListener listener = 1945 new ConfirmDialogListener( 1946 trackers, 1947 (TextView) 1948 layout.findViewById(R.id.sms_short_code_remember_undo_instruction), 1949 ConfirmDialogListener.SHORT_CODE_MSG); 1950 1951 TextView messageView = (TextView) layout.findViewById(R.id.sms_short_code_confirm_message); 1952 messageView.setText(messageText); 1953 1954 ViewGroup detailsLayout = (ViewGroup) layout.findViewById( 1955 R.id.sms_short_code_detail_layout); 1956 TextView detailsView = (TextView) detailsLayout.findViewById( 1957 R.id.sms_short_code_detail_message); 1958 detailsView.setText(detailsId); 1959 1960 CheckBox rememberChoice = (CheckBox) layout.findViewById( 1961 R.id.sms_short_code_remember_choice_checkbox); 1962 rememberChoice.setOnCheckedChangeListener(listener); 1963 1964 AlertDialog d = new AlertDialog.Builder(mContext) 1965 .setView(layout) 1966 .setPositiveButton(r.getString(R.string.sms_short_code_confirm_allow), listener) 1967 .setNegativeButton(r.getString(R.string.sms_short_code_confirm_deny), listener) 1968 .setOnCancelListener(listener) 1969 .create(); 1970 1971 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT); 1972 d.show(); 1973 1974 listener.setPositiveButton(d.getButton(DialogInterface.BUTTON_POSITIVE)); 1975 listener.setNegativeButton(d.getButton(DialogInterface.BUTTON_NEGATIVE)); 1976 } 1977 1978 /** 1979 * Send the message along to the radio. 1980 * 1981 * @param tracker holds the SMS message to send 1982 */ 1983 @UnsupportedAppUsage sendSms(SmsTracker tracker)1984 protected abstract void sendSms(SmsTracker tracker); 1985 1986 /** 1987 * Retry the message along to the radio. 1988 * 1989 * @param tracker holds the SMS message to send 1990 */ sendRetrySms(SmsTracker tracker)1991 public void sendRetrySms(SmsTracker tracker) { 1992 // re-routing to SmsDispatchersController 1993 if (mSmsDispatchersController != null) { 1994 mSmsDispatchersController.sendRetrySms(tracker); 1995 } else { 1996 Rlog.e(TAG, mSmsDispatchersController + " is null. Retry failed " 1997 + SmsController.formatCrossStackMessageId(tracker.mMessageId)); 1998 } 1999 } 2000 handleSmsTrackersFailure(SmsTracker[] trackers, @SmsManager.Result int error, int errorCode)2001 private void handleSmsTrackersFailure(SmsTracker[] trackers, @SmsManager.Result int error, 2002 int errorCode) { 2003 for (SmsTracker tracker : trackers) { 2004 tracker.onFailed(mContext, error, errorCode); 2005 } 2006 if (trackers.length > 0) { 2007 // This error occurs before the SMS is sent. Make an assumption if it would have 2008 // been sent over IMS or not. 2009 mPhone.getSmsStats().onOutgoingSms( 2010 isIms(), 2011 SmsConstants.FORMAT_3GPP2.equals(getFormat()), 2012 false /* fallbackToCs */, 2013 error, 2014 trackers[0].mMessageId, 2015 trackers[0].isFromDefaultSmsApplication(mContext), 2016 trackers[0].getInterval()); 2017 } 2018 } 2019 2020 /** 2021 * Keeps track of an SMS that has been sent to the RIL, until it has 2022 * successfully been sent, or we're done trying. 2023 */ 2024 public static class SmsTracker { 2025 // fields need to be public for derived SmsDispatchers 2026 @UnsupportedAppUsage 2027 private final HashMap<String, Object> mData; 2028 public int mRetryCount; 2029 // IMS retry counter. Nonzero indicates initial message was sent over IMS channel in RIL and 2030 // counts how many retries have been made on the IMS channel. 2031 // Used in older implementations where the message is sent over IMS using the RIL. 2032 public int mImsRetry; 2033 // Tag indicating that this SMS is being handled by the ImsSmsDispatcher. This tracker 2034 // should not try to use SMS over IMS over the RIL interface in this case when falling back. 2035 public boolean mUsesImsServiceForIms; 2036 @UnsupportedAppUsage 2037 public int mMessageRef; 2038 public boolean mExpectMore; 2039 public int mValidityPeriod; 2040 public int mPriority; 2041 String mFormat; 2042 2043 @UnsupportedAppUsage 2044 public final PendingIntent mSentIntent; 2045 @UnsupportedAppUsage 2046 public final PendingIntent mDeliveryIntent; 2047 2048 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2049 public final PackageInfo mAppInfo; 2050 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2051 public final String mDestAddress; 2052 2053 public final SmsHeader mSmsHeader; 2054 2055 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2056 private long mTimestamp = SystemClock.elapsedRealtime(); 2057 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2058 public Uri mMessageUri; // Uri of persisted message if we wrote one 2059 2060 // Reference to states of a multipart message that this part belongs to 2061 private AtomicInteger mUnsentPartCount; 2062 private AtomicBoolean mAnyPartFailed; 2063 // The full message content of a single part message 2064 // or a multipart message that this part belongs to 2065 private String mFullMessageText; 2066 2067 private int mSubId; 2068 2069 // If this is a text message (instead of data message) 2070 private boolean mIsText; 2071 2072 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2073 private boolean mPersistMessage; 2074 2075 // User who sends the SMS. 2076 private final @UserIdInt int mUserId; 2077 2078 private final boolean mIsForVvm; 2079 2080 public final long mMessageId; 2081 2082 private Boolean mIsFromDefaultSmsApplication; 2083 2084 private int mCarrierId; 2085 // SMS anomaly uuid -- unexpected error from RIL 2086 private final UUID mAnomalyUnexpectedErrorFromRilUUID = 2087 UUID.fromString("43043600-ea7a-44d2-9ae6-a58567ac7886"); 2088 SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent, PackageInfo appInfo, String destAddr, String format, AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri, SmsHeader smsHeader, boolean expectMore, String fullMessageText, int subId, boolean isText, boolean persistMessage, int userId, int priority, int validityPeriod, boolean isForVvm, long messageId, int carrierId)2089 private SmsTracker(HashMap<String, Object> data, PendingIntent sentIntent, 2090 PendingIntent deliveryIntent, PackageInfo appInfo, String destAddr, String format, 2091 AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri, 2092 SmsHeader smsHeader, boolean expectMore, String fullMessageText, int subId, 2093 boolean isText, boolean persistMessage, int userId, int priority, 2094 int validityPeriod, boolean isForVvm, long messageId, int carrierId) { 2095 mData = data; 2096 mSentIntent = sentIntent; 2097 mDeliveryIntent = deliveryIntent; 2098 mRetryCount = 0; 2099 mAppInfo = appInfo; 2100 mDestAddress = destAddr; 2101 mFormat = format; 2102 mExpectMore = expectMore; 2103 mImsRetry = 0; 2104 mUsesImsServiceForIms = false; 2105 mMessageRef = 0; 2106 mUnsentPartCount = unsentPartCount; 2107 mAnyPartFailed = anyPartFailed; 2108 mMessageUri = messageUri; 2109 mSmsHeader = smsHeader; 2110 mFullMessageText = fullMessageText; 2111 mSubId = subId; 2112 mIsText = isText; 2113 mPersistMessage = persistMessage; 2114 mUserId = userId; 2115 mPriority = priority; 2116 mValidityPeriod = validityPeriod; 2117 mIsForVvm = isForVvm; 2118 mMessageId = messageId; 2119 mCarrierId = carrierId; 2120 } 2121 getData()2122 public HashMap<String, Object> getData() { 2123 return mData; 2124 } 2125 2126 /** 2127 * Get the App package name 2128 * @return App package name info 2129 */ getAppPackageName()2130 public String getAppPackageName() { 2131 return mAppInfo != null ? mAppInfo.packageName : null; 2132 } 2133 2134 /** Return if the SMS was originated from the default SMS application. */ isFromDefaultSmsApplication(Context context)2135 public boolean isFromDefaultSmsApplication(Context context) { 2136 if (mIsFromDefaultSmsApplication == null) { 2137 // Perform a lazy initialization, due to the cost of the operation. 2138 mIsFromDefaultSmsApplication = 2139 SmsApplication.isDefaultSmsApplication(context, getAppPackageName()); 2140 } 2141 return mIsFromDefaultSmsApplication; 2142 } 2143 2144 /** 2145 * Update the status of this message if we persisted it 2146 */ 2147 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) updateSentMessageStatus(Context context, int status)2148 public void updateSentMessageStatus(Context context, int status) { 2149 if (mMessageUri != null) { 2150 // If we wrote this message in writeSentMessage, update it now 2151 ContentValues values = new ContentValues(1); 2152 values.put(Sms.STATUS, status); 2153 context.getContentResolver().update(mMessageUri, values, null, null); 2154 } 2155 } 2156 2157 /** 2158 * Set the final state of a message: FAILED or SENT 2159 * 2160 * @param context The Context 2161 * @param messageType The final message type 2162 * @param errorCode The error code 2163 */ updateMessageState(Context context, int messageType, int errorCode)2164 private void updateMessageState(Context context, int messageType, int errorCode) { 2165 if (mMessageUri == null) { 2166 return; 2167 } 2168 final ContentValues values = new ContentValues(2); 2169 values.put(Sms.TYPE, messageType); 2170 values.put(Sms.ERROR_CODE, errorCode); 2171 final long identity = Binder.clearCallingIdentity(); 2172 try { 2173 if (context.getContentResolver().update(mMessageUri, values, 2174 null/*where*/, null/*selectionArgs*/) != 1) { 2175 Rlog.e(TAG, "Failed to move message to " + messageType); 2176 } 2177 } finally { 2178 Binder.restoreCallingIdentity(identity); 2179 } 2180 } 2181 2182 /** 2183 * Returns the interval in milliseconds between sending the message out and current time. 2184 * Called after receiving success/failure response to calculate the time 2185 * to complete the SMS send to the network. 2186 */ getInterval()2187 protected long getInterval() { 2188 return SystemClock.elapsedRealtime() - mTimestamp; 2189 } 2190 2191 /** 2192 * Persist a sent SMS if required: 2193 * 1. It is a text message 2194 * 2. SmsApplication tells us to persist: sent from apps that are not default-SMS app or 2195 * bluetooth 2196 * 2197 * @param context 2198 * @param messageType The folder to store (FAILED or SENT) 2199 * @param errorCode The current error code for this SMS or SMS part 2200 * @return The telephony provider URI if stored 2201 */ persistSentMessageIfRequired(Context context, int messageType, int errorCode)2202 private Uri persistSentMessageIfRequired(Context context, int messageType, int errorCode) { 2203 if (!mIsText || !mPersistMessage || isFromDefaultSmsApplication(context)) { 2204 return null; 2205 } 2206 Rlog.d(TAG, "Persist SMS into " 2207 + (messageType == Sms.MESSAGE_TYPE_FAILED ? "FAILED" : "SENT")); 2208 final ContentValues values = new ContentValues(); 2209 values.put(Sms.SUBSCRIPTION_ID, mSubId); 2210 values.put(Sms.ADDRESS, mDestAddress); 2211 values.put(Sms.BODY, mFullMessageText); 2212 values.put(Sms.DATE, System.currentTimeMillis()); // milliseconds 2213 values.put(Sms.SEEN, 1); 2214 values.put(Sms.READ, 1); 2215 final String creator = mAppInfo != null ? mAppInfo.packageName : null; 2216 if (!TextUtils.isEmpty(creator)) { 2217 values.put(Sms.CREATOR, creator); 2218 } 2219 if (mDeliveryIntent != null) { 2220 values.put(Sms.STATUS, Telephony.Sms.STATUS_PENDING); 2221 } 2222 if (errorCode != NO_ERROR_CODE) { 2223 values.put(Sms.ERROR_CODE, errorCode); 2224 } 2225 final long identity = Binder.clearCallingIdentity(); 2226 final ContentResolver resolver = context.getContentResolver(); 2227 try { 2228 final Uri uri = resolver.insert(Telephony.Sms.Sent.CONTENT_URI, values); 2229 if (uri != null && messageType == Sms.MESSAGE_TYPE_FAILED) { 2230 // Since we can't persist a message directly into FAILED box, 2231 // we have to update the column after we persist it into SENT box. 2232 // The gap between the state change is tiny so I would not expect 2233 // it to cause any serious problem 2234 // TODO: we should add a "failed" URI for this in SmsProvider? 2235 final ContentValues updateValues = new ContentValues(1); 2236 updateValues.put(Sms.TYPE, Sms.MESSAGE_TYPE_FAILED); 2237 resolver.update(uri, updateValues, null/*where*/, null/*selectionArgs*/); 2238 } 2239 return uri; 2240 } catch (Exception e) { 2241 Rlog.e(TAG, "writeOutboxMessage: Failed to persist outbox message", e); 2242 return null; 2243 } finally { 2244 Binder.restoreCallingIdentity(identity); 2245 } 2246 } 2247 2248 /** 2249 * Persist or update an SMS depending on if we send a new message or a stored message 2250 * 2251 * @param context 2252 * @param messageType The message folder for this SMS, FAILED or SENT 2253 * @param errorCode The current error code for this SMS or SMS part 2254 */ persistOrUpdateMessage(Context context, int messageType, int errorCode)2255 private void persistOrUpdateMessage(Context context, int messageType, int errorCode) { 2256 if (mMessageUri != null) { 2257 updateMessageState(context, messageType, errorCode); 2258 } else { 2259 mMessageUri = persistSentMessageIfRequired(context, messageType, errorCode); 2260 } 2261 } 2262 2263 /** 2264 * Handle a failure of a single part message or a part of a multipart message 2265 * 2266 * @param context The Context 2267 * @param error The error to send back with 2268 * @param errorCode 2269 */ 2270 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) onFailed(Context context, int error, int errorCode)2271 public void onFailed(Context context, int error, int errorCode) { 2272 if (mAnyPartFailed != null) { 2273 mAnyPartFailed.set(true); 2274 } 2275 // is single part or last part of multipart message 2276 boolean isSinglePartOrLastPart = true; 2277 if (mUnsentPartCount != null) { 2278 isSinglePartOrLastPart = mUnsentPartCount.decrementAndGet() == 0; 2279 } 2280 if (isSinglePartOrLastPart) { 2281 persistOrUpdateMessage(context, Sms.MESSAGE_TYPE_FAILED, errorCode); 2282 } 2283 if (mSentIntent != null) { 2284 try { 2285 // Extra information to send with the sent intent 2286 Intent fillIn = new Intent(); 2287 if (mMessageUri != null) { 2288 // Pass this to SMS apps so that they know where it is stored 2289 fillIn.putExtra("uri", mMessageUri.toString()); 2290 } 2291 if (errorCode != NO_ERROR_CODE) { 2292 fillIn.putExtra("errorCode", errorCode); 2293 } 2294 if (mUnsentPartCount != null && isSinglePartOrLastPart) { 2295 // Is multipart and last part 2296 fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true); 2297 } 2298 if (mMessageId != 0L) { 2299 // Send the id back to the caller so they can verify the message id 2300 // with the one they passed to SmsManager. 2301 fillIn.putExtra(MESSAGE_ID_EXTRA, mMessageId); 2302 } 2303 fillIn.putExtra("format", mFormat); 2304 fillIn.putExtra("ims", mUsesImsServiceForIms); 2305 mSentIntent.send(context, error, fillIn); 2306 } catch (CanceledException ex) { 2307 Rlog.e(TAG, "Failed to send result " 2308 + SmsController.formatCrossStackMessageId(mMessageId)); 2309 } 2310 } 2311 reportAnomaly(error, errorCode); 2312 } 2313 reportAnomaly(int error, int errorCode)2314 private void reportAnomaly(int error, int errorCode) { 2315 switch (error) { 2316 // Exclude known failed reason 2317 case SmsManager.RESULT_ERROR_NO_SERVICE: 2318 case SmsManager.RESULT_ERROR_RADIO_OFF: 2319 case SmsManager.RESULT_ERROR_LIMIT_EXCEEDED: 2320 case SmsManager.RESULT_ERROR_SHORT_CODE_NEVER_ALLOWED: 2321 case SmsManager.RESULT_ERROR_SHORT_CODE_NOT_ALLOWED: 2322 case SmsManager.RESULT_SMS_BLOCKED_DURING_EMERGENCY: 2323 break; 2324 // Dump bugreport for analysis 2325 default: 2326 String message = "SMS failed"; 2327 Rlog.d(TAG, message + " with error " + error + ", errorCode " + errorCode); 2328 AnomalyReporter.reportAnomaly( 2329 generateUUID(error, errorCode), message, mCarrierId); 2330 } 2331 } 2332 generateUUID(int error, int errorCode)2333 private UUID generateUUID(int error, int errorCode) { 2334 long lerror = error; 2335 long lerrorCode = errorCode; 2336 return new UUID(mAnomalyUnexpectedErrorFromRilUUID.getMostSignificantBits(), 2337 mAnomalyUnexpectedErrorFromRilUUID.getLeastSignificantBits() 2338 + ((lerrorCode << 32) + lerror)); 2339 } 2340 2341 /** 2342 * Handle the sent of a single part message or a part of a multipart message 2343 * 2344 * @param context The Context 2345 */ 2346 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) onSent(Context context)2347 public void onSent(Context context) { 2348 // is single part or last part of multipart message 2349 boolean isSinglePartOrLastPart = true; 2350 if (mUnsentPartCount != null) { 2351 isSinglePartOrLastPart = mUnsentPartCount.decrementAndGet() == 0; 2352 } 2353 if (isSinglePartOrLastPart) { 2354 int messageType = Sms.MESSAGE_TYPE_SENT; 2355 if (mAnyPartFailed != null && mAnyPartFailed.get()) { 2356 messageType = Sms.MESSAGE_TYPE_FAILED; 2357 } 2358 persistOrUpdateMessage(context, messageType, NO_ERROR_CODE); 2359 } 2360 if (mSentIntent != null) { 2361 try { 2362 // Extra information to send with the sent intent 2363 Intent fillIn = new Intent(); 2364 if (mMessageUri != null) { 2365 // Pass this to SMS apps so that they know where it is stored 2366 fillIn.putExtra("uri", mMessageUri.toString()); 2367 } 2368 if (mUnsentPartCount != null && isSinglePartOrLastPart) { 2369 // Is multipart and last part 2370 fillIn.putExtra(SEND_NEXT_MSG_EXTRA, true); 2371 } 2372 fillIn.putExtra("format", mFormat); 2373 fillIn.putExtra("ims", mUsesImsServiceForIms); 2374 mSentIntent.send(context, Activity.RESULT_OK, fillIn); 2375 } catch (CanceledException ex) { 2376 Rlog.e(TAG, "Failed to send result"); 2377 } 2378 } 2379 } 2380 } 2381 getSmsTracker(String callingPackage, HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent, String format, AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri, SmsHeader smsHeader, boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage, int priority, int validityPeriod, boolean isForVvm, long messageId)2382 protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data, 2383 PendingIntent sentIntent, PendingIntent deliveryIntent, String format, 2384 AtomicInteger unsentPartCount, AtomicBoolean anyPartFailed, Uri messageUri, 2385 SmsHeader smsHeader, boolean expectMore, String fullMessageText, boolean isText, 2386 boolean persistMessage, int priority, int validityPeriod, boolean isForVvm, 2387 long messageId) { 2388 // Get package info via packagemanager 2389 UserHandle callingUser = UserHandle.getUserHandleForUid(Binder.getCallingUid()); 2390 final int userId = callingUser.getIdentifier(); 2391 PackageManager pm = mContext.createContextAsUser(callingUser, 0).getPackageManager(); 2392 PackageInfo appInfo = null; 2393 try { 2394 appInfo = pm.getPackageInfo(callingPackage, PackageManager.GET_SIGNATURES); 2395 } catch (PackageManager.NameNotFoundException e) { 2396 // error will be logged in sendRawPdu 2397 } 2398 // Strip non-digits from destination phone number before checking for short codes 2399 // and before displaying the number to the user if confirmation is required. 2400 String destAddr = PhoneNumberUtils.extractNetworkPortion((String) data.get("destAddr")); 2401 return new SmsTracker(data, sentIntent, deliveryIntent, appInfo, destAddr, format, 2402 unsentPartCount, anyPartFailed, messageUri, smsHeader, expectMore, 2403 fullMessageText, getSubId(), isText, persistMessage, userId, priority, 2404 validityPeriod, isForVvm, messageId, mPhone.getCarrierId()); 2405 } 2406 getSmsTracker(String callingPackage, HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri, boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage, boolean isForVvm, long messageId)2407 protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data, 2408 PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri, 2409 boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage, 2410 boolean isForVvm, long messageId) { 2411 return getSmsTracker(callingPackage, data, sentIntent, deliveryIntent, format, 2412 null/*unsentPartCount*/, null/*anyPartFailed*/, messageUri, null/*smsHeader*/, 2413 expectMore, fullMessageText, isText, persistMessage, 2414 SMS_MESSAGE_PRIORITY_NOT_SPECIFIED, SMS_MESSAGE_PERIOD_NOT_SPECIFIED, isForVvm, 2415 messageId); 2416 } 2417 getSmsTracker(String callingPackage, HashMap<String, Object> data, PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri, boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage, int priority, int validityPeriod, boolean isForVvm, long messageId)2418 protected SmsTracker getSmsTracker(String callingPackage, HashMap<String, Object> data, 2419 PendingIntent sentIntent, PendingIntent deliveryIntent, String format, Uri messageUri, 2420 boolean expectMore, String fullMessageText, boolean isText, boolean persistMessage, 2421 int priority, int validityPeriod, boolean isForVvm, long messageId) { 2422 return getSmsTracker(callingPackage, data, sentIntent, deliveryIntent, format, 2423 null/*unsentPartCount*/, null/*anyPartFailed*/, messageUri, null/*smsHeader*/, 2424 expectMore, fullMessageText, isText, persistMessage, priority, validityPeriod, 2425 isForVvm, messageId); 2426 } 2427 getSmsTrackerMap(String destAddr, String scAddr, String text, SmsMessageBase.SubmitPduBase pdu)2428 protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr, 2429 String text, SmsMessageBase.SubmitPduBase pdu) { 2430 HashMap<String, Object> map = new HashMap<String, Object>(); 2431 map.put(MAP_KEY_DEST_ADDR, destAddr); 2432 map.put(MAP_KEY_SC_ADDR, scAddr); 2433 map.put(MAP_KEY_TEXT, text); 2434 map.put(MAP_KEY_SMSC, pdu.encodedScAddress); 2435 map.put(MAP_KEY_PDU, pdu.encodedMessage); 2436 return map; 2437 } 2438 getSmsTrackerMap(String destAddr, String scAddr, int destPort, byte[] data, SmsMessageBase.SubmitPduBase pdu)2439 protected HashMap<String, Object> getSmsTrackerMap(String destAddr, String scAddr, 2440 int destPort, byte[] data, SmsMessageBase.SubmitPduBase pdu) { 2441 HashMap<String, Object> map = new HashMap<String, Object>(); 2442 map.put(MAP_KEY_DEST_ADDR, destAddr); 2443 map.put(MAP_KEY_SC_ADDR, scAddr); 2444 map.put(MAP_KEY_DEST_PORT, destPort); 2445 map.put(MAP_KEY_DATA, data); 2446 map.put(MAP_KEY_SMSC, pdu.encodedScAddress); 2447 map.put(MAP_KEY_PDU, pdu.encodedMessage); 2448 return map; 2449 } 2450 2451 /** 2452 * Dialog listener for SMS confirmation dialog. 2453 */ 2454 private final class ConfirmDialogListener 2455 implements DialogInterface.OnClickListener, DialogInterface.OnCancelListener, 2456 CompoundButton.OnCheckedChangeListener { 2457 2458 private final SmsTracker[] mTrackers; 2459 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2460 private Button mPositiveButton; 2461 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2462 private Button mNegativeButton; 2463 private boolean mRememberChoice; // default is unchecked 2464 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 2465 private final TextView mRememberUndoInstruction; 2466 private int mConfirmationType; // 0 - Short Code Msg Sending; 1 - Rate Limit Exceeded 2467 private static final int SHORT_CODE_MSG = 0; // Short Code Msg 2468 private static final int RATE_LIMIT = 1; // Rate Limit Exceeded 2469 private static final int NEVER_ALLOW = 1; // Never Allow 2470 ConfirmDialogListener(SmsTracker[] trackers, TextView textView, int confirmationType)2471 ConfirmDialogListener(SmsTracker[] trackers, TextView textView, int confirmationType) { 2472 mTrackers = trackers; 2473 mRememberUndoInstruction = textView; 2474 mConfirmationType = confirmationType; 2475 } 2476 setPositiveButton(Button button)2477 void setPositiveButton(Button button) { 2478 mPositiveButton = button; 2479 } 2480 setNegativeButton(Button button)2481 void setNegativeButton(Button button) { 2482 mNegativeButton = button; 2483 } 2484 2485 @Override onClick(DialogInterface dialog, int which)2486 public void onClick(DialogInterface dialog, int which) { 2487 // Always set the SMS permission so that Settings will show a permission setting 2488 // for the app (it won't be shown until after the app tries to send to a short code). 2489 int newSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ASK_USER; 2490 2491 if (which == DialogInterface.BUTTON_POSITIVE) { 2492 Rlog.d(TAG, "CONFIRM sending SMS"); 2493 // XXX this is lossy- apps can have more than one signature 2494 EventLog.writeEvent( 2495 EventLogTags.EXP_DET_SMS_SENT_BY_USER, 2496 mTrackers[0].mAppInfo.applicationInfo == null 2497 ? -1 2498 : mTrackers[0].mAppInfo.applicationInfo.uid); 2499 sendMessage(obtainMessage(EVENT_SEND_CONFIRMED_SMS, mTrackers)); 2500 if (mRememberChoice) { 2501 newSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_ALWAYS_ALLOW; 2502 } 2503 } else if (which == DialogInterface.BUTTON_NEGATIVE) { 2504 Rlog.d(TAG, "DENY sending SMS"); 2505 // XXX this is lossy- apps can have more than one signature 2506 EventLog.writeEvent( 2507 EventLogTags.EXP_DET_SMS_DENIED_BY_USER, 2508 mTrackers[0].mAppInfo.applicationInfo == null 2509 ? -1 2510 : mTrackers[0].mAppInfo.applicationInfo.uid); 2511 Message msg = obtainMessage(EVENT_STOP_SENDING, mTrackers); 2512 msg.arg1 = mConfirmationType; 2513 if (mRememberChoice) { 2514 newSmsPermission = SmsUsageMonitor.PREMIUM_SMS_PERMISSION_NEVER_ALLOW; 2515 msg.arg2 = ConfirmDialogListener.NEVER_ALLOW; 2516 } 2517 sendMessage(msg); 2518 } 2519 mSmsDispatchersController.setPremiumSmsPermission( 2520 mTrackers[0].getAppPackageName(), newSmsPermission); 2521 } 2522 2523 @Override onCancel(DialogInterface dialog)2524 public void onCancel(DialogInterface dialog) { 2525 Rlog.d(TAG, "dialog dismissed: don't send SMS"); 2526 Message msg = obtainMessage(EVENT_STOP_SENDING, mTrackers); 2527 msg.arg1 = mConfirmationType; 2528 sendMessage(msg); 2529 } 2530 2531 @Override onCheckedChanged(CompoundButton buttonView, boolean isChecked)2532 public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { 2533 Rlog.d(TAG, "remember this choice: " + isChecked); 2534 mRememberChoice = isChecked; 2535 if (isChecked) { 2536 mPositiveButton.setText(R.string.sms_short_code_confirm_always_allow); 2537 mNegativeButton.setText(R.string.sms_short_code_confirm_never_allow); 2538 if (mRememberUndoInstruction != null) { 2539 mRememberUndoInstruction 2540 .setText(R.string.sms_short_code_remember_undo_instruction); 2541 mRememberUndoInstruction.setPadding(0,0,0,32); 2542 } 2543 } else { 2544 mPositiveButton.setText(R.string.sms_short_code_confirm_allow); 2545 mNegativeButton.setText(R.string.sms_short_code_confirm_deny); 2546 if (mRememberUndoInstruction != null) { 2547 mRememberUndoInstruction.setText(""); 2548 mRememberUndoInstruction.setPadding(0,0,0,0); 2549 } 2550 } 2551 } 2552 } 2553 isIms()2554 public boolean isIms() { 2555 if (mSmsDispatchersController != null) { 2556 return mSmsDispatchersController.isIms(); 2557 } else { 2558 Rlog.e(TAG, "mSmsDispatchersController is null"); 2559 return false; 2560 } 2561 } 2562 2563 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getMultipartMessageText(ArrayList<String> parts)2564 private String getMultipartMessageText(ArrayList<String> parts) { 2565 final StringBuilder sb = new StringBuilder(); 2566 for (String part : parts) { 2567 if (part != null) { 2568 sb.append(part); 2569 } 2570 } 2571 return sb.toString(); 2572 } 2573 2574 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getCarrierAppPackageName()2575 protected String getCarrierAppPackageName() { 2576 CarrierPrivilegesTracker cpt = mPhone.getCarrierPrivilegesTracker(); 2577 if (cpt == null) { 2578 return null; 2579 } 2580 List<String> carrierPackages = 2581 cpt.getCarrierPackageNamesForIntent( 2582 new Intent(CarrierMessagingService.SERVICE_INTERFACE)); 2583 if (carrierPackages != null && carrierPackages.size() == 1) { 2584 return carrierPackages.get(0); 2585 } 2586 // If there is no carrier package which implements CarrierMessagingService, then lookup 2587 // an ImsService implementing RCS that also implements CarrierMessagingService. 2588 return CarrierSmsUtils.getImsRcsPackageForIntent(mContext, mPhone, 2589 new Intent(CarrierMessagingService.SERVICE_INTERFACE)); 2590 } 2591 2592 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getSubId()2593 protected int getSubId() { 2594 return SubscriptionController.getInstance().getSubIdUsingPhoneId(mPhone.getPhoneId()); 2595 } 2596 2597 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) checkCallerIsPhoneOrCarrierApp()2598 private void checkCallerIsPhoneOrCarrierApp() { 2599 int uid = Binder.getCallingUid(); 2600 int appId = UserHandle.getAppId(uid); 2601 if (appId == Process.PHONE_UID || uid == 0) { 2602 return; 2603 } 2604 try { 2605 PackageManager pm = mContext.getPackageManager(); 2606 ApplicationInfo ai = pm.getApplicationInfo(getCarrierAppPackageName(), 0); 2607 if (UserHandle.getAppId(ai.uid) != UserHandle.getAppId(Binder.getCallingUid())) { 2608 throw new SecurityException("Caller is not phone or carrier app!"); 2609 } 2610 } catch (PackageManager.NameNotFoundException re) { 2611 throw new SecurityException("Caller is not phone or carrier app!"); 2612 } 2613 } 2614 isCdmaMo()2615 protected boolean isCdmaMo() { 2616 return mSmsDispatchersController.isCdmaMo(); 2617 } 2618 isAscii7bitSupportedForLongMessage()2619 private boolean isAscii7bitSupportedForLongMessage() { 2620 //TODO: Do not rely on calling identity here, we should store UID & clear identity earlier. 2621 long token = Binder.clearCallingIdentity(); 2622 try { 2623 CarrierConfigManager configManager = (CarrierConfigManager) mContext.getSystemService( 2624 Context.CARRIER_CONFIG_SERVICE); 2625 PersistableBundle pb = null; 2626 pb = configManager.getConfigForSubId(mPhone.getSubId()); 2627 if (pb != null) { 2628 return pb.getBoolean(CarrierConfigManager 2629 .KEY_ASCII_7_BIT_SUPPORT_FOR_LONG_MESSAGE_BOOL); 2630 } 2631 return false; 2632 } finally { 2633 Binder.restoreCallingIdentity(token); 2634 } 2635 } 2636 2637 /** 2638 * Dump local logs 2639 */ dump(FileDescriptor fd, PrintWriter printWriter, String[] args)2640 public void dump(FileDescriptor fd, PrintWriter printWriter, String[] args) { 2641 IndentingPrintWriter pw = new IndentingPrintWriter(printWriter, " "); 2642 pw.println(TAG); 2643 pw.increaseIndent(); 2644 pw.println("mLocalLog:"); 2645 pw.increaseIndent(); 2646 mLocalLog.dump(fd, pw, args); 2647 pw.decreaseIndent(); 2648 pw.decreaseIndent(); 2649 } 2650 } 2651