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