• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2020 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.internal.telephony;
18 
19 import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
20 import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
21 import static android.telephony.CarrierConfigManager.KEY_CARRIER_CERTIFICATE_STRING_ARRAY;
22 import static android.telephony.SubscriptionManager.INVALID_SIM_SLOT_INDEX;
23 import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
24 import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
25 import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
26 import static android.telephony.TelephonyManager.CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
27 import static android.telephony.TelephonyManager.EXTRA_SIM_STATE;
28 import static android.telephony.TelephonyManager.SIM_STATE_ABSENT;
29 import static android.telephony.TelephonyManager.SIM_STATE_LOADED;
30 import static android.telephony.TelephonyManager.SIM_STATE_NOT_READY;
31 import static android.telephony.TelephonyManager.SIM_STATE_READY;
32 import static android.telephony.TelephonyManager.SIM_STATE_UNKNOWN;
33 
34 import static com.android.internal.telephony.SubscriptionInfoUpdater.simStateString;
35 
36 import android.annotation.ElapsedRealtimeLong;
37 import android.annotation.NonNull;
38 import android.annotation.Nullable;
39 import android.app.ActivityManager;
40 import android.content.BroadcastReceiver;
41 import android.content.Context;
42 import android.content.Intent;
43 import android.content.IntentFilter;
44 import android.content.pm.PackageInfo;
45 import android.content.pm.PackageManager;
46 import android.content.pm.PackageManager.NameNotFoundException;
47 import android.content.pm.ResolveInfo;
48 import android.content.pm.Signature;
49 import android.content.pm.UserInfo;
50 import android.net.Uri;
51 import android.os.Bundle;
52 import android.os.Handler;
53 import android.os.Looper;
54 import android.os.Message;
55 import android.os.PersistableBundle;
56 import android.os.Process;
57 import android.os.Registrant;
58 import android.os.RegistrantList;
59 import android.os.SystemClock;
60 import android.os.UserHandle;
61 import android.os.UserManager;
62 import android.service.carrier.CarrierService;
63 import android.telephony.Annotation.CarrierPrivilegeStatus;
64 import android.telephony.CarrierConfigManager;
65 import android.telephony.SubscriptionManager;
66 import android.telephony.TelephonyManager;
67 import android.telephony.TelephonyRegistryManager;
68 import android.telephony.UiccAccessRule;
69 import android.text.TextUtils;
70 import android.util.ArrayMap;
71 import android.util.ArraySet;
72 import android.util.IntArray;
73 import android.util.LocalLog;
74 import android.util.Pair;
75 
76 import com.android.internal.annotations.GuardedBy;
77 import com.android.internal.telephony.uicc.IccUtils;
78 import com.android.internal.telephony.uicc.UiccPort;
79 import com.android.internal.telephony.uicc.UiccProfile;
80 import com.android.telephony.Rlog;
81 
82 import java.io.FileDescriptor;
83 import java.io.PrintWriter;
84 import java.util.ArrayList;
85 import java.util.Arrays;
86 import java.util.Collection;
87 import java.util.Collections;
88 import java.util.List;
89 import java.util.Map;
90 import java.util.Objects;
91 import java.util.Set;
92 import java.util.StringJoiner;
93 import java.util.concurrent.TimeUnit;
94 import java.util.concurrent.locks.ReadWriteLock;
95 import java.util.concurrent.locks.ReentrantReadWriteLock;
96 import java.util.function.Function;
97 
98 /**
99  * CarrierPrivilegesTracker will track the Carrier Privileges for a specific {@link Phone}.
100  * Registered Telephony entities will receive notifications when the UIDs with these privileges
101  * change.
102  */
103 public class CarrierPrivilegesTracker extends Handler {
104     private static final String TAG = CarrierPrivilegesTracker.class.getSimpleName();
105 
106     private static final boolean VDBG = false;
107 
108     private static final String SHA_1 = "SHA-1";
109     private static final String SHA_256 = "SHA-256";
110 
111     private static final int PACKAGE_NOT_PRIVILEGED = 0;
112     private static final int PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG = 1;
113     private static final int PACKAGE_PRIVILEGED_FROM_SIM = 2;
114 
115     // TODO(b/232273884): Turn feature on when find solution to handle the inter-carriers switching
116     /**
117      * Time delay to clear UICC rules after UICC is gone.
118      * This introduces the grace period to retain carrier privileges when SIM is removed.
119      *
120      * This feature is off by default due to the security concern during inter-carriers switching.
121      */
122     private static final long CLEAR_UICC_RULES_DELAY_MILLIS = TimeUnit.SECONDS.toMillis(0);
123 
124     /**
125      * PackageManager flags used to query installed packages.
126      * Include DISABLED_UNTIL_USED components. This facilitates cases where a carrier app
127      * is disabled by default, and some other component wants to enable it when it has
128      * gained carrier privileges (as an indication that a matching SIM has been inserted).
129      */
130     private static final int INSTALLED_PACKAGES_QUERY_FLAGS =
131             PackageManager.GET_SIGNING_CERTIFICATES
132                     | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
133                     | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
134 
135     /**
136      * Action to register a Registrant with this Tracker.
137      * obj: Registrant that will be notified of Carrier Privileged UID changes.
138      */
139     private static final int ACTION_REGISTER_LISTENER = 1;
140 
141     /**
142      * Action to unregister a Registrant with this Tracker.
143      * obj: Handler used by the Registrant that will be removed.
144      */
145     private static final int ACTION_UNREGISTER_LISTENER = 2;
146 
147     /**
148      * Action for tracking when Carrier Configs are updated.
149      * arg1: Subscription Id for the Carrier Configs update being broadcast
150      * arg2: Slot Index for the Carrier Configs update being broadcast
151      */
152     private static final int ACTION_CARRIER_CONFIG_CERTS_UPDATED = 3;
153 
154     /**
155      * Action for tracking when the Phone's SIM state changes.
156      * arg1: slotId that this Action applies to
157      * arg2: simState reported by this Broadcast
158      */
159     private static final int ACTION_SIM_STATE_UPDATED = 4;
160 
161     /**
162      * Action for tracking when a package is installed, replaced or changed (exclude the case
163      * disabled by user) on the device.
164      * obj: String package name that was installed, replaced or changed on the device.
165      */
166     private static final int ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED = 5;
167 
168     /**
169      * Action for tracking when a package is uninstalled or disabled by user on the device.
170      * obj: String package name that was installed or disabled by user on the device.
171      */
172     private static final int ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER = 6;
173 
174     /**
175      * Action used to initialize the state of the Tracker.
176      */
177     private static final int ACTION_INITIALIZE_TRACKER = 7;
178 
179     /**
180      * Action to set the test override rule through {@link TelephonyManager#setCarrierTestOverride}.
181      * obj: String of the carrierPrivilegeRules from method setCarrierTestOverride.
182      */
183     private static final int ACTION_SET_TEST_OVERRIDE_RULE = 8;
184 
185     /**
186      * Action to clear UICC rules.
187      */
188     private static final int ACTION_CLEAR_UICC_RULES = 9;
189 
190     /**
191      * Action to handle the case when UiccAccessRules has been loaded.
192      */
193     private static final int ACTION_UICC_ACCESS_RULES_LOADED = 10;
194 
195     private final Context mContext;
196     private final Phone mPhone;
197     private final PackageManager mPackageManager;
198     private final UserManager mUserManager;
199     private final CarrierConfigManager mCarrierConfigManager;
200     private final TelephonyManager mTelephonyManager;
201     private final TelephonyRegistryManager mTelephonyRegistryManager;
202 
203     @NonNull private final LocalLog mLocalLog = new LocalLog(64);
204     @NonNull private final RegistrantList mRegistrantList = new RegistrantList();
205     // Stores rules for Carrier Config-loaded rules
206     @NonNull private final List<UiccAccessRule> mCarrierConfigRules = new ArrayList<>();
207     // Stores rules for SIM-loaded rules.
208     @NonNull private final List<UiccAccessRule> mUiccRules = new ArrayList<>();
209     // Stores rule from test override (through TelephonyManager#setCarrierTestOverride).
210     // - Null list indicates no test override (CC and UICC rules are respected)
211     // - Empty list indicates test override to simulate no rules (CC and UICC rules are ignored)
212     // - Non-empty list indicates test override with specific rules (CC and UICC rules are ignored)
213     @Nullable private List<UiccAccessRule> mTestOverrideRules = null;
214     // Map of PackageName -> Certificate hashes for that Package
215     @NonNull private final Map<String, Set<String>> mInstalledPackageCerts = new ArrayMap<>();
216     // Map of PackageName -> UIDs for that Package
217     @NonNull private final Map<String, Set<Integer>> mCachedUids = new ArrayMap<>();
218 
219     // This should be used to guard critical section either with
220     // mPrivilegedPackageInfoLock.readLock() or mPrivilegedPackageInfoLock.writeLock(), but never
221     // with the mPrivilegedPackageInfoLock object itself.
222     @NonNull private final ReadWriteLock mPrivilegedPackageInfoLock = new ReentrantReadWriteLock();
223     // Package names and UIDs of apps that currently hold carrier privileges.
224     @GuardedBy(anyOf = {"mPrivilegedPackageInfoLock.readLock()",
225             "mPrivilegedPackageInfoLock.writeLock()"})
226     @NonNull private PrivilegedPackageInfo mPrivilegedPackageInfo = new PrivilegedPackageInfo();
227 
228     // Uptime in millis on when the NEXT clear-up of UiccRules are scheduled
229     @ElapsedRealtimeLong
230     private long mClearUiccRulesUptimeMillis = CLEAR_UICC_RULE_NOT_SCHEDULED;
231     // Constant indicates no schedule to clear UiccRules
232     private static final long CLEAR_UICC_RULE_NOT_SCHEDULED = -1;
233 
234     // Indicates SIM has reached SIM_STATE_READY but not SIM_STATE_LOADED yet. During this transient
235     // state, all the information previously loaded from SIM may be updated soon later and thus
236     // unreliable. For security's concern, any carrier privileges check should return
237     // CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED (instead of neither HAS_ACCESS nor NO_ACCESS) until
238     // SIM becomes LOADED again, or grace period specified by CLEAR_UICC_RULES_DELAY_MILLIS expires.
239     @GuardedBy(anyOf = {"mPrivilegedPackageInfoLock.readLock()",
240             "mPrivilegedPackageInfoLock.writeLock()"})
241     private boolean mSimIsReadyButNotLoaded = false;
242 
243     /** Small snapshot to hold package names and UIDs of privileged packages. */
244     private static final class PrivilegedPackageInfo {
245         @NonNull final Set<String> mPackageNames;
246         @NonNull final Set<Integer> mUids;
247         // The carrier service (packageName, UID) pair
248         @NonNull final Pair<String, Integer> mCarrierService;
249 
PrivilegedPackageInfo()250         PrivilegedPackageInfo() {
251             mPackageNames = Collections.emptySet();
252             mUids = Collections.emptySet();
253             mCarrierService = new Pair<>(null, Process.INVALID_UID);
254         }
255 
PrivilegedPackageInfo(@onNull Set<String> packageNames, @NonNull Set<Integer> uids, @NonNull Pair<String, Integer> carrierService)256         PrivilegedPackageInfo(@NonNull Set<String> packageNames, @NonNull Set<Integer> uids,
257                 @NonNull Pair<String, Integer> carrierService) {
258             mPackageNames = packageNames;
259             mUids = uids;
260             mCarrierService = carrierService;
261         }
262 
263         @Override
toString()264         public String toString() {
265             return "{packageNames="
266                     + getObfuscatedPackages(mPackageNames, pkg -> Rlog.pii(TAG, pkg))
267                     + ", uids="
268                     + mUids
269                     + ", carrierServicePackageName="
270                     + Rlog.pii(TAG, mCarrierService.first)
271                     + ", carrierServiceUid="
272                     + mCarrierService.second
273                     + "}";
274         }
275 
276         @Override
equals(Object o)277         public boolean equals(Object o) {
278             if (this == o) {
279                 return true;
280             }
281             if (!(o instanceof PrivilegedPackageInfo)) {
282                 return false;
283             }
284             PrivilegedPackageInfo other = (PrivilegedPackageInfo) o;
285             return mPackageNames.equals(other.mPackageNames) && mUids.equals(other.mUids)
286                     && mCarrierService.equals(other.mCarrierService);
287         }
288 
289         @Override
hashCode()290         public int hashCode() {
291             return Objects.hash(mPackageNames, mUids, mCarrierService);
292         }
293     }
294 
295     private final BroadcastReceiver mIntentReceiver =
296             new BroadcastReceiver() {
297                 @Override
298                 public void onReceive(Context context, Intent intent) {
299                     String action = intent.getAction();
300                     if (action == null) return;
301 
302                     switch (action) {
303                         case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED: {
304                             Bundle extras = intent.getExtras();
305                             int slotIndex = extras.getInt(EXTRA_SLOT_INDEX);
306                             int subId =
307                                     extras.getInt(
308                                             EXTRA_SUBSCRIPTION_INDEX, INVALID_SUBSCRIPTION_ID);
309                             sendMessage(
310                                     obtainMessage(
311                                             ACTION_CARRIER_CONFIG_CERTS_UPDATED,
312                                             subId,
313                                             slotIndex));
314                             break;
315                         }
316                         case TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED: // fall through
317                         case TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED: {
318                             Bundle extras = intent.getExtras();
319                             int simState = extras.getInt(EXTRA_SIM_STATE, SIM_STATE_UNKNOWN);
320                             int slotId =
321                                     extras.getInt(PhoneConstants.PHONE_KEY, INVALID_SIM_SLOT_INDEX);
322 
323                             if (simState != SIM_STATE_ABSENT
324                                     && simState != SIM_STATE_NOT_READY
325                                     && simState != SIM_STATE_READY
326                                     && simState != SIM_STATE_LOADED) {
327                                 return;
328                             }
329 
330                             sendMessage(obtainMessage(ACTION_SIM_STATE_UPDATED, slotId, simState));
331                             break;
332                         }
333                         case Intent.ACTION_PACKAGE_ADDED: // fall through
334                         case Intent.ACTION_PACKAGE_REPLACED: // fall through
335                         case Intent.ACTION_PACKAGE_REMOVED: // fall through
336                         case Intent.ACTION_PACKAGE_CHANGED: {
337                             Uri uri = intent.getData();
338                             String pkgName = (uri != null) ? uri.getSchemeSpecificPart() : null;
339                             if (TextUtils.isEmpty(pkgName)) {
340                                 Rlog.e(TAG, "Failed to get package from Intent");
341                                 return;
342                             }
343 
344                             boolean removed = action.equals(Intent.ACTION_PACKAGE_REMOVED);
345                             boolean disabledByUser = false;
346                             boolean notExist = false;
347                             try {
348                                 disabledByUser = action.equals(Intent.ACTION_PACKAGE_CHANGED)
349                                         && mPackageManager.getApplicationEnabledSetting(pkgName)
350                                         == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
351                             } catch (IllegalArgumentException iae) {
352                                 // Very rare case when package changed race with package removed
353                                 Rlog.w(TAG, "Package does not exist: " + pkgName);
354                                 notExist = true;
355                             }
356                             // When a package is explicitly disabled by the user or does not exist,
357                             // treat them as if it was removed: clear it from the cache
358                             int what = (removed || disabledByUser || notExist)
359                                     ? ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER
360                                     : ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED;
361 
362                             sendMessage(obtainMessage(what, pkgName));
363                             break;
364                         }
365                     }
366                 }
367             };
368 
CarrierPrivilegesTracker( @onNull Looper looper, @NonNull Phone phone, @NonNull Context context)369     public CarrierPrivilegesTracker(
370             @NonNull Looper looper, @NonNull Phone phone, @NonNull Context context) {
371         super(looper);
372         mContext = context;
373         mPhone = phone;
374         mPackageManager = mContext.getPackageManager();
375         mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
376         mCarrierConfigManager =
377                 (CarrierConfigManager) mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
378         mTelephonyManager = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
379         mTelephonyRegistryManager =
380                 (TelephonyRegistryManager)
381                         mContext.getSystemService(Context.TELEPHONY_REGISTRY_SERVICE);
382 
383         IntentFilter certFilter = new IntentFilter();
384         certFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
385         certFilter.addAction(TelephonyManager.ACTION_SIM_CARD_STATE_CHANGED);
386         certFilter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
387         mContext.registerReceiver(mIntentReceiver, certFilter);
388 
389         IntentFilter packageFilter = new IntentFilter();
390         packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
391         packageFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
392         packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
393         packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);
394 
395         // For package-related broadcasts, specify the data scheme for "package" to receive the
396         // package name along with the broadcast
397         packageFilter.addDataScheme("package");
398         mContext.registerReceiver(mIntentReceiver, packageFilter);
399 
400         sendMessage(obtainMessage(ACTION_INITIALIZE_TRACKER));
401     }
402 
403     @Override
handleMessage(Message msg)404     public void handleMessage(Message msg) {
405         switch (msg.what) {
406             case ACTION_REGISTER_LISTENER: {
407                 handleRegisterListener((Registrant) msg.obj);
408                 break;
409             }
410             case ACTION_UNREGISTER_LISTENER: {
411                 handleUnregisterListener((Handler) msg.obj);
412                 break;
413             }
414             case ACTION_CARRIER_CONFIG_CERTS_UPDATED: {
415                 int subId = msg.arg1;
416                 int slotIndex = msg.arg2;
417                 handleCarrierConfigUpdated(subId, slotIndex);
418                 break;
419             }
420             case ACTION_SIM_STATE_UPDATED: {
421                 handleSimStateChanged(msg.arg1, msg.arg2);
422                 break;
423             }
424             case ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED: {
425                 String pkgName = (String) msg.obj;
426                 handlePackageAddedReplacedOrChanged(pkgName);
427                 break;
428             }
429             case ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER: {
430                 String pkgName = (String) msg.obj;
431                 handlePackageRemovedOrDisabledByUser(pkgName);
432                 break;
433             }
434             case ACTION_INITIALIZE_TRACKER: {
435                 handleInitializeTracker();
436                 break;
437             }
438             case ACTION_SET_TEST_OVERRIDE_RULE: {
439                 String carrierPrivilegeRules = (String) msg.obj;
440                 handleSetTestOverrideRules(carrierPrivilegeRules);
441                 break;
442             }
443             case ACTION_CLEAR_UICC_RULES: {
444                 handleClearUiccRules();
445                 break;
446             }
447             case ACTION_UICC_ACCESS_RULES_LOADED: {
448                 handleUiccAccessRulesLoaded();
449                 break;
450             }
451             default: {
452                 Rlog.e(TAG, "Received unknown msg type: " + msg.what);
453                 break;
454             }
455         }
456     }
457 
handleRegisterListener(@onNull Registrant registrant)458     private void handleRegisterListener(@NonNull Registrant registrant) {
459         mRegistrantList.add(registrant);
460         mPrivilegedPackageInfoLock.readLock().lock();
461         try {
462             // Old registrant callback still takes int[] as parameter, need conversion here
463             int[] uids = intSetToArray(mPrivilegedPackageInfo.mUids);
464             registrant.notifyResult(
465                     Arrays.copyOf(uids, uids.length));
466         } finally {
467             mPrivilegedPackageInfoLock.readLock().unlock();
468         }
469     }
470 
handleUnregisterListener(@onNull Handler handler)471     private void handleUnregisterListener(@NonNull Handler handler) {
472         mRegistrantList.remove(handler);
473     }
474 
handleCarrierConfigUpdated(int subId, int slotIndex)475     private void handleCarrierConfigUpdated(int subId, int slotIndex) {
476         if (slotIndex != mPhone.getPhoneId()) return;
477 
478         List<UiccAccessRule> updatedCarrierConfigRules = Collections.EMPTY_LIST;
479 
480         // Carrier Config broadcasts with INVALID_SUBSCRIPTION_ID when the SIM is removed. This is
481         // an expected event. When this happens, clear the certificates from the previous configs.
482         // The rules will be cleared in maybeUpdateRulesAndNotifyRegistrants() below.
483         if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
484             updatedCarrierConfigRules = getCarrierConfigRules(subId);
485         }
486 
487         mLocalLog.log("CarrierConfigUpdated:"
488                 + " subId=" + subId
489                 + " slotIndex=" + slotIndex
490                 + " updated CarrierConfig rules=" + updatedCarrierConfigRules);
491         maybeUpdateRulesAndNotifyRegistrants(mCarrierConfigRules, updatedCarrierConfigRules);
492     }
493 
494     @NonNull
getCarrierConfigRules(int subId)495     private List<UiccAccessRule> getCarrierConfigRules(int subId) {
496         PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
497         if (!mCarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) {
498             return Collections.EMPTY_LIST;
499         }
500 
501         String[] carrierConfigRules =
502                 carrierConfigs.getStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
503         if (carrierConfigRules == null) {
504             return Collections.EMPTY_LIST;
505         }
506         return Arrays.asList(UiccAccessRule.decodeRulesFromCarrierConfig(carrierConfigRules));
507     }
508 
handleSimStateChanged(int slotId, int simState)509     private void handleSimStateChanged(int slotId, int simState) {
510         if (slotId != mPhone.getPhoneId()) return;
511 
512         List<UiccAccessRule> updatedUiccRules = Collections.EMPTY_LIST;
513 
514         mPrivilegedPackageInfoLock.writeLock().lock();
515         try {
516             mSimIsReadyButNotLoaded = simState == SIM_STATE_READY;
517         } finally {
518             mPrivilegedPackageInfoLock.writeLock().unlock();
519         }
520 
521         // Only include the UICC rules if the SIM is fully loaded
522         if (simState == SIM_STATE_LOADED) {
523             mLocalLog.log("SIM fully loaded, handleUiccAccessRulesLoaded.");
524             handleUiccAccessRulesLoaded();
525         } else {
526             if (!mUiccRules.isEmpty()
527                     && mClearUiccRulesUptimeMillis == CLEAR_UICC_RULE_NOT_SCHEDULED) {
528                 mClearUiccRulesUptimeMillis =
529                         SystemClock.uptimeMillis() + CLEAR_UICC_RULES_DELAY_MILLIS;
530                 sendMessageAtTime(obtainMessage(ACTION_CLEAR_UICC_RULES),
531                         mClearUiccRulesUptimeMillis);
532                 mLocalLog.log("SIM is gone, simState=" + simStateString(simState)
533                         + ". Delay " + TimeUnit.MILLISECONDS.toSeconds(
534                         CLEAR_UICC_RULES_DELAY_MILLIS) + " seconds to clear UICC rules.");
535             } else {
536                 mLocalLog.log(
537                         "Ignore SIM gone event while UiccRules is empty or waiting to be emptied.");
538             }
539         }
540     }
541 
handleUiccAccessRulesLoaded()542     private void handleUiccAccessRulesLoaded() {
543         mClearUiccRulesUptimeMillis = CLEAR_UICC_RULE_NOT_SCHEDULED;
544         removeMessages(ACTION_CLEAR_UICC_RULES);
545 
546         List<UiccAccessRule> updatedUiccRules = getSimRules();
547         mLocalLog.log("UiccAccessRules loaded:"
548                 + " updated SIM-loaded rules=" + updatedUiccRules);
549         maybeUpdateRulesAndNotifyRegistrants(mUiccRules, updatedUiccRules);
550     }
551 
552     /** Called when UiccAccessRules has been loaded */
onUiccAccessRulesLoaded()553     public void onUiccAccessRulesLoaded() {
554         sendEmptyMessage(ACTION_UICC_ACCESS_RULES_LOADED);
555     }
556 
handleClearUiccRules()557     private void handleClearUiccRules() {
558         mClearUiccRulesUptimeMillis = CLEAR_UICC_RULE_NOT_SCHEDULED;
559         removeMessages(ACTION_CLEAR_UICC_RULES);
560         maybeUpdateRulesAndNotifyRegistrants(mUiccRules, Collections.EMPTY_LIST);
561     }
562 
563     @NonNull
getSimRules()564     private List<UiccAccessRule> getSimRules() {
565         if (!mTelephonyManager.hasIccCard(mPhone.getPhoneId())) {
566             return Collections.EMPTY_LIST;
567         }
568 
569         UiccPort uiccPort = mPhone.getUiccPort();
570         if (uiccPort == null) {
571             Rlog.w(
572                     TAG,
573                     "Null UiccPort, but hasIccCard was present for phoneId " + mPhone.getPhoneId());
574             return Collections.EMPTY_LIST;
575         }
576 
577         UiccProfile uiccProfile = uiccPort.getUiccProfile();
578         if (uiccProfile == null) {
579             Rlog.w(
580                     TAG,
581                     "Null UiccProfile, but hasIccCard was true for phoneId " + mPhone.getPhoneId());
582             return Collections.EMPTY_LIST;
583         }
584         return uiccProfile.getCarrierPrivilegeAccessRules();
585     }
586 
handlePackageAddedReplacedOrChanged(@ullable String pkgName)587     private void handlePackageAddedReplacedOrChanged(@Nullable String pkgName) {
588         if (pkgName == null) return;
589 
590         PackageInfo pkg;
591         try {
592             pkg = mPackageManager.getPackageInfo(pkgName, INSTALLED_PACKAGES_QUERY_FLAGS);
593         } catch (NameNotFoundException e) {
594             Rlog.e(TAG, "Error getting installed package: " + pkgName, e);
595             return;
596         }
597 
598         updateCertsForPackage(pkg);
599         // Invalidate cache because this may be a package already on the device but getting
600         // installed for a user it wasn't installed in before, which means there will be an
601         // additional UID.
602         getUidsForPackage(pkg.packageName, /* invalidateCache= */ true);
603         if (VDBG) {
604             Rlog.d(TAG, "Package added/replaced/changed:"
605                     + " pkg=" + Rlog.pii(TAG, pkgName)
606                     + " cert hashes=" + mInstalledPackageCerts.get(pkgName));
607         }
608 
609         maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
610     }
611 
updateCertsForPackage(@onNull PackageInfo pkg)612     private void updateCertsForPackage(@NonNull PackageInfo pkg) {
613         Set<String> certs = new ArraySet<>();
614         List<Signature> signatures = UiccAccessRule.getSignatures(pkg);
615         for (Signature signature : signatures) {
616             byte[] sha1 = UiccAccessRule.getCertHash(signature, SHA_1);
617             certs.add(IccUtils.bytesToHexString(sha1).toUpperCase());
618 
619             byte[] sha256 = UiccAccessRule.getCertHash(signature, SHA_256);
620             certs.add(IccUtils.bytesToHexString(sha256).toUpperCase());
621         }
622 
623         mInstalledPackageCerts.put(pkg.packageName, certs);
624     }
625 
handlePackageRemovedOrDisabledByUser(@ullable String pkgName)626     private void handlePackageRemovedOrDisabledByUser(@Nullable String pkgName) {
627         if (pkgName == null) return;
628 
629         if (mInstalledPackageCerts.remove(pkgName) == null || mCachedUids.remove(pkgName) == null) {
630             Rlog.e(TAG, "Unknown package was uninstalled or disabled by user: " + pkgName);
631             return;
632         }
633 
634         if (VDBG) {
635             Rlog.d(TAG, "Package removed or disabled by user: pkg=" + Rlog.pii(TAG, pkgName));
636         }
637 
638         maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
639     }
640 
handleInitializeTracker()641     private void handleInitializeTracker() {
642         // Cache CarrierConfig rules
643         mCarrierConfigRules.addAll(getCarrierConfigRules(mPhone.getSubId()));
644 
645         // Cache SIM rules
646         mUiccRules.addAll(getSimRules());
647 
648         // Cache all installed packages and their certs
649         refreshInstalledPackageCache();
650 
651         // Okay because no registrants exist yet
652         maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
653 
654         String msg = "Initializing state:"
655                 + " CarrierConfig rules=" + mCarrierConfigRules
656                 + " SIM-loaded rules=" + mUiccRules;
657         if (VDBG) {
658             msg +=
659                     " installed pkgs="
660                             + getObfuscatedPackages(
661                                     mInstalledPackageCerts.entrySet(),
662                                     e -> "pkg(" + Rlog.pii(TAG, e.getKey()) + ")=" + e.getValue());
663         }
664         mLocalLog.log(msg);
665     }
666 
refreshInstalledPackageCache()667     private void refreshInstalledPackageCache() {
668         List<PackageInfo> installedPackages =
669                 mPackageManager.getInstalledPackagesAsUser(
670                         INSTALLED_PACKAGES_QUERY_FLAGS, UserHandle.SYSTEM.getIdentifier());
671         for (PackageInfo pkg : installedPackages) {
672             updateCertsForPackage(pkg);
673             // This may be unnecessary before initialization, but invalidate the cache all the time
674             // just in case to ensure consistency.
675             getUidsForPackage(pkg.packageName, /* invalidateCache= */ true);
676         }
677     }
678 
679     @NonNull
getObfuscatedPackages( @onNull Collection<T> packageNames, @NonNull Function<T, String> obfuscator)680     private static <T> String getObfuscatedPackages(
681             @NonNull Collection<T> packageNames, @NonNull Function<T, String> obfuscator) {
682         StringJoiner obfuscated = new StringJoiner(", ", "{", "}");
683         for (T packageName : packageNames) {
684             obfuscated.add(obfuscator.apply(packageName));
685         }
686         return obfuscated.toString();
687     }
688 
maybeUpdateRulesAndNotifyRegistrants(@onNull List<UiccAccessRule> currentRules, @NonNull List<UiccAccessRule> updatedRules)689     private void maybeUpdateRulesAndNotifyRegistrants(@NonNull List<UiccAccessRule> currentRules,
690             @NonNull List<UiccAccessRule> updatedRules) {
691         if (currentRules.equals(updatedRules)) return;
692 
693         currentRules.clear();
694         currentRules.addAll(updatedRules);
695 
696         maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
697     }
698 
maybeUpdatePrivilegedPackagesAndNotifyRegistrants()699     private void maybeUpdatePrivilegedPackagesAndNotifyRegistrants() {
700         PrivilegedPackageInfo currentPrivilegedPackageInfo =
701                 getCurrentPrivilegedPackagesForAllUsers();
702 
703         boolean carrierPrivilegesPackageNamesChanged;
704         boolean carrierPrivilegesUidsChanged;
705         boolean carrierServiceChanged;
706 
707         mPrivilegedPackageInfoLock.readLock().lock();
708         try {
709             if (mPrivilegedPackageInfo.equals(currentPrivilegedPackageInfo)) return;
710 
711             mLocalLog.log("Privileged packages info changed. New state = "
712                     + currentPrivilegedPackageInfo);
713 
714             carrierPrivilegesPackageNamesChanged =
715                     !currentPrivilegedPackageInfo.mPackageNames.equals(
716                             mPrivilegedPackageInfo.mPackageNames);
717             carrierPrivilegesUidsChanged =
718                     !currentPrivilegedPackageInfo.mUids.equals(mPrivilegedPackageInfo.mUids);
719             carrierServiceChanged = !currentPrivilegedPackageInfo.mCarrierService.equals(
720                     mPrivilegedPackageInfo.mCarrierService);
721         } finally {
722             mPrivilegedPackageInfoLock.readLock().unlock();
723         }
724 
725         mPrivilegedPackageInfoLock.writeLock().lock();
726         try {
727             mPrivilegedPackageInfo = currentPrivilegedPackageInfo;
728         } finally {
729             mPrivilegedPackageInfoLock.writeLock().unlock();
730         }
731 
732         mPrivilegedPackageInfoLock.readLock().lock();
733         try {
734             // The obsoleted callback only care about UIDs
735             if (carrierPrivilegesUidsChanged) {
736                 int[] uids = intSetToArray(mPrivilegedPackageInfo.mUids);
737                 mRegistrantList.notifyResult(Arrays.copyOf(uids, uids.length));
738             }
739 
740             if (carrierPrivilegesPackageNamesChanged || carrierPrivilegesUidsChanged) {
741                 mTelephonyRegistryManager.notifyCarrierPrivilegesChanged(
742                         mPhone.getPhoneId(),
743                         Collections.unmodifiableSet(mPrivilegedPackageInfo.mPackageNames),
744                         Collections.unmodifiableSet(mPrivilegedPackageInfo.mUids));
745             }
746 
747             if (carrierServiceChanged) {
748                 mTelephonyRegistryManager.notifyCarrierServiceChanged(mPhone.getPhoneId(),
749                         mPrivilegedPackageInfo.mCarrierService.first,
750                         mPrivilegedPackageInfo.mCarrierService.second);
751             }
752         } finally {
753             mPrivilegedPackageInfoLock.readLock().unlock();
754         }
755 
756         // Update set of enabled carrier apps now that the privilege rules may have changed.
757         ActivityManager am = mContext.getSystemService(ActivityManager.class);
758         CarrierAppUtils.disableCarrierAppsUntilPrivileged(mContext.getOpPackageName(),
759                 mTelephonyManager, am.getCurrentUser(), mContext);
760     }
761 
762     @NonNull
getCurrentPrivilegedPackagesForAllUsers()763     private PrivilegedPackageInfo getCurrentPrivilegedPackagesForAllUsers() {
764         Set<String> carrierServiceEligiblePackages = new ArraySet<>();
765         Set<String> privilegedPackageNames = new ArraySet<>();
766         Set<Integer> privilegedUids = new ArraySet<>();
767         for (Map.Entry<String, Set<String>> e : mInstalledPackageCerts.entrySet()) {
768             final int priv = getPackagePrivilegedStatus(e.getKey(), e.getValue());
769             switch (priv) {
770                 case PACKAGE_PRIVILEGED_FROM_SIM:
771                     carrierServiceEligiblePackages.add(e.getKey());
772                     // fallthrough
773                 case PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG:
774                     privilegedPackageNames.add(e.getKey());
775                     privilegedUids.addAll(
776                             getUidsForPackage(e.getKey(), /* invalidateCache= */ false));
777             }
778         }
779 
780         return new PrivilegedPackageInfo(
781                 privilegedPackageNames,
782                 privilegedUids,
783                 getCarrierService(carrierServiceEligiblePackages));
784     }
785 
786     /**
787      * Returns the privilege status of the provided package.
788      *
789      * <p>Returned privilege status depends on whether a package matches the certificates from
790      * carrier config, from test overrides or from certificates stored on the SIM.
791      */
getPackagePrivilegedStatus(@onNull String pkgName, @NonNull Set<String> certs)792     private int getPackagePrivilegedStatus(@NonNull String pkgName, @NonNull Set<String> certs) {
793         // Double-nested for loops, but each collection should contain at most 2 elements in nearly
794         // every case.
795         // TODO(b/184382310) find a way to speed this up
796         for (String cert : certs) {
797             // Non-null (whether empty or not) test override rule will ignore the UICC and CC rules
798             if (mTestOverrideRules != null) {
799                 for (UiccAccessRule rule : mTestOverrideRules) {
800                     if (rule.matches(cert, pkgName)) {
801                         return PACKAGE_PRIVILEGED_FROM_SIM;
802                     }
803                 }
804             } else {
805                 for (UiccAccessRule rule : mUiccRules) {
806                     if (rule.matches(cert, pkgName)) {
807                         return PACKAGE_PRIVILEGED_FROM_SIM;
808                     }
809                 }
810                 for (UiccAccessRule rule : mCarrierConfigRules) {
811                     if (rule.matches(cert, pkgName)) {
812                         return PACKAGE_PRIVILEGED_FROM_CARRIER_CONFIG;
813                     }
814                 }
815             }
816         }
817         return PACKAGE_NOT_PRIVILEGED;
818     }
819 
820     @NonNull
getUidsForPackage(@onNull String pkgName, boolean invalidateCache)821     private Set<Integer> getUidsForPackage(@NonNull String pkgName, boolean invalidateCache) {
822         if (invalidateCache) {
823             mCachedUids.remove(pkgName);
824         }
825         if (mCachedUids.containsKey(pkgName)) {
826             return mCachedUids.get(pkgName);
827         }
828 
829         Set<Integer> uids = new ArraySet<>();
830         List<UserInfo> users = mUserManager.getUsers();
831         for (UserInfo user : users) {
832             int userId = user.getUserHandle().getIdentifier();
833             try {
834                 uids.add(mPackageManager.getPackageUidAsUser(pkgName, userId));
835             } catch (NameNotFoundException exception) {
836                 // Didn't find package. Continue looking at other packages
837                 Rlog.e(TAG, "Unable to find uid for package " + pkgName + " and user " + userId);
838             }
839         }
840         mCachedUids.put(pkgName, uids);
841         return uids;
842     }
843 
getPackageUid(@ullable String pkgName)844     private int getPackageUid(@Nullable String pkgName) {
845         int uid = Process.INVALID_UID;
846         try {
847             uid = mPackageManager.getPackageUid(pkgName, /* flags= */0);
848         } catch (NameNotFoundException e) {
849             Rlog.e(TAG, "Unable to find uid for package " + pkgName);
850         }
851         return uid;
852     }
853 
854     /**
855      * Dump the local log buffer and other internal state of CarrierPrivilegesTracker.
856      */
dump(@onNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args)857     public void dump(@NonNull FileDescriptor fd, @NonNull PrintWriter pw, @NonNull String[] args) {
858         pw.println("CarrierPrivilegesTracker - phoneId: " + mPhone.getPhoneId());
859         pw.println("CarrierPrivilegesTracker - Log Begin ----");
860         mLocalLog.dump(fd, pw, args);
861         pw.println("CarrierPrivilegesTracker - Log End ----");
862         mPrivilegedPackageInfoLock.readLock().lock();
863         try {
864             pw.println(
865                     "CarrierPrivilegesTracker - Privileged package info: "
866                             + mPrivilegedPackageInfo);
867             pw.println("mSimIsReadyButNotLoaded: " + mSimIsReadyButNotLoaded);
868         } finally {
869             mPrivilegedPackageInfoLock.readLock().unlock();
870         }
871         pw.println("CarrierPrivilegesTracker - Test-override rules: " + mTestOverrideRules);
872         pw.println("CarrierPrivilegesTracker - SIM-loaded rules: " + mUiccRules);
873         pw.println("CarrierPrivilegesTracker - Carrier config rules: " + mCarrierConfigRules);
874         if (VDBG) {
875             pw.println(
876                     "CarrierPrivilegesTracker - Obfuscated Pkgs + Certs: "
877                             + getObfuscatedPackages(
878                                     mInstalledPackageCerts.entrySet(),
879                                     e -> "pkg(" + Rlog.pii(TAG, e.getKey()) + ")=" + e.getValue()));
880         }
881         pw.println("mClearUiccRulesUptimeMillis: " + mClearUiccRulesUptimeMillis);
882     }
883 
884     /**
885      * Registers the given Registrant with this tracker.
886      *
887      * <p>After being registered, the Registrant will be notified with the current Carrier
888      * Privileged UIDs for this Phone.
889      *
890      * @deprecated Use {@link TelephonyManager#addCarrierPrivilegesListener} instead, which also
891      *     provides package names
892      *     <p>TODO(b/211658797) migrate callers, then delete all Registrant logic from CPT
893      */
894     @Deprecated
registerCarrierPrivilegesListener(@onNull Handler h, int what, @Nullable Object obj)895     public void registerCarrierPrivilegesListener(@NonNull Handler h, int what,
896             @Nullable Object obj) {
897         sendMessage(obtainMessage(ACTION_REGISTER_LISTENER, new Registrant(h, what, obj)));
898     }
899 
900     /**
901      * Unregisters the given listener with this tracker.
902      *
903      * @deprecated Use {@link TelephonyManager#removeCarrierPrivilegesListener} instead
904      *     <p>TODO(b/211658797) migrate callers, then delete all Registrant logic from CPT
905      */
906     @Deprecated
unregisterCarrierPrivilegesListener(@onNull Handler handler)907     public void unregisterCarrierPrivilegesListener(@NonNull Handler handler) {
908         sendMessage(obtainMessage(ACTION_UNREGISTER_LISTENER, handler));
909     }
910 
911     /**
912      * Set test carrier privilege rules which will override the actual rules on both Carrier Config
913      * and SIM.
914      *
915      * <p>{@code carrierPrivilegeRules} can be null, in which case the rules on the Carrier Config
916      * and SIM will be used and any previous overrides will be cleared.
917      *
918      * @see TelephonyManager#setCarrierTestOverride
919      */
setTestOverrideCarrierPrivilegeRules(@ullable String carrierPrivilegeRules)920     public void setTestOverrideCarrierPrivilegeRules(@Nullable String carrierPrivilegeRules) {
921         sendMessage(obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules));
922     }
923 
handleSetTestOverrideRules(@ullable String carrierPrivilegeRules)924     private void handleSetTestOverrideRules(@Nullable String carrierPrivilegeRules) {
925         if (carrierPrivilegeRules == null) {
926             mTestOverrideRules = null;
927         } else if (carrierPrivilegeRules.isEmpty()) {
928             mTestOverrideRules = Collections.emptyList();
929         } else {
930             mTestOverrideRules = Arrays.asList(UiccAccessRule.decodeRulesFromCarrierConfig(
931                     new String[]{carrierPrivilegeRules}));
932             // TODO(b/215239409): remove the additional cache refresh for test override cases.
933             // Test override doesn't respect if the package for the specified cert has been removed
934             // or hidden since initialization. Refresh the cache again to get the pkg/uid with the
935             // best effort.
936             refreshInstalledPackageCache();
937         }
938         maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
939     }
940 
941     /** Backing of {@link TelephonyManager#checkCarrierPrivilegesForPackage}. */
getCarrierPrivilegeStatusForPackage( @ullable String packageName)942     public @CarrierPrivilegeStatus int getCarrierPrivilegeStatusForPackage(
943             @Nullable String packageName) {
944         if (packageName == null) return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
945 
946         // TODO(b/205736323) consider if/how we want to account for the RULES_NOT_LOADED and
947         // ERROR_LOADING_RULES constants. Technically those will never be returned today since those
948         // results are only from the SIM rules, but the CC rules' result (which never has these
949         // errors) always supersede them unless something goes super wrong when getting CC.
950         mPrivilegedPackageInfoLock.readLock().lock();
951         try {
952             if (mSimIsReadyButNotLoaded) {
953                 return CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
954             } else if (mPrivilegedPackageInfo.mPackageNames.contains(packageName)) {
955                 return CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
956             } else {
957                 return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
958             }
959         } finally {
960             mPrivilegedPackageInfoLock.readLock().unlock();
961         }
962     }
963 
964     /** Backing of {@link TelephonyManager#getPackagesWithCarrierPrivileges}. */
965     @NonNull
getPackagesWithCarrierPrivileges()966     public Set<String> getPackagesWithCarrierPrivileges() {
967         mPrivilegedPackageInfoLock.readLock().lock();
968         try {
969             return mSimIsReadyButNotLoaded ? Collections.emptySet() :
970                     Collections.unmodifiableSet(mPrivilegedPackageInfo.mPackageNames);
971         } finally {
972             mPrivilegedPackageInfoLock.readLock().unlock();
973         }
974     }
975 
976     /**
977      * Backing of {@link TelephonyManager#hasCarrierPrivileges} and {@link
978      * TelephonyManager#getCarrierPrivilegeStatus(int)}.
979      */
getCarrierPrivilegeStatusForUid(int uid)980     public @CarrierPrivilegeStatus int getCarrierPrivilegeStatusForUid(int uid) {
981         // TODO(b/205736323) consider if/how we want to account for the RULES_NOT_LOADED and
982         // ERROR_LOADING_RULES constants. Technically those will never be returned today since those
983         // results are only from the SIM rules, but the CC rules' result (which never has these
984         // errors) always supersede them unless something goes super wrong when getting CC.
985         mPrivilegedPackageInfoLock.readLock().lock();
986         try {
987             if (mSimIsReadyButNotLoaded) {
988                 return CARRIER_PRIVILEGE_STATUS_RULES_NOT_LOADED;
989             } else if (mPrivilegedPackageInfo.mUids.contains(uid)) {
990                 return CARRIER_PRIVILEGE_STATUS_HAS_ACCESS;
991             } else {
992                 return CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
993             }
994         } finally {
995             mPrivilegedPackageInfoLock.readLock().unlock();
996         }
997     }
998 
999     /**
1000      * Backing of {@link TelephonyManager#getCarrierServicePackageName()} and
1001      * {@link TelephonyManager#getCarrierServicePackageNameForLogicalSlot(int)}
1002      */
1003     @Nullable
getCarrierServicePackageName()1004     public String getCarrierServicePackageName() {
1005         // Return the cached one if present, it is fast and safe (no IPC call to PackageManager)
1006         mPrivilegedPackageInfoLock.readLock().lock();
1007         try {
1008             // If SIM is READY but not LOADED, neither the cache nor the queries below are reliable,
1009             // we should return null for this transient state for security/privacy's concern.
1010             if (mSimIsReadyButNotLoaded) return null;
1011 
1012             return mPrivilegedPackageInfo.mCarrierService.first;
1013         } finally {
1014             mPrivilegedPackageInfoLock.readLock().unlock();
1015         }
1016         // Do NOT query package manager, mPrivilegedPackageInfo.mCarrierService has maintained the
1017         // latest CarrierService info. Querying PM will not get better result.
1018     }
1019 
1020     /**
1021      * @return The UID of carrier service package. {@link Process#INVALID_UID} if not found.
1022      */
getCarrierServicePackageUid()1023     public int getCarrierServicePackageUid() {
1024         mPrivilegedPackageInfoLock.readLock().lock();
1025         try {
1026             if (mSimIsReadyButNotLoaded) return Process.INVALID_UID;
1027 
1028             return mPrivilegedPackageInfo.mCarrierService.second;
1029         } finally {
1030             mPrivilegedPackageInfoLock.readLock().unlock();
1031         }
1032     }
1033 
1034     /**
1035      * Backing of {@link TelephonyManager#getCarrierPackageNamesForIntent} and {@link
1036      * TelephonyManager#getCarrierPackageNamesForIntentAndPhone}.
1037      */
1038     @NonNull
getCarrierPackageNamesForIntent(@onNull Intent intent)1039     public List<String> getCarrierPackageNamesForIntent(@NonNull Intent intent) {
1040         mPrivilegedPackageInfoLock.readLock().lock();
1041         try {
1042             if (mSimIsReadyButNotLoaded) return Collections.emptyList();
1043         } finally {
1044             mPrivilegedPackageInfoLock.readLock().unlock();
1045         }
1046 
1047         // Do the PackageManager queries before we take the lock, as these are the longest-running
1048         // pieces of this method and don't depend on the set of carrier apps.
1049         List<ResolveInfo> resolveInfos = new ArrayList<>();
1050         resolveInfos.addAll(mPackageManager.queryBroadcastReceivers(intent, 0));
1051         resolveInfos.addAll(mPackageManager.queryIntentActivities(intent, 0));
1052         resolveInfos.addAll(mPackageManager.queryIntentServices(intent, 0));
1053         resolveInfos.addAll(mPackageManager.queryIntentContentProviders(intent, 0));
1054 
1055         // Now actually check which of the resolved packages have carrier privileges.
1056         mPrivilegedPackageInfoLock.readLock().lock();
1057         try {
1058             // Check mSimIsReadyButNotLoaded again here since the PackageManager queries above are
1059             // pretty time-consuming, mSimIsReadyButNotLoaded state may change since last check
1060             if (mSimIsReadyButNotLoaded) return Collections.emptyList();
1061 
1062             Set<String> packageNames = new ArraySet<>(); // For deduping purposes
1063             for (ResolveInfo resolveInfo : resolveInfos) {
1064                 String packageName = getPackageName(resolveInfo);
1065                 if (packageName != null && CARRIER_PRIVILEGE_STATUS_HAS_ACCESS
1066                         == getCarrierPrivilegeStatusForPackage(packageName)) {
1067                     packageNames.add(packageName);
1068                 }
1069             }
1070             return new ArrayList<>(packageNames);
1071         } finally {
1072             mPrivilegedPackageInfoLock.readLock().unlock();
1073         }
1074     }
1075 
1076     @Nullable
getPackageName(@onNull ResolveInfo resolveInfo)1077     private static String getPackageName(@NonNull ResolveInfo resolveInfo) {
1078         // Note: activityInfo covers both activities + broadcast receivers
1079         if (resolveInfo.activityInfo != null) return resolveInfo.activityInfo.packageName;
1080         if (resolveInfo.serviceInfo != null) return resolveInfo.serviceInfo.packageName;
1081         if (resolveInfo.providerInfo != null) return resolveInfo.providerInfo.packageName;
1082         return null;
1083     }
1084 
1085     @NonNull
getCarrierService(@onNull Set<String> simPrivilegedPackages)1086     private Pair<String, Integer> getCarrierService(@NonNull Set<String> simPrivilegedPackages) {
1087         List<ResolveInfo> carrierServiceResolveInfos = mPackageManager.queryIntentServices(
1088                 new Intent(CarrierService.CARRIER_SERVICE_INTERFACE), /* flags= */ 0);
1089         String carrierServicePackageName = null;
1090         for (ResolveInfo resolveInfo : carrierServiceResolveInfos) {
1091             String packageName = getPackageName(resolveInfo);
1092             if (simPrivilegedPackages.contains(packageName)) {
1093                 carrierServicePackageName = packageName;
1094                 break;
1095             }
1096         }
1097         return carrierServicePackageName == null
1098                 ? new Pair<>(null, Process.INVALID_UID)
1099                 : new Pair<>(carrierServicePackageName, getPackageUid(carrierServicePackageName));
1100     }
1101 
1102     @NonNull
intSetToArray(@onNull Set<Integer> intSet)1103     private static int[] intSetToArray(@NonNull Set<Integer> intSet) {
1104         IntArray converter = new IntArray(intSet.size());
1105         intSet.forEach(converter::add);
1106         return converter.toArray();
1107     }
1108 }
1109