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