1 /* 2 * Copyright (C) 2006 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.Manifest.permission.MODIFY_PHONE_STATE; 22 import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; 23 24 import android.annotation.NonNull; 25 import android.annotation.Nullable; 26 import android.app.AppOpsManager; 27 import android.compat.annotation.UnsupportedAppUsage; 28 import android.content.Context; 29 import android.content.pm.PackageManager; 30 import android.os.Binder; 31 import android.os.Build; 32 import android.os.RemoteException; 33 import android.os.TelephonyServiceManager.ServiceRegisterer; 34 import android.os.UserHandle; 35 import android.telephony.ImsiEncryptionInfo; 36 import android.telephony.PhoneNumberUtils; 37 import android.telephony.SubscriptionManager; 38 import android.telephony.TelephonyFrameworkInitializer; 39 import android.util.EventLog; 40 41 import com.android.internal.telephony.uicc.IsimRecords; 42 import com.android.internal.telephony.uicc.UiccCard; 43 import com.android.internal.telephony.uicc.UiccCardApplication; 44 import com.android.telephony.Rlog; 45 46 public class PhoneSubInfoController extends IPhoneSubInfo.Stub { 47 private static final String TAG = "PhoneSubInfoController"; 48 private static final boolean DBG = true; 49 private static final boolean VDBG = false; // STOPSHIP if true 50 51 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 52 private final Context mContext; 53 private AppOpsManager mAppOps; 54 PhoneSubInfoController(Context context)55 public PhoneSubInfoController(Context context) { 56 ServiceRegisterer phoneSubServiceRegisterer = TelephonyFrameworkInitializer 57 .getTelephonyServiceManager() 58 .getPhoneSubServiceRegisterer(); 59 if (phoneSubServiceRegisterer.get() == null) { 60 phoneSubServiceRegisterer.register(this); 61 } 62 mAppOps = context.getSystemService(AppOpsManager.class); 63 mContext = context; 64 } 65 66 @Deprecated getDeviceId(String callingPackage)67 public String getDeviceId(String callingPackage) { 68 return getDeviceIdWithFeature(callingPackage, null); 69 } 70 getDeviceIdWithFeature(String callingPackage, String callingFeatureId)71 public String getDeviceIdWithFeature(String callingPackage, String callingFeatureId) { 72 return getDeviceIdForPhone(SubscriptionManager.getPhoneId(getDefaultSubscription()), 73 callingPackage, callingFeatureId); 74 } 75 getDeviceIdForPhone(int phoneId, String callingPackage, String callingFeatureId)76 public String getDeviceIdForPhone(int phoneId, String callingPackage, 77 String callingFeatureId) { 78 enforceCallingPackageUidMatched(callingPackage); 79 return callPhoneMethodForPhoneIdWithReadDeviceIdentifiersCheck(phoneId, callingPackage, 80 callingFeatureId, "getDeviceId", (phone) -> phone.getDeviceId()); 81 } 82 getNaiForSubscriber(int subId, String callingPackage, String callingFeatureId)83 public String getNaiForSubscriber(int subId, String callingPackage, String callingFeatureId) { 84 return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage, 85 callingFeatureId, "getNai", (phone)-> phone.getNai()); 86 } 87 getImeiForSubscriber(int subId, String callingPackage, String callingFeatureId)88 public String getImeiForSubscriber(int subId, String callingPackage, 89 String callingFeatureId) { 90 return callPhoneMethodForSubIdWithReadDeviceIdentifiersCheck(subId, callingPackage, 91 callingFeatureId, "getImei", (phone) -> phone.getImei()); 92 } 93 getCarrierInfoForImsiEncryption(int subId, int keyType, String callingPackage)94 public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType, 95 String callingPackage) { 96 return callPhoneMethodForSubIdWithPrivilegedCheck(subId, 97 "getCarrierInfoForImsiEncryption", 98 (phone)-> phone.getCarrierInfoForImsiEncryption(keyType, true)); 99 } 100 setCarrierInfoForImsiEncryption(int subId, String callingPackage, ImsiEncryptionInfo imsiEncryptionInfo)101 public void setCarrierInfoForImsiEncryption(int subId, String callingPackage, 102 ImsiEncryptionInfo imsiEncryptionInfo) { 103 callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, 104 "setCarrierInfoForImsiEncryption", 105 (phone)-> { 106 phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo); 107 return null; 108 }); 109 } 110 111 /** 112 * Resets the Carrier Keys in the database. This involves 2 steps: 113 * 1. Delete the keys from the database. 114 * 2. Send an intent to download new Certificates. 115 * @param subId 116 * @param callingPackage 117 */ resetCarrierKeysForImsiEncryption(int subId, String callingPackage)118 public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) { 119 callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, 120 "resetCarrierKeysForImsiEncryption", 121 (phone)-> { 122 phone.resetCarrierKeysForImsiEncryption(); 123 return null; 124 }); 125 } 126 getDeviceSvn(String callingPackage, String callingFeatureId)127 public String getDeviceSvn(String callingPackage, String callingFeatureId) { 128 return getDeviceSvnUsingSubId(getDefaultSubscription(), callingPackage, callingFeatureId); 129 } 130 getDeviceSvnUsingSubId(int subId, String callingPackage, String callingFeatureId)131 public String getDeviceSvnUsingSubId(int subId, String callingPackage, 132 String callingFeatureId) { 133 return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, 134 "getDeviceSvn", (phone)-> phone.getDeviceSvn()); 135 } 136 137 @Deprecated getSubscriberId(String callingPackage)138 public String getSubscriberId(String callingPackage) { 139 return getSubscriberIdWithFeature(callingPackage, null); 140 } 141 getSubscriberIdWithFeature(String callingPackage, String callingFeatureId)142 public String getSubscriberIdWithFeature(String callingPackage, String callingFeatureId) { 143 return getSubscriberIdForSubscriber(getDefaultSubscription(), callingPackage, 144 callingFeatureId); 145 } 146 getSubscriberIdForSubscriber(int subId, String callingPackage, String callingFeatureId)147 public String getSubscriberIdForSubscriber(int subId, String callingPackage, 148 String callingFeatureId) { 149 String message = "getSubscriberIdForSubscriber"; 150 151 enforceCallingPackage(callingPackage, Binder.getCallingUid(), message); 152 153 long identity = Binder.clearCallingIdentity(); 154 boolean isActive; 155 try { 156 isActive = SubscriptionController.getInstance().isActiveSubId(subId, callingPackage, 157 callingFeatureId); 158 } finally { 159 Binder.restoreCallingIdentity(identity); 160 } 161 if (isActive) { 162 return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage, 163 callingFeatureId, message, (phone) -> phone.getSubscriberId()); 164 } else { 165 if (!TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers( 166 mContext, subId, callingPackage, callingFeatureId, message)) { 167 return null; 168 } 169 identity = Binder.clearCallingIdentity(); 170 try { 171 return SubscriptionController.getInstance().getImsiPrivileged(subId); 172 } finally { 173 Binder.restoreCallingIdentity(identity); 174 } 175 } 176 } 177 178 @Deprecated getIccSerialNumber(String callingPackage)179 public String getIccSerialNumber(String callingPackage) { 180 return getIccSerialNumberWithFeature(callingPackage, null); 181 } 182 183 /** 184 * Retrieves the serial number of the ICC, if applicable. 185 */ getIccSerialNumberWithFeature(String callingPackage, String callingFeatureId)186 public String getIccSerialNumberWithFeature(String callingPackage, String callingFeatureId) { 187 return getIccSerialNumberForSubscriber(getDefaultSubscription(), callingPackage, 188 callingFeatureId); 189 } 190 getIccSerialNumberForSubscriber(int subId, String callingPackage, String callingFeatureId)191 public String getIccSerialNumberForSubscriber(int subId, String callingPackage, 192 String callingFeatureId) { 193 return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage, 194 callingFeatureId, "getIccSerialNumber", (phone) -> phone.getIccSerialNumber()); 195 } 196 getLine1Number(String callingPackage, String callingFeatureId)197 public String getLine1Number(String callingPackage, String callingFeatureId) { 198 return getLine1NumberForSubscriber(getDefaultSubscription(), callingPackage, 199 callingFeatureId); 200 } 201 202 // In R and beyond, READ_PHONE_NUMBERS includes READ_PHONE_NUMBERS and READ_SMS only. 203 // Prior to R, it also included READ_PHONE_STATE. Maintain that for compatibility. getLine1NumberForSubscriber(int subId, String callingPackage, String callingFeatureId)204 public String getLine1NumberForSubscriber(int subId, String callingPackage, 205 String callingFeatureId) { 206 return callPhoneMethodForSubIdWithReadPhoneNumberCheck( 207 subId, callingPackage, callingFeatureId, "getLine1Number", 208 (phone)-> phone.getLine1Number()); 209 } 210 getLine1AlphaTag(String callingPackage, String callingFeatureId)211 public String getLine1AlphaTag(String callingPackage, String callingFeatureId) { 212 return getLine1AlphaTagForSubscriber(getDefaultSubscription(), callingPackage, 213 callingFeatureId); 214 } 215 getLine1AlphaTagForSubscriber(int subId, String callingPackage, String callingFeatureId)216 public String getLine1AlphaTagForSubscriber(int subId, String callingPackage, 217 String callingFeatureId) { 218 return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, 219 "getLine1AlphaTag", (phone)-> phone.getLine1AlphaTag()); 220 } 221 getMsisdn(String callingPackage, String callingFeatureId)222 public String getMsisdn(String callingPackage, String callingFeatureId) { 223 return getMsisdnForSubscriber(getDefaultSubscription(), callingPackage, callingFeatureId); 224 } 225 226 // In R and beyond this will require READ_PHONE_NUMBERS. 227 // Prior to R it needed READ_PHONE_STATE. Maintain that for compatibility. getMsisdnForSubscriber(int subId, String callingPackage, String callingFeatureId)228 public String getMsisdnForSubscriber(int subId, String callingPackage, 229 String callingFeatureId) { 230 return callPhoneMethodForSubIdWithReadPhoneNumberCheck( 231 subId, callingPackage, callingFeatureId, "getMsisdn", (phone)-> phone.getMsisdn()); 232 } 233 getVoiceMailNumber(String callingPackage, String callingFeatureId)234 public String getVoiceMailNumber(String callingPackage, String callingFeatureId) { 235 return getVoiceMailNumberForSubscriber(getDefaultSubscription(), callingPackage, 236 callingFeatureId); 237 } 238 getVoiceMailNumberForSubscriber(int subId, String callingPackage, String callingFeatureId)239 public String getVoiceMailNumberForSubscriber(int subId, String callingPackage, 240 String callingFeatureId) { 241 return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, 242 "getVoiceMailNumber", (phone)-> { 243 String number = PhoneNumberUtils.extractNetworkPortion( 244 phone.getVoiceMailNumber()); 245 if (VDBG) log("VM: getVoiceMailNUmber: " + number); 246 return number; 247 }); 248 } 249 getVoiceMailAlphaTag(String callingPackage, String callingFeatureId)250 public String getVoiceMailAlphaTag(String callingPackage, String callingFeatureId) { 251 return getVoiceMailAlphaTagForSubscriber(getDefaultSubscription(), callingPackage, 252 callingFeatureId); 253 } 254 getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage, String callingFeatureId)255 public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage, 256 String callingFeatureId) { 257 return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, 258 "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag()); 259 } 260 261 /** 262 * get Phone object based on subId. 263 **/ 264 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getPhone(int subId)265 private Phone getPhone(int subId) { 266 int phoneId = SubscriptionManager.getPhoneId(subId); 267 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 268 return null; 269 } 270 return PhoneFactory.getPhone(phoneId); 271 } 272 enforceCallingPackageUidMatched(String callingPackage)273 private void enforceCallingPackageUidMatched(String callingPackage) { 274 try { 275 mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); 276 } catch (SecurityException se) { 277 EventLog.writeEvent(0x534e4554, "188677422", Binder.getCallingUid()); 278 throw se; 279 } 280 } 281 enforceIccSimChallengeResponsePermission(Context context, int subId, String callingPackage, String callingFeatureId, String message)282 private boolean enforceIccSimChallengeResponsePermission(Context context, int subId, 283 String callingPackage, String callingFeatureId, String message) { 284 if (TelephonyPermissions.checkCallingOrSelfUseIccAuthWithDeviceIdentifier(context, 285 callingPackage, callingFeatureId, message)) { 286 return true; 287 } 288 if (VDBG) log("No USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER permission."); 289 enforcePrivilegedPermissionOrCarrierPrivilege(subId, message); 290 return true; 291 } 292 293 /** 294 * Make sure caller has either read privileged phone permission or carrier privilege. 295 * 296 * @throws SecurityException if the caller does not have the required permission/privilege 297 */ enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message)298 private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) { 299 // TODO(b/73660190): Migrate to 300 // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete 301 // this helper method. 302 int permissionResult = mContext.checkCallingOrSelfPermission( 303 READ_PRIVILEGED_PHONE_STATE); 304 if (permissionResult == PackageManager.PERMISSION_GRANTED) { 305 return; 306 } 307 if (VDBG) log("No read privileged phone permission, check carrier privilege next."); 308 TelephonyPermissions.enforceCallingOrSelfCarrierPrivilege(mContext, subId, message); 309 } 310 311 /** 312 * Make sure caller has modify phone state permission. 313 */ enforceModifyPermission()314 private void enforceModifyPermission() { 315 mContext.enforceCallingOrSelfPermission(MODIFY_PHONE_STATE, 316 "Requires MODIFY_PHONE_STATE"); 317 } 318 319 /** 320 * Make sure the caller is the calling package itself 321 * 322 * @throws SecurityException if the caller is not the calling package 323 */ enforceCallingPackage(String callingPackage, int callingUid, String message)324 private void enforceCallingPackage(String callingPackage, int callingUid, String message) { 325 int packageUid = -1; 326 PackageManager pm = mContext.createContextAsUser( 327 UserHandle.getUserHandleForUid(callingUid), 0).getPackageManager(); 328 if (pm != null) { 329 try { 330 packageUid = pm.getPackageUid(callingPackage, 0); 331 } catch (PackageManager.NameNotFoundException e) { 332 // packageUid is -1 333 } 334 } 335 if (packageUid != callingUid) { 336 throw new SecurityException(message + ": Package " + callingPackage 337 + " does not belong to " + callingUid); 338 } 339 } 340 341 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) getDefaultSubscription()342 private int getDefaultSubscription() { 343 return PhoneFactory.getDefaultSubscription(); 344 } 345 346 /** 347 * get the Isim Impi based on subId 348 */ getIsimImpi(int subId)349 public String getIsimImpi(int subId) { 350 return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpi", 351 (phone) -> { 352 IsimRecords isim = phone.getIsimRecords(); 353 if (isim != null) { 354 return isim.getIsimImpi(); 355 } else { 356 return null; 357 } 358 }); 359 } 360 361 /** 362 * get the Isim Domain based on subId 363 */ 364 public String getIsimDomain(int subId) { 365 return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimDomain", 366 (phone) -> { 367 IsimRecords isim = phone.getIsimRecords(); 368 if (isim != null) { 369 return isim.getIsimDomain(); 370 } else { 371 return null; 372 } 373 }); 374 } 375 376 /** 377 * get the Isim Impu based on subId 378 */ 379 public String[] getIsimImpu(int subId) { 380 return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpu", 381 (phone) -> { 382 IsimRecords isim = phone.getIsimRecords(); 383 if (isim != null) { 384 return isim.getIsimImpu(); 385 } else { 386 return null; 387 } 388 }); 389 } 390 391 /** 392 * get the Isim Ist based on subId 393 */ 394 public String getIsimIst(int subId) throws RemoteException { 395 return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimIst", 396 (phone) -> { 397 IsimRecords isim = phone.getIsimRecords(); 398 if (isim != null) { 399 return isim.getIsimIst(); 400 } else { 401 return null; 402 } 403 }); 404 } 405 406 /** 407 * get the Isim Pcscf based on subId 408 */ 409 public String[] getIsimPcscf(int subId) throws RemoteException { 410 return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimPcscf", 411 (phone) -> { 412 IsimRecords isim = phone.getIsimRecords(); 413 if (isim != null) { 414 return isim.getIsimPcscf(); 415 } else { 416 return null; 417 } 418 }); 419 } 420 421 @Override 422 public String getIccSimChallengeResponse(int subId, int appType, int authType, String data, 423 String callingPackage, String callingFeatureId) throws RemoteException { 424 CallPhoneMethodHelper<String> toExecute = (phone)-> { 425 UiccCard uiccCard = phone.getUiccCard(); 426 if (uiccCard == null) { 427 loge("getIccSimChallengeResponse() UiccCard is null"); 428 return null; 429 } 430 431 UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType); 432 if (uiccApp == null) { 433 loge("getIccSimChallengeResponse() no app with specified type -- " + appType); 434 return null; 435 } else { 436 loge("getIccSimChallengeResponse() found app " + uiccApp.getAid() 437 + " specified type -- " + appType); 438 } 439 440 if (authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM 441 && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) { 442 loge("getIccSimChallengeResponse() unsupported authType: " + authType); 443 return null; 444 } 445 return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data); 446 }; 447 448 return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId, 449 "getIccSimChallengeResponse", toExecute, 450 this::enforceIccSimChallengeResponsePermission); 451 } 452 453 public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage, 454 String callingFeatureId) { 455 return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, 456 "getGroupIdLevel1", (phone)-> phone.getGroupIdLevel1()); 457 } 458 459 /** Below are utility methods that abstracts the flow that many public methods use: 460 * 1. Check permission: pass, throw exception, or fails (returns false). 461 * 2. clearCallingIdentity. 462 * 3. Call a specified phone method and get return value. 463 * 4. restoreCallingIdentity and return. 464 */ 465 private interface CallPhoneMethodHelper<T> { 466 T callMethod(Phone phone); 467 } 468 469 private interface PermissionCheckHelper { 470 // Implemented to do whatever permission check it wants. 471 // If passes, it should return true. 472 // If permission is not granted, throws SecurityException. 473 // If permission is revoked by AppOps, return false. 474 boolean checkPermission(Context context, int subId, String callingPackage, 475 @Nullable String callingFeatureId, String message); 476 } 477 478 // Base utility method that others use. 479 private <T> T callPhoneMethodWithPermissionCheck(int subId, String callingPackage, 480 @Nullable String callingFeatureId, String message, 481 CallPhoneMethodHelper<T> callMethodHelper, 482 PermissionCheckHelper permissionCheckHelper) { 483 if (!permissionCheckHelper.checkPermission(mContext, subId, callingPackage, 484 callingFeatureId, message)) { 485 return null; 486 } 487 488 final long identity = Binder.clearCallingIdentity(); 489 try { 490 Phone phone = getPhone(subId); 491 if (phone != null) { 492 return callMethodHelper.callMethod(phone); 493 } else { 494 loge(message + " phone is null for Subscription:" + subId); 495 return null; 496 } 497 } finally { 498 Binder.restoreCallingIdentity(identity); 499 } 500 } 501 502 private <T> T callPhoneMethodForSubIdWithReadCheck(int subId, String callingPackage, 503 @Nullable String callingFeatureId, String message, 504 CallPhoneMethodHelper<T> callMethodHelper) { 505 return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId, 506 message, callMethodHelper, 507 (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)-> 508 TelephonyPermissions.checkCallingOrSelfReadPhoneState( 509 aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)); 510 } 511 512 private <T> T callPhoneMethodForSubIdWithReadDeviceIdentifiersCheck(int subId, 513 String callingPackage, @Nullable String callingFeatureId, String message, 514 CallPhoneMethodHelper<T> callMethodHelper) { 515 return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId, 516 message, callMethodHelper, 517 (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)-> 518 TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers( 519 aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)); 520 } 521 522 private <T> T callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(int subId, 523 String callingPackage, @Nullable String callingFeatureId, String message, 524 CallPhoneMethodHelper<T> callMethodHelper) { 525 return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId, 526 message, callMethodHelper, 527 (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)-> 528 TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers( 529 aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)); 530 } 531 532 private <T> T callPhoneMethodForSubIdWithPrivilegedCheck( 533 int subId, String message, CallPhoneMethodHelper<T> callMethodHelper) { 534 return callPhoneMethodWithPermissionCheck(subId, null, null, message, callMethodHelper, 535 (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage) -> { 536 mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message); 537 return true; 538 }); 539 } 540 541 private <T> T callPhoneMethodForSubIdWithModifyCheck(int subId, String callingPackage, 542 String message, CallPhoneMethodHelper<T> callMethodHelper) { 543 return callPhoneMethodWithPermissionCheck(subId, null, null, message, callMethodHelper, 544 (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)-> { 545 enforceModifyPermission(); 546 return true; 547 }); 548 } 549 550 private <T> T callPhoneMethodForSubIdWithReadPhoneNumberCheck(int subId, String callingPackage, 551 @NonNull String callingFeatureId, String message, 552 CallPhoneMethodHelper<T> callMethodHelper) { 553 return callPhoneMethodWithPermissionCheck(subId, callingPackage, callingFeatureId, 554 message, callMethodHelper, 555 (aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage) -> 556 TelephonyPermissions.checkCallingOrSelfReadPhoneNumber( 557 aContext, aSubId, aCallingPackage, aCallingFeatureId, aMessage)); 558 } 559 560 private <T> T callPhoneMethodForPhoneIdWithReadDeviceIdentifiersCheck(int phoneId, 561 String callingPackage, @Nullable String callingFeatureId, String message, 562 CallPhoneMethodHelper<T> callMethodHelper) { 563 // Getting subId before doing permission check. 564 if (!SubscriptionManager.isValidPhoneId(phoneId)) { 565 phoneId = 0; 566 } 567 final Phone phone = PhoneFactory.getPhone(phoneId); 568 if (phone == null) { 569 return null; 570 } 571 if (!TelephonyPermissions.checkCallingOrSelfReadDeviceIdentifiers(mContext, 572 phone.getSubId(), callingPackage, callingFeatureId, message)) { 573 return null; 574 } 575 576 final long identity = Binder.clearCallingIdentity(); 577 try { 578 return callMethodHelper.callMethod(phone); 579 } finally { 580 Binder.restoreCallingIdentity(identity); 581 } 582 } 583 584 private void log(String s) { 585 Rlog.d(TAG, s); 586 } 587 588 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) 589 private void loge(String s) { 590 Rlog.e(TAG, s); 591 } 592 } 593