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