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