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