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