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