1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * Copyright (c) 2011-2013, The Linux Foundation. All rights reserved. 4 * Not a Contribution. 5 * 6 * Licensed under the Apache License, Version 2.0 (the "License"); 7 * you may not use this file except in compliance with the License. 8 * You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, software 13 * distributed under the License is distributed on an "AS IS" BASIS, 14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 * See the License for the specific language governing permissions and 16 * limitations under the License. 17 */ 18 19 package com.android.internal.telephony; 20 21 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 22 23 import static com.android.internal.telephony.util.TelephonyUtils.checkDumpPermission; 24 25 import android.annotation.Nullable; 26 import android.app.ActivityManager; 27 import android.app.AppOpsManager; 28 import android.app.PendingIntent; 29 import android.compat.annotation.UnsupportedAppUsage; 30 import android.content.Context; 31 import android.content.pm.PackageManager; 32 import android.net.Uri; 33 import android.os.BaseBundle; 34 import android.os.Binder; 35 import android.os.Build; 36 import android.os.Bundle; 37 import android.os.TelephonyServiceManager.ServiceRegisterer; 38 import android.provider.Telephony.Sms.Intents; 39 import android.telephony.CarrierConfigManager; 40 import android.telephony.SmsManager; 41 import android.telephony.SubscriptionInfo; 42 import android.telephony.SubscriptionManager; 43 import android.telephony.TelephonyFrameworkInitializer; 44 import android.telephony.TelephonyManager; 45 46 import com.android.internal.annotations.VisibleForTesting; 47 import com.android.internal.telephony.subscription.SubscriptionManagerService; 48 import com.android.internal.telephony.util.TelephonyUtils; 49 import com.android.internal.util.IndentingPrintWriter; 50 import com.android.telephony.Rlog; 51 52 import java.io.FileDescriptor; 53 import java.io.PrintWriter; 54 import java.nio.charset.StandardCharsets; 55 import java.util.List; 56 import java.util.Locale; 57 58 /** 59 * Implements the ISmsImplBase interface used in the SmsManager API. 60 */ 61 public class SmsController extends ISmsImplBase { 62 static final String LOG_TAG = "SmsController"; 63 64 private final Context mContext; 65 66 @VisibleForTesting SmsController(Context context)67 public SmsController(Context context) { 68 mContext = context; 69 ServiceRegisterer smsServiceRegisterer = TelephonyFrameworkInitializer 70 .getTelephonyServiceManager() 71 .getSmsServiceRegisterer(); 72 if (smsServiceRegisterer.get() == null) { 73 smsServiceRegisterer.register(this); 74 } 75 } 76 getPhone(int subId)77 private Phone getPhone(int subId) { 78 Phone phone = PhoneFactory.getPhone(SubscriptionManager.getPhoneId(subId)); 79 if (phone == null) { 80 phone = PhoneFactory.getDefaultPhone(); 81 } 82 return phone; 83 } 84 getSmsPermissions(int subId)85 private SmsPermissions getSmsPermissions(int subId) { 86 Phone phone = getPhone(subId); 87 88 return new SmsPermissions(phone, mContext, 89 (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE)); 90 } 91 92 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 93 @Override updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index, int status, byte[] pdu)94 public boolean updateMessageOnIccEfForSubscriber(int subId, String callingPackage, int index, 95 int status, byte[] pdu) { 96 if (callingPackage == null) { 97 callingPackage = getCallingPackage(); 98 } 99 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 100 if (iccSmsIntMgr != null) { 101 return iccSmsIntMgr.updateMessageOnIccEf(callingPackage, index, status, pdu); 102 } else { 103 Rlog.e(LOG_TAG, "updateMessageOnIccEfForSubscriber iccSmsIntMgr is null" 104 + " for Subscription: " + subId); 105 return false; 106 } 107 } 108 109 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 110 @Override copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status, byte[] pdu, byte[] smsc)111 public boolean copyMessageToIccEfForSubscriber(int subId, String callingPackage, int status, 112 byte[] pdu, byte[] smsc) { 113 if (callingPackage == null) { 114 callingPackage = getCallingPackage(); 115 } 116 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 117 if (iccSmsIntMgr != null) { 118 return iccSmsIntMgr.copyMessageToIccEf(callingPackage, status, pdu, smsc); 119 } else { 120 Rlog.e(LOG_TAG, "copyMessageToIccEfForSubscriber iccSmsIntMgr is null" 121 + " for Subscription: " + subId); 122 return false; 123 } 124 } 125 126 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 127 @Override getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage)128 public List<SmsRawData> getAllMessagesFromIccEfForSubscriber(int subId, String callingPackage) { 129 if (callingPackage == null) { 130 callingPackage = getCallingPackage(); 131 } 132 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 133 if (iccSmsIntMgr != null) { 134 return iccSmsIntMgr.getAllMessagesFromIccEf(callingPackage); 135 } else { 136 Rlog.e(LOG_TAG, "getAllMessagesFromIccEfForSubscriber iccSmsIntMgr is" 137 + " null for Subscription: " + subId); 138 return null; 139 } 140 } 141 142 /** 143 * @deprecated Use {@link #sendDataForSubscriber(int, String, String, String, String, int, 144 * byte[], PendingIntent, PendingIntent)} instead 145 */ 146 @Deprecated 147 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) sendDataForSubscriber(int subId, String callingPackage, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)148 public void sendDataForSubscriber(int subId, String callingPackage, String destAddr, 149 String scAddr, int destPort, byte[] data, PendingIntent sentIntent, 150 PendingIntent deliveryIntent) { 151 sendDataForSubscriber(subId, callingPackage, null, destAddr, scAddr, destPort, data, 152 sentIntent, deliveryIntent); 153 } 154 155 @Override sendDataForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent)156 public void sendDataForSubscriber(int subId, String callingPackage, 157 String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data, 158 PendingIntent sentIntent, PendingIntent deliveryIntent) { 159 if (callingPackage == null) { 160 callingPackage = getCallingPackage(); 161 } 162 Rlog.d(LOG_TAG, "sendDataForSubscriber caller=" + callingPackage); 163 164 // Check if user is associated with the subscription 165 if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId, 166 Binder.getCallingUserHandle(), destAddr)) { 167 TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId, 168 Binder.getCallingUid(), callingPackage); 169 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED); 170 return; 171 } 172 173 // Perform FDN check 174 if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) { 175 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE); 176 return; 177 } 178 179 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 180 if (iccSmsIntMgr != null) { 181 iccSmsIntMgr.sendData(callingPackage, callingAttributionTag, destAddr, scAddr, destPort, 182 data, sentIntent, deliveryIntent); 183 } else { 184 Rlog.e(LOG_TAG, "sendDataForSubscriber iccSmsIntMgr is null for" 185 + " Subscription: " + subId); 186 // TODO: Use a more specific error code to replace RESULT_ERROR_GENERIC_FAILURE. 187 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 188 } 189 } 190 sendDataForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm)191 private void sendDataForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage, 192 String callingAttributionTag, String destAddr, String scAddr, int destPort, byte[] data, 193 PendingIntent sentIntent, PendingIntent deliveryIntent, boolean isForVvm) { 194 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 195 if (iccSmsIntMgr != null) { 196 iccSmsIntMgr.sendDataWithSelfPermissions(callingPackage, callingAttributionTag, 197 destAddr, scAddr, destPort, data, sentIntent, deliveryIntent, isForVvm); 198 } else { 199 Rlog.e(LOG_TAG, "sendText iccSmsIntMgr is null for" 200 + " Subscription: " + subId); 201 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 202 } 203 } 204 getCallingPackage()205 private String getCallingPackage() { 206 return mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid())[0]; 207 } 208 209 @Override sendTextForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, long messageId)210 public void sendTextForSubscriber(int subId, String callingPackage, 211 String callingAttributionTag, String destAddr, String scAddr, String text, 212 PendingIntent sentIntent, PendingIntent deliveryIntent, 213 boolean persistMessageForNonDefaultSmsApp, long messageId) { 214 sendTextForSubscriber(subId, callingPackage, callingAttributionTag, destAddr, scAddr, 215 text, sentIntent, deliveryIntent, persistMessageForNonDefaultSmsApp, messageId, 216 false, false); 217 218 } 219 220 /** 221 * @param subId Subscription Id 222 * @param callingAttributionTag the attribution tag of the caller 223 * @param destAddr the address to send the message to 224 * @param scAddr is the service center address or null to use 225 * the current default SMSC 226 * @param text the body of the message to send 227 * @param sentIntent if not NULL this <code>PendingIntent</code> is 228 * broadcast when the message is successfully sent, or failed. 229 * The result code will be <code>Activity.RESULT_OK</code> for success, or relevant errors 230 * the sentIntent may include the extra "errorCode" containing a radio technology specific 231 * value, generally only useful for troubleshooting. 232 * @param deliveryIntent if not NULL this <code>PendingIntent</code> is 233 * broadcast when the message is delivered to the recipient. The 234 * raw pdu of the status report is in the extended data ("pdu"). 235 * @param skipFdnCheck if set to true, FDN check must be skipped .This is set in case of STK sms 236 * 237 * @hide 238 */ sendTextForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipFdnCheck, boolean skipShortCodeCheck)239 public void sendTextForSubscriber(int subId, String callingPackage, 240 String callingAttributionTag, String destAddr, String scAddr, String text, 241 PendingIntent sentIntent, PendingIntent deliveryIntent, 242 boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipFdnCheck, 243 boolean skipShortCodeCheck) { 244 if (callingPackage == null) { 245 callingPackage = getCallingPackage(); 246 } 247 Rlog.d(LOG_TAG, "sendTextForSubscriber caller=" + callingPackage); 248 249 if (skipFdnCheck || skipShortCodeCheck) { 250 if (mContext.checkCallingOrSelfPermission( 251 android.Manifest.permission.MODIFY_PHONE_STATE) 252 != PackageManager.PERMISSION_GRANTED) { 253 throw new SecurityException("Requires MODIFY_PHONE_STATE permission."); 254 } 255 } 256 if (!getSmsPermissions(subId).checkCallingCanSendText(persistMessageForNonDefaultSmsApp, 257 callingPackage, callingAttributionTag, "Sending SMS message")) { 258 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 259 return; 260 } 261 262 // Check if user is associated with the subscription 263 boolean crossUserFullGranted = mContext.checkCallingOrSelfPermission( 264 android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) == PERMISSION_GRANTED; 265 Rlog.d(LOG_TAG, "sendTextForSubscriber: caller has INTERACT_ACROSS_USERS_FULL? " 266 + crossUserFullGranted); 267 if (!crossUserFullGranted 268 && !TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId, 269 Binder.getCallingUserHandle(), destAddr)) { 270 TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId, 271 Binder.getCallingUid(), callingPackage); 272 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED); 273 return; 274 } 275 276 // Perform FDN check 277 if (!skipFdnCheck && isNumberBlockedByFDN(subId, destAddr, callingPackage)) { 278 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE); 279 return; 280 } 281 282 long token = Binder.clearCallingIdentity(); 283 SubscriptionInfo info; 284 try { 285 info = getSubscriptionInfo(subId); 286 } finally { 287 Binder.restoreCallingIdentity(token); 288 } 289 290 if (isBluetoothSubscription(info)) { 291 sendBluetoothText(info, destAddr, text, sentIntent, deliveryIntent); 292 } else { 293 sendIccText(subId, callingPackage, destAddr, scAddr, text, sentIntent, deliveryIntent, 294 persistMessageForNonDefaultSmsApp, messageId, skipShortCodeCheck); 295 } 296 } 297 isBluetoothSubscription(SubscriptionInfo info)298 private boolean isBluetoothSubscription(SubscriptionInfo info) { 299 return info != null 300 && info.getSubscriptionType() == SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM; 301 } 302 sendBluetoothText(SubscriptionInfo info, String destAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent)303 private void sendBluetoothText(SubscriptionInfo info, String destAddr, 304 String text, PendingIntent sentIntent, PendingIntent deliveryIntent) { 305 BtSmsInterfaceManager btSmsInterfaceManager = new BtSmsInterfaceManager(); 306 btSmsInterfaceManager.sendText(mContext, destAddr, text, sentIntent, deliveryIntent, info); 307 } 308 sendIccText(int subId, String callingPackage, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipShortCodeCheck)309 private void sendIccText(int subId, String callingPackage, String destAddr, 310 String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, 311 boolean persistMessageForNonDefaultSmsApp, long messageId, boolean skipShortCodeCheck) { 312 Rlog.d(LOG_TAG, "sendTextForSubscriber iccSmsIntMgr" 313 + " Subscription: " + subId + " " + formatCrossStackMessageId(messageId)); 314 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 315 if (iccSmsIntMgr != null) { 316 iccSmsIntMgr.sendText(callingPackage, destAddr, scAddr, text, sentIntent, 317 deliveryIntent, persistMessageForNonDefaultSmsApp, messageId, 318 skipShortCodeCheck); 319 } else { 320 Rlog.e(LOG_TAG, "sendTextForSubscriber iccSmsIntMgr is null for" 321 + " Subscription: " + subId + " " + formatCrossStackMessageId(messageId)); 322 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 323 } 324 } 325 sendTextForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage, String callingAttributeTag, String destAddr, String scAddr, String text, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, boolean isForVvm)326 private void sendTextForSubscriberWithSelfPermissionsInternal(int subId, String callingPackage, 327 String callingAttributeTag, String destAddr, String scAddr, String text, 328 PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, 329 boolean isForVvm) { 330 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 331 if (iccSmsIntMgr != null) { 332 iccSmsIntMgr.sendTextWithSelfPermissions(callingPackage, callingAttributeTag, destAddr, 333 scAddr, text, sentIntent, deliveryIntent, persistMessage, isForVvm); 334 } else { 335 Rlog.e(LOG_TAG, "sendText iccSmsIntMgr is null for" 336 + " Subscription: " + subId); 337 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 338 } 339 } 340 341 @Override sendTextForSubscriberWithOptions(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, String parts, PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, int priority, boolean expectMore, int validityPeriod)342 public void sendTextForSubscriberWithOptions(int subId, String callingPackage, 343 String callingAttributionTag, String destAddr, String scAddr, String parts, 344 PendingIntent sentIntent, PendingIntent deliveryIntent, boolean persistMessage, 345 int priority, boolean expectMore, int validityPeriod) { 346 if (callingPackage == null) { 347 callingPackage = getCallingPackage(); 348 } 349 Rlog.d(LOG_TAG, "sendTextForSubscriberWithOptions caller=" + callingPackage); 350 351 // Check if user is associated with the subscription 352 if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId, 353 Binder.getCallingUserHandle(), destAddr)) { 354 TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId, 355 Binder.getCallingUid(), callingPackage); 356 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED); 357 return; 358 } 359 360 // Perform FDN check 361 if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) { 362 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE); 363 return; 364 } 365 366 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 367 if (iccSmsIntMgr != null) { 368 iccSmsIntMgr.sendTextWithOptions(callingPackage, callingAttributionTag, destAddr, 369 scAddr, parts, sentIntent, deliveryIntent, persistMessage, priority, expectMore, 370 validityPeriod); 371 } else { 372 Rlog.e(LOG_TAG, "sendTextWithOptions iccSmsIntMgr is null for" 373 + " Subscription: " + subId); 374 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 375 } 376 } 377 378 @Override sendMultipartTextForSubscriber(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessageForNonDefaultSmsApp, long messageId)379 public void sendMultipartTextForSubscriber(int subId, String callingPackage, 380 String callingAttributionTag, String destAddr, String scAddr, List<String> parts, 381 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, 382 boolean persistMessageForNonDefaultSmsApp, long messageId) { 383 // This is different from the checking of other method. It prefers the package name 384 // returned by getCallPackage() for backward-compatibility. 385 if (getCallingPackage() != null) { 386 callingPackage = getCallingPackage(); 387 } 388 Rlog.d(LOG_TAG, "sendMultipartTextForSubscriber caller=" + callingPackage); 389 390 // Check if user is associated with the subscription 391 if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId, 392 Binder.getCallingUserHandle(), destAddr)) { 393 TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId, 394 Binder.getCallingUid(), callingPackage); 395 sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_USER_NOT_ALLOWED); 396 return; 397 } 398 399 // Perform FDN check 400 if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) { 401 sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE); 402 return; 403 } 404 405 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 406 if (iccSmsIntMgr != null) { 407 iccSmsIntMgr.sendMultipartText(callingPackage, callingAttributionTag, destAddr, scAddr, 408 parts, sentIntents, deliveryIntents, persistMessageForNonDefaultSmsApp, 409 messageId); 410 } else { 411 Rlog.e(LOG_TAG, "sendMultipartTextForSubscriber iccSmsIntMgr is null for" 412 + " Subscription: " + subId + " " + formatCrossStackMessageId(messageId)); 413 sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 414 } 415 } 416 417 @Override sendMultipartTextForSubscriberWithOptions(int subId, String callingPackage, String callingAttributionTag, String destAddr, String scAddr, List<String> parts, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, boolean persistMessage, int priority, boolean expectMore, int validityPeriod)418 public void sendMultipartTextForSubscriberWithOptions(int subId, String callingPackage, 419 String callingAttributionTag, String destAddr, String scAddr, List<String> parts, 420 List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents, 421 boolean persistMessage, int priority, boolean expectMore, int validityPeriod) { 422 if (callingPackage == null) { 423 callingPackage = getCallingPackage(); 424 } 425 Rlog.d(LOG_TAG, "sendMultipartTextForSubscriberWithOptions caller=" + callingPackage); 426 427 // Check if user is associated with the subscription 428 if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId, 429 Binder.getCallingUserHandle(), destAddr)) { 430 TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId, 431 Binder.getCallingUid(), callingPackage); 432 sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_USER_NOT_ALLOWED); 433 return; 434 } 435 436 // Perform FDN check 437 if (isNumberBlockedByFDN(subId, destAddr, callingPackage)) { 438 sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_FDN_CHECK_FAILURE); 439 return; 440 } 441 442 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 443 if (iccSmsIntMgr != null) { 444 iccSmsIntMgr.sendMultipartTextWithOptions(callingPackage, callingAttributionTag, 445 destAddr, scAddr, parts, sentIntents, deliveryIntents, persistMessage, priority, 446 expectMore, validityPeriod, 0L /* messageId */); 447 } else { 448 Rlog.e(LOG_TAG, "sendMultipartTextWithOptions iccSmsIntMgr is null for" 449 + " Subscription: " + subId); 450 sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 451 } 452 } 453 454 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 455 @Override enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)456 public boolean enableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType) { 457 return enableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier, 458 ranType); 459 } 460 461 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 462 @Override enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType)463 public boolean enableCellBroadcastRangeForSubscriber(int subId, int startMessageId, 464 int endMessageId, int ranType) { 465 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 466 if (iccSmsIntMgr != null) { 467 return iccSmsIntMgr.enableCellBroadcastRange(startMessageId, endMessageId, ranType); 468 } else { 469 Rlog.e(LOG_TAG, "enableCellBroadcastRangeForSubscriber iccSmsIntMgr is null for" 470 + " Subscription: " + subId); 471 } 472 return false; 473 } 474 475 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 476 @Override disableCellBroadcastForSubscriber(int subId, int messageIdentifier, int ranType)477 public boolean disableCellBroadcastForSubscriber(int subId, 478 int messageIdentifier, int ranType) { 479 return disableCellBroadcastRangeForSubscriber(subId, messageIdentifier, messageIdentifier, 480 ranType); 481 } 482 483 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 484 @Override disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, int endMessageId, int ranType)485 public boolean disableCellBroadcastRangeForSubscriber(int subId, int startMessageId, 486 int endMessageId, int ranType) { 487 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 488 if (iccSmsIntMgr != null) { 489 return iccSmsIntMgr.disableCellBroadcastRange(startMessageId, endMessageId, ranType); 490 } else { 491 Rlog.e(LOG_TAG, "disableCellBroadcastRangeForSubscriber iccSmsIntMgr is null for" 492 + " Subscription:" + subId); 493 } 494 return false; 495 } 496 497 @Override getPremiumSmsPermission(String packageName)498 public int getPremiumSmsPermission(String packageName) { 499 return getPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName); 500 } 501 502 @Override getPremiumSmsPermissionForSubscriber(int subId, String packageName)503 public int getPremiumSmsPermissionForSubscriber(int subId, String packageName) { 504 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 505 if (iccSmsIntMgr != null) { 506 return iccSmsIntMgr.getPremiumSmsPermission(packageName); 507 } else { 508 Rlog.e(LOG_TAG, "getPremiumSmsPermissionForSubscriber iccSmsIntMgr is null"); 509 } 510 //TODO Rakesh 511 return 0; 512 } 513 514 @Override setPremiumSmsPermission(String packageName, int permission)515 public void setPremiumSmsPermission(String packageName, int permission) { 516 setPremiumSmsPermissionForSubscriber(getPreferredSmsSubscription(), packageName, 517 permission); 518 } 519 520 @Override setPremiumSmsPermissionForSubscriber(int subId, String packageName, int permission)521 public void setPremiumSmsPermissionForSubscriber(int subId, String packageName, 522 int permission) { 523 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 524 if (iccSmsIntMgr != null) { 525 iccSmsIntMgr.setPremiumSmsPermission(packageName, permission); 526 } else { 527 Rlog.e(LOG_TAG, "setPremiumSmsPermissionForSubscriber iccSmsIntMgr is null"); 528 } 529 } 530 531 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 532 @Override isImsSmsSupportedForSubscriber(int subId)533 public boolean isImsSmsSupportedForSubscriber(int subId) { 534 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 535 if (iccSmsIntMgr != null) { 536 return iccSmsIntMgr.isImsSmsSupported(); 537 } else { 538 Rlog.e(LOG_TAG, "isImsSmsSupportedForSubscriber iccSmsIntMgr is null"); 539 } 540 return false; 541 } 542 543 @Override isSmsSimPickActivityNeeded(int subId)544 public boolean isSmsSimPickActivityNeeded(int subId) { 545 final Context context = mContext.getApplicationContext(); 546 ActivityManager am = context.getSystemService(ActivityManager.class); 547 // Don't show the SMS SIM Pick activity if it is not foreground. 548 boolean isCallingProcessForeground = am != null 549 && am.getUidImportance(Binder.getCallingUid()) 550 == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; 551 if (!isCallingProcessForeground) { 552 Rlog.d(LOG_TAG, "isSmsSimPickActivityNeeded: calling process not foreground. " 553 + "Suppressing activity."); 554 return false; 555 } 556 TelephonyManager telephonyManager = 557 (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); 558 List<SubscriptionInfo> subInfoList; 559 final long identity = Binder.clearCallingIdentity(); 560 try { 561 subInfoList = SubscriptionManager.from(context).getActiveSubscriptionInfoList(); 562 } finally { 563 Binder.restoreCallingIdentity(identity); 564 } 565 566 if (subInfoList != null) { 567 final int subInfoLength = subInfoList.size(); 568 569 for (int i = 0; i < subInfoLength; ++i) { 570 final SubscriptionInfo sir = subInfoList.get(i); 571 if (sir != null && sir.getSubscriptionId() == subId) { 572 // The subscription id is valid, sms sim pick activity not needed 573 return false; 574 } 575 } 576 577 // If reached here and multiple SIMs and subs present, sms sim pick activity is needed 578 if (subInfoLength > 1 && telephonyManager.getSimCount() > 1) { 579 return true; 580 } 581 } 582 583 return false; 584 } 585 586 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 587 @Override getImsSmsFormatForSubscriber(int subId)588 public String getImsSmsFormatForSubscriber(int subId) { 589 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 590 if (iccSmsIntMgr != null) { 591 return iccSmsIntMgr.getImsSmsFormat(); 592 } else { 593 Rlog.e(LOG_TAG, "getImsSmsFormatForSubscriber iccSmsIntMgr is null"); 594 } 595 return null; 596 } 597 598 @Override injectSmsPduForSubscriber( int subId, byte[] pdu, String format, PendingIntent receivedIntent)599 public void injectSmsPduForSubscriber( 600 int subId, byte[] pdu, String format, PendingIntent receivedIntent) { 601 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 602 if (iccSmsIntMgr != null) { 603 iccSmsIntMgr.injectSmsPdu(pdu, format, receivedIntent); 604 } else { 605 Rlog.e(LOG_TAG, "injectSmsPduForSubscriber iccSmsIntMgr is null"); 606 // RESULT_SMS_GENERIC_ERROR is documented for injectSmsPdu 607 sendErrorInPendingIntent(receivedIntent, Intents.RESULT_SMS_GENERIC_ERROR); 608 } 609 } 610 611 /** 612 * Get preferred SMS subscription. 613 * 614 * @return User-defined default SMS subscription. If there is no default, return the active 615 * subscription if there is only one active. If no preference can be found, return 616 * {@link SubscriptionManager#INVALID_SUBSCRIPTION_ID}. 617 */ 618 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 619 @Override getPreferredSmsSubscription()620 public int getPreferredSmsSubscription() { 621 // If there is a default, choose that one. 622 int defaultSubId = SubscriptionManagerService.getInstance().getDefaultSmsSubId(); 623 624 if (SubscriptionManager.isValidSubscriptionId(defaultSubId)) { 625 return defaultSubId; 626 } 627 // No default, if there is only one sub active, choose that as the "preferred" sub id. 628 long token = Binder.clearCallingIdentity(); 629 try { 630 int[] activeSubs = SubscriptionManagerService.getInstance() 631 .getActiveSubIdList(true /*visibleOnly*/); 632 if (activeSubs.length == 1) { 633 return activeSubs[0]; 634 } 635 } finally { 636 Binder.restoreCallingIdentity(token); 637 } 638 // No preference can be found. 639 return SubscriptionManager.INVALID_SUBSCRIPTION_ID; 640 } 641 642 /** 643 * Get SMS prompt property enabled or not 644 * 645 * @return True if SMS prompt is enabled. 646 */ 647 @Override isSMSPromptEnabled()648 public boolean isSMSPromptEnabled() { 649 return PhoneFactory.isSMSPromptEnabled(); 650 } 651 652 @Override sendStoredText(int subId, String callingPkg, String callingAttributionTag, Uri messageUri, String scAddress, PendingIntent sentIntent, PendingIntent deliveryIntent)653 public void sendStoredText(int subId, String callingPkg, String callingAttributionTag, 654 Uri messageUri, String scAddress, PendingIntent sentIntent, 655 PendingIntent deliveryIntent) { 656 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 657 if (!getCallingPackage().equals(callingPkg)) { 658 throw new SecurityException("sendStoredText: Package " + callingPkg 659 + "does not belong to " + Binder.getCallingUid()); 660 } 661 Rlog.d(LOG_TAG, "sendStoredText caller=" + callingPkg); 662 663 if (iccSmsIntMgr != null) { 664 iccSmsIntMgr.sendStoredText(callingPkg, callingAttributionTag, messageUri, scAddress, 665 sentIntent, deliveryIntent); 666 } else { 667 Rlog.e(LOG_TAG, "sendStoredText iccSmsIntMgr is null for subscription: " + subId); 668 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 669 } 670 } 671 672 @Override sendStoredMultipartText(int subId, String callingPkg, String callingAttributionTag, Uri messageUri, String scAddress, List<PendingIntent> sentIntents, List<PendingIntent> deliveryIntents)673 public void sendStoredMultipartText(int subId, String callingPkg, String callingAttributionTag, 674 Uri messageUri, String scAddress, List<PendingIntent> sentIntents, 675 List<PendingIntent> deliveryIntents) { 676 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 677 if (!getCallingPackage().equals(callingPkg)) { 678 throw new SecurityException("sendStoredMultipartText: Package " + callingPkg 679 + " does not belong to " + Binder.getCallingUid()); 680 } 681 Rlog.d(LOG_TAG, "sendStoredMultipartText caller=" + callingPkg); 682 683 if (iccSmsIntMgr != null) { 684 iccSmsIntMgr.sendStoredMultipartText(callingPkg, callingAttributionTag, messageUri, 685 scAddress, sentIntents, deliveryIntents); 686 } else { 687 Rlog.e(LOG_TAG, "sendStoredMultipartText iccSmsIntMgr is null for subscription: " 688 + subId); 689 sendErrorInPendingIntents(sentIntents, SmsManager.RESULT_ERROR_GENERIC_FAILURE); 690 } 691 } 692 693 @Override getCarrierConfigValuesForSubscriber(int subId)694 public Bundle getCarrierConfigValuesForSubscriber(int subId) { 695 final long identity = Binder.clearCallingIdentity(); 696 try { 697 final CarrierConfigManager configManager = 698 (CarrierConfigManager) 699 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE); 700 return getMmsConfig(configManager.getConfigForSubId(subId)); 701 } finally { 702 Binder.restoreCallingIdentity(identity); 703 } 704 } 705 706 /** 707 * Filters a bundle to only contain MMS config variables. 708 * 709 * This is for use with bundles returned by CarrierConfigManager which contain MMS config and 710 * unrelated config. It is assumed that all MMS_CONFIG_* keys are present in the supplied 711 * bundle. 712 * 713 * @param config a Bundle that contains MMS config variables and possibly more. 714 * @return a new Bundle that only contains the MMS_CONFIG_* keys defined in SmsManager. 715 */ getMmsConfig(BaseBundle config)716 private static Bundle getMmsConfig(BaseBundle config) { 717 Bundle filtered = new Bundle(); 718 filtered.putBoolean( 719 SmsManager.MMS_CONFIG_APPEND_TRANSACTION_ID, 720 config.getBoolean(SmsManager.MMS_CONFIG_APPEND_TRANSACTION_ID)); 721 filtered.putBoolean( 722 SmsManager.MMS_CONFIG_MMS_ENABLED, 723 config.getBoolean(SmsManager.MMS_CONFIG_MMS_ENABLED)); 724 filtered.putBoolean( 725 SmsManager.MMS_CONFIG_GROUP_MMS_ENABLED, 726 config.getBoolean(SmsManager.MMS_CONFIG_GROUP_MMS_ENABLED)); 727 filtered.putBoolean( 728 SmsManager.MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED, 729 config.getBoolean(SmsManager.MMS_CONFIG_NOTIFY_WAP_MMSC_ENABLED)); 730 filtered.putBoolean( 731 SmsManager.MMS_CONFIG_ALIAS_ENABLED, 732 config.getBoolean(SmsManager.MMS_CONFIG_ALIAS_ENABLED)); 733 filtered.putBoolean( 734 SmsManager.MMS_CONFIG_ALLOW_ATTACH_AUDIO, 735 config.getBoolean(SmsManager.MMS_CONFIG_ALLOW_ATTACH_AUDIO)); 736 filtered.putBoolean( 737 SmsManager.MMS_CONFIG_MULTIPART_SMS_ENABLED, 738 config.getBoolean(SmsManager.MMS_CONFIG_MULTIPART_SMS_ENABLED)); 739 filtered.putBoolean( 740 SmsManager.MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED, 741 config.getBoolean(SmsManager.MMS_CONFIG_SMS_DELIVERY_REPORT_ENABLED)); 742 filtered.putBoolean( 743 SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION, 744 config.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_MMS_CONTENT_DISPOSITION)); 745 filtered.putBoolean( 746 SmsManager.MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES, 747 config.getBoolean(SmsManager.MMS_CONFIG_SEND_MULTIPART_SMS_AS_SEPARATE_MESSAGES)); 748 filtered.putBoolean( 749 SmsManager.MMS_CONFIG_MMS_READ_REPORT_ENABLED, 750 config.getBoolean(SmsManager.MMS_CONFIG_MMS_READ_REPORT_ENABLED)); 751 filtered.putBoolean( 752 SmsManager.MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED, 753 config.getBoolean(SmsManager.MMS_CONFIG_MMS_DELIVERY_REPORT_ENABLED)); 754 filtered.putBoolean( 755 SmsManager.MMS_CONFIG_CLOSE_CONNECTION, 756 config.getBoolean(SmsManager.MMS_CONFIG_CLOSE_CONNECTION)); 757 filtered.putInt( 758 SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE, 759 config.getInt(SmsManager.MMS_CONFIG_MAX_MESSAGE_SIZE)); 760 filtered.putInt( 761 SmsManager.MMS_CONFIG_MAX_IMAGE_WIDTH, 762 config.getInt(SmsManager.MMS_CONFIG_MAX_IMAGE_WIDTH)); 763 filtered.putInt( 764 SmsManager.MMS_CONFIG_MAX_IMAGE_HEIGHT, 765 config.getInt(SmsManager.MMS_CONFIG_MAX_IMAGE_HEIGHT)); 766 filtered.putInt( 767 SmsManager.MMS_CONFIG_RECIPIENT_LIMIT, 768 config.getInt(SmsManager.MMS_CONFIG_RECIPIENT_LIMIT)); 769 filtered.putInt( 770 SmsManager.MMS_CONFIG_ALIAS_MIN_CHARS, 771 config.getInt(SmsManager.MMS_CONFIG_ALIAS_MIN_CHARS)); 772 filtered.putInt( 773 SmsManager.MMS_CONFIG_ALIAS_MAX_CHARS, 774 config.getInt(SmsManager.MMS_CONFIG_ALIAS_MAX_CHARS)); 775 filtered.putInt( 776 SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD, 777 config.getInt(SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_THRESHOLD)); 778 filtered.putInt( 779 SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD, 780 config.getInt(SmsManager.MMS_CONFIG_SMS_TO_MMS_TEXT_LENGTH_THRESHOLD)); 781 filtered.putInt( 782 SmsManager.MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE, 783 config.getInt(SmsManager.MMS_CONFIG_MESSAGE_TEXT_MAX_SIZE)); 784 filtered.putInt( 785 SmsManager.MMS_CONFIG_SUBJECT_MAX_LENGTH, 786 config.getInt(SmsManager.MMS_CONFIG_SUBJECT_MAX_LENGTH)); 787 filtered.putInt( 788 SmsManager.MMS_CONFIG_HTTP_SOCKET_TIMEOUT, 789 config.getInt(SmsManager.MMS_CONFIG_HTTP_SOCKET_TIMEOUT)); 790 filtered.putString( 791 SmsManager.MMS_CONFIG_UA_PROF_TAG_NAME, 792 config.getString(SmsManager.MMS_CONFIG_UA_PROF_TAG_NAME)); 793 filtered.putString( 794 SmsManager.MMS_CONFIG_USER_AGENT, 795 config.getString(SmsManager.MMS_CONFIG_USER_AGENT)); 796 filtered.putString( 797 SmsManager.MMS_CONFIG_UA_PROF_URL, 798 config.getString(SmsManager.MMS_CONFIG_UA_PROF_URL)); 799 filtered.putString( 800 SmsManager.MMS_CONFIG_HTTP_PARAMS, 801 config.getString(SmsManager.MMS_CONFIG_HTTP_PARAMS)); 802 filtered.putString( 803 SmsManager.MMS_CONFIG_EMAIL_GATEWAY_NUMBER, 804 config.getString(SmsManager.MMS_CONFIG_EMAIL_GATEWAY_NUMBER)); 805 filtered.putString( 806 SmsManager.MMS_CONFIG_NAI_SUFFIX, 807 config.getString(SmsManager.MMS_CONFIG_NAI_SUFFIX)); 808 filtered.putBoolean( 809 SmsManager.MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS, 810 config.getBoolean(SmsManager.MMS_CONFIG_SHOW_CELL_BROADCAST_APP_LINKS)); 811 filtered.putBoolean( 812 SmsManager.MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER, 813 config.getBoolean(SmsManager.MMS_CONFIG_SUPPORT_HTTP_CHARSET_HEADER)); 814 return filtered; 815 } 816 817 @Override createAppSpecificSmsTokenWithPackageInfo( int subId, String callingPkg, String prefixes, PendingIntent intent)818 public String createAppSpecificSmsTokenWithPackageInfo( 819 int subId, String callingPkg, String prefixes, PendingIntent intent) { 820 if (callingPkg == null) { 821 callingPkg = getCallingPackage(); 822 } 823 return getPhone(subId).getAppSmsManager().createAppSpecificSmsTokenWithPackageInfo( 824 subId, callingPkg, prefixes, intent); 825 } 826 827 @Override createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent)828 public String createAppSpecificSmsToken(int subId, String callingPkg, PendingIntent intent) { 829 if (callingPkg == null) { 830 callingPkg = getCallingPackage(); 831 } 832 return getPhone(subId).getAppSmsManager().createAppSpecificSmsToken(callingPkg, intent); 833 } 834 835 @Override setStorageMonitorMemoryStatusOverride(int subId, boolean isStorageAvailable)836 public void setStorageMonitorMemoryStatusOverride(int subId, boolean isStorageAvailable) { 837 Phone phone = getPhone(subId); 838 Context context; 839 if (phone != null) { 840 context = phone.getContext(); 841 } else { 842 Rlog.e(LOG_TAG, "Phone Object is Null"); 843 return; 844 } 845 // If it doesn't have modify phone state permission 846 // a SecurityException will be thrown. 847 if (context.checkPermission(android.Manifest 848 .permission.MODIFY_PHONE_STATE, Binder.getCallingPid(), 849 Binder.getCallingUid()) != PERMISSION_GRANTED) { 850 throw new SecurityException( 851 "setStorageMonitorMemoryStatusOverride needs MODIFY_PHONE_STATE"); 852 } 853 final long identity = Binder.clearCallingIdentity(); 854 try { 855 phone.mSmsStorageMonitor.sendMemoryStatusOverride(isStorageAvailable); 856 } finally { 857 Binder.restoreCallingIdentity(identity); 858 } 859 } 860 861 @Override clearStorageMonitorMemoryStatusOverride(int subId)862 public void clearStorageMonitorMemoryStatusOverride(int subId) { 863 Phone phone = getPhone(subId); 864 Context context; 865 if (phone != null) { 866 context = phone.getContext(); 867 } else { 868 Rlog.e(LOG_TAG, "Phone Object is Null"); 869 return; 870 } 871 // If it doesn't have modify phone state permission 872 // a SecurityException will be thrown. 873 if (context.checkPermission(android.Manifest 874 .permission.MODIFY_PHONE_STATE, Binder.getCallingPid(), 875 Binder.getCallingUid()) != PERMISSION_GRANTED) { 876 throw new SecurityException( 877 "clearStorageMonitorMemoryStatusOverride needs MODIFY_PHONE_STATE"); 878 } 879 final long identity = Binder.clearCallingIdentity(); 880 try { 881 phone.mSmsStorageMonitor.clearMemoryStatusOverride(); 882 } finally { 883 Binder.restoreCallingIdentity(identity); 884 } 885 } 886 887 @Override checkSmsShortCodeDestination(int subId, String callingPackage, String callingFeatureId, String destAddress, String countryIso)888 public int checkSmsShortCodeDestination(int subId, String callingPackage, 889 String callingFeatureId, String destAddress, String countryIso) { 890 if (callingPackage == null) { 891 callingPackage = getCallingPackage(); 892 } 893 if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState(getPhone(subId).getContext(), 894 subId, callingPackage, callingFeatureId, "checkSmsShortCodeDestination")) { 895 return SmsManager.SMS_CATEGORY_NOT_SHORT_CODE; 896 } 897 final long identity = Binder.clearCallingIdentity(); 898 try { 899 return getPhone(subId).mSmsUsageMonitor.checkDestination(destAddress, countryIso); 900 } finally { 901 Binder.restoreCallingIdentity(identity); 902 } 903 } 904 905 /** 906 * Internal API to send visual voicemail related SMS. This is not exposed outside the phone 907 * process, and should be called only after verifying that the caller is the default VVM app. 908 */ sendVisualVoicemailSmsForSubscriber(String callingPackage, String callingAttributionTag, int subId, String number, int port, String text, PendingIntent sentIntent)909 public void sendVisualVoicemailSmsForSubscriber(String callingPackage, 910 String callingAttributionTag, int subId, String number, int port, String text, 911 PendingIntent sentIntent) { 912 Rlog.d(LOG_TAG, "sendVisualVoicemailSmsForSubscriber caller=" + callingPackage); 913 914 // Do not send non-emergency SMS in ECBM as it forces device to exit ECBM. 915 if(getPhone(subId).isInEcm()) { 916 Rlog.d(LOG_TAG, "sendVisualVoicemailSmsForSubscriber: Do not send non-emergency " 917 + "SMS in ECBM as it forces device to exit ECBM."); 918 return; 919 } 920 921 // Check if user is associated with the subscription 922 if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId, 923 Binder.getCallingUserHandle(), number)) { 924 TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext, subId, 925 Binder.getCallingUid(), callingPackage); 926 sendErrorInPendingIntent(sentIntent, SmsManager.RESULT_USER_NOT_ALLOWED); 927 return; 928 } 929 930 if (port == 0) { 931 sendTextForSubscriberWithSelfPermissionsInternal(subId, callingPackage, 932 callingAttributionTag, number, null, text, sentIntent, null, false, 933 true /* isForVvm */); 934 } else { 935 byte[] data = text.getBytes(StandardCharsets.UTF_8); 936 sendDataForSubscriberWithSelfPermissionsInternal(subId, callingPackage, 937 callingAttributionTag, number, null, (short) port, data, sentIntent, null, 938 true /* isForVvm */); 939 } 940 } 941 942 @Override getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage)943 public String getSmscAddressFromIccEfForSubscriber(int subId, String callingPackage) { 944 if (callingPackage == null) { 945 callingPackage = getCallingPackage(); 946 } 947 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 948 if (iccSmsIntMgr != null) { 949 return iccSmsIntMgr.getSmscAddressFromIccEf(callingPackage); 950 } else { 951 Rlog.e(LOG_TAG, "getSmscAddressFromIccEfForSubscriber iccSmsIntMgr is null" 952 + " for Subscription: " + subId); 953 return null; 954 } 955 } 956 957 @Override setSmscAddressOnIccEfForSubscriber( String smsc, int subId, String callingPackage)958 public boolean setSmscAddressOnIccEfForSubscriber( 959 String smsc, int subId, String callingPackage) { 960 if (callingPackage == null) { 961 callingPackage = getCallingPackage(); 962 } 963 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 964 if (iccSmsIntMgr != null) { 965 return iccSmsIntMgr.setSmscAddressOnIccEf(callingPackage, smsc); 966 } else { 967 Rlog.e(LOG_TAG, "setSmscAddressOnIccEfForSubscriber iccSmsIntMgr is null" 968 + " for Subscription: " + subId); 969 return false; 970 } 971 } 972 973 /** 974 * Triggered by `adb shell dumpsys isms` 975 */ 976 @Override dump(FileDescriptor fd, PrintWriter pw, String[] args)977 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { 978 if (!checkDumpPermission(mContext, LOG_TAG, pw)) { 979 return; 980 } 981 982 IndentingPrintWriter indentingPW = 983 new IndentingPrintWriter(pw, " " /* singleIndent */); 984 for (Phone phone : PhoneFactory.getPhones()) { 985 int subId = phone.getSubId(); 986 indentingPW.println(String.format("SmsManager for subId = %d:", subId)); 987 indentingPW.increaseIndent(); 988 if (getIccSmsInterfaceManager(subId) != null) { 989 getIccSmsInterfaceManager(subId).dump(fd, indentingPW, args); 990 } 991 indentingPW.decreaseIndent(); 992 } 993 indentingPW.flush(); 994 } 995 996 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) sendErrorInPendingIntent(@ullable PendingIntent intent, int errorCode)997 private void sendErrorInPendingIntent(@Nullable PendingIntent intent, int errorCode) { 998 if (intent != null) { 999 try { 1000 intent.send(errorCode); 1001 } catch (PendingIntent.CanceledException ex) { 1002 } 1003 } 1004 } 1005 1006 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode)1007 private void sendErrorInPendingIntents(List<PendingIntent> intents, int errorCode) { 1008 if (intents == null) { 1009 return; 1010 } 1011 1012 for (PendingIntent intent : intents) { 1013 sendErrorInPendingIntent(intent, errorCode); 1014 } 1015 } 1016 1017 /** 1018 * Get sms interface manager object based on subscription. 1019 * 1020 * @return ICC SMS manager 1021 */ 1022 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getIccSmsInterfaceManager(int subId)1023 private @Nullable IccSmsInterfaceManager getIccSmsInterfaceManager(int subId) { 1024 return getPhone(subId).getIccSmsInterfaceManager(); 1025 } 1026 getSubscriptionInfo(int subId)1027 private SubscriptionInfo getSubscriptionInfo(int subId) { 1028 SubscriptionManager manager = (SubscriptionManager) mContext 1029 .getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); 1030 return manager.getActiveSubscriptionInfo(subId); 1031 } 1032 1033 /** 1034 * Get the capacity count of sms on Icc card. 1035 */ 1036 @Override getSmsCapacityOnIccForSubscriber(int subId)1037 public int getSmsCapacityOnIccForSubscriber(int subId) { 1038 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 1039 1040 if (iccSmsIntMgr != null ) { 1041 return iccSmsIntMgr.getSmsCapacityOnIcc(getCallingPackage(), null); 1042 } else { 1043 Rlog.e(LOG_TAG, "iccSmsIntMgr is null for " + " subId: " + subId); 1044 return 0; 1045 } 1046 } 1047 1048 /** 1049 * Reset all cell broadcast ranges. Previously enabled ranges will become invalid after this. 1050 * 1051 * @param subId Subscription index 1052 * @return {@code true} if succeeded, otherwise {@code false}. 1053 */ 1054 @Override resetAllCellBroadcastRanges(int subId)1055 public boolean resetAllCellBroadcastRanges(int subId) { 1056 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 1057 if (iccSmsIntMgr != null) { 1058 iccSmsIntMgr.resetAllCellBroadcastRanges(); 1059 return true; 1060 } else { 1061 Rlog.e(LOG_TAG, "iccSmsIntMgr is null for " + " subId: " + subId); 1062 return false; 1063 } 1064 } 1065 1066 /** 1067 * Internal API to consistently format the debug log output of the cross-stack message id. 1068 */ formatCrossStackMessageId(long id)1069 public static String formatCrossStackMessageId(long id) { 1070 return "{x-message-id:" + id + "}"; 1071 } 1072 1073 /** 1074 * The following function checks if destination address or smsc is blocked due to FDN. 1075 * @param subId subscription ID 1076 * @param destAddr destination address of the message 1077 * @return true if either destAddr or smscAddr is blocked due to FDN. 1078 */ 1079 @VisibleForTesting isNumberBlockedByFDN(int subId, String destAddr, String callingPackage)1080 public boolean isNumberBlockedByFDN(int subId, String destAddr, String callingPackage) { 1081 int phoneId = SubscriptionManager.getPhoneId(subId); 1082 if (!FdnUtils.isFdnEnabled(phoneId)) { 1083 return false; 1084 } 1085 1086 // Skip FDN check for emergency numbers 1087 TelephonyManager tm = mContext.getSystemService(TelephonyManager.class); 1088 if (tm.isEmergencyNumber(destAddr)) { 1089 return false; 1090 } 1091 1092 // Check if destAddr is present in FDN list 1093 String defaultCountryIso = tm.getSimCountryIso().toUpperCase(Locale.ENGLISH); 1094 if (FdnUtils.isNumberBlockedByFDN(phoneId, destAddr, defaultCountryIso)) { 1095 return true; 1096 } 1097 1098 // Get SMSC address for this subscription 1099 IccSmsInterfaceManager iccSmsIntMgr = getIccSmsInterfaceManager(subId); 1100 String smscAddr; 1101 if (iccSmsIntMgr != null) { 1102 long identity = Binder.clearCallingIdentity(); 1103 try { 1104 smscAddr = iccSmsIntMgr.getSmscAddressFromIccEf(callingPackage); 1105 } finally { 1106 Binder.restoreCallingIdentity(identity); 1107 } 1108 } else { 1109 Rlog.e(LOG_TAG, "getSmscAddressFromIccEfForSubscriber iccSmsIntMgr is null" 1110 + " for Subscription: " + subId); 1111 return true; 1112 } 1113 1114 // Check if smscAddr is present in FDN list 1115 return FdnUtils.isNumberBlockedByFDN(phoneId, smscAddr, defaultCountryIso); 1116 } 1117 }