Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a0364b05 authored by Hunter Knepshield's avatar Hunter Knepshield Committed by Automerger Merge Worker
Browse files

Merge "Migrate CarrierPrivilegesTracker to UiccAccessRule." am: a7719379 am:...

Merge "Migrate CarrierPrivilegesTracker to UiccAccessRule." am: a7719379 am: 702cf5b3 am: 68830343

Original change: https://android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/1612005

Change-Id: I0b160eb7c859c98fdf33dc08e70512432736a91f
parents f7723142 68830343
Loading
Loading
Loading
Loading
+67 −61
Original line number Original line Diff line number Diff line
@@ -58,6 +58,8 @@ import android.util.IntArray;
import android.util.LocalLog;
import android.util.LocalLog;


import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.telephony.uicc.UiccCard;
import com.android.internal.telephony.uicc.UiccProfile;
import com.android.telephony.Rlog;
import com.android.telephony.Rlog;


import java.io.FileDescriptor;
import java.io.FileDescriptor;
@@ -135,11 +137,11 @@ public class CarrierPrivilegesTracker extends Handler {
    private final RegistrantList mRegistrantList;
    private final RegistrantList mRegistrantList;
    private final LocalLog mLocalLog;
    private final LocalLog mLocalLog;


    // Stores rules for Carrier Config-loaded certs
    // Stores rules for Carrier Config-loaded rules
    private final List<UiccAccessRule> mCarrierConfigCerts;
    private final List<UiccAccessRule> mCarrierConfigRules;


    // TODO(b/151981841): Use Set<UiccAccessRule> to also check for package names loaded from SIM
    // Stores rules for SIM-loaded rules.
    private final Set<String> mUiccCerts;
    private final List<UiccAccessRule> mUiccRules;


    // Map of PackageName -> Certificate hashes for that Package
    // Map of PackageName -> Certificate hashes for that Package
    private final Map<String, Set<String>> mInstalledPackageCerts;
    private final Map<String, Set<String>> mInstalledPackageCerts;
@@ -235,8 +237,8 @@ public class CarrierPrivilegesTracker extends Handler {
        mContext.registerReceiver(mIntentReceiver, packageFilter);
        mContext.registerReceiver(mIntentReceiver, packageFilter);


        mRegistrantList = new RegistrantList();
        mRegistrantList = new RegistrantList();
        mCarrierConfigCerts = new ArrayList<>();
        mCarrierConfigRules = new ArrayList<>();
        mUiccCerts = new ArraySet<>();
        mUiccRules = new ArrayList<>();
        mInstalledPackageCerts = new ArrayMap<>();
        mInstalledPackageCerts = new ArrayMap<>();
        mCachedUids = new ArrayMap<>();
        mCachedUids = new ArrayMap<>();
        mPrivilegedUids = new int[0];
        mPrivilegedUids = new int[0];
@@ -298,67 +300,72 @@ public class CarrierPrivilegesTracker extends Handler {
    private void handleCarrierConfigUpdated(int subId, int slotIndex) {
    private void handleCarrierConfigUpdated(int subId, int slotIndex) {
        if (slotIndex != mPhone.getPhoneId()) return;
        if (slotIndex != mPhone.getPhoneId()) return;


        List<UiccAccessRule> updatedCarrierConfigCerts = Collections.EMPTY_LIST;
        List<UiccAccessRule> updatedCarrierConfigRules = Collections.EMPTY_LIST;


        // Carrier Config broadcasts with INVALID_SUBSCRIPTION_ID when the SIM is removed. This is
        // Carrier Config broadcasts with INVALID_SUBSCRIPTION_ID when the SIM is removed. This is
        // an expected event. When this happens, clear the certificates from the previous configs.
        // an expected event. When this happens, clear the certificates from the previous configs.
        // The certs will be cleared in maybeUpdateCertsAndNotifyRegistrants() below.
        // The rules will be cleared in maybeUpdateRulesAndNotifyRegistrants() below.
        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            updatedCarrierConfigCerts = getCarrierConfigCerts(subId);
            updatedCarrierConfigRules = getCarrierConfigRules(subId);
        }
        }


        mLocalLog.log("CarrierConfigUpdated:"
        mLocalLog.log("CarrierConfigUpdated:"
                + " subId=" + subId
                + " subId=" + subId
                + " slotIndex=" + slotIndex
                + " slotIndex=" + slotIndex
                + " updated CarrierConfig certs=" + updatedCarrierConfigCerts);
                + " updated CarrierConfig rules=" + updatedCarrierConfigRules);
        maybeUpdateCertsAndNotifyRegistrants(mCarrierConfigCerts, updatedCarrierConfigCerts);
        maybeUpdateRulesAndNotifyRegistrants(mCarrierConfigRules, updatedCarrierConfigRules);
    }
    }


    private List<UiccAccessRule> getCarrierConfigCerts(int subId) {
    private List<UiccAccessRule> getCarrierConfigRules(int subId) {
        PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
        PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
        if (!mCarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) {
        if (!mCarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) {
            return Collections.EMPTY_LIST;
            return Collections.EMPTY_LIST;
        }
        }


        String[] carrierConfigCerts =
        String[] carrierConfigRules =
                carrierConfigs.getStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
                carrierConfigs.getStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY);
        if (carrierConfigCerts == null) {
        if (carrierConfigRules == null) {
            return Collections.EMPTY_LIST;
            return Collections.EMPTY_LIST;
        }
        }
        return Arrays.asList(UiccAccessRule.decodeRulesFromCarrierConfig(carrierConfigCerts));
        return Arrays.asList(UiccAccessRule.decodeRulesFromCarrierConfig(carrierConfigRules));
    }
    }


    private void handleSimStateChanged(int slotId, int simState) {
    private void handleSimStateChanged(int slotId, int simState) {
        if (slotId != mPhone.getPhoneId()) return;
        if (slotId != mPhone.getPhoneId()) return;


        Set<String> updatedUiccCerts = Collections.EMPTY_SET;
        List<UiccAccessRule> updatedUiccRules = Collections.EMPTY_LIST;


        // Only include the UICC certs if the SIM is fully loaded
        // Only include the UICC rules if the SIM is fully loaded
        if (simState == SIM_STATE_LOADED) {
        if (simState == SIM_STATE_LOADED) {
            updatedUiccCerts = getSimCerts();
            updatedUiccRules = getSimRules();
        }
        }


        mLocalLog.log("SIM State Changed:"
        mLocalLog.log("SIM State Changed:"
                + " slotId=" + slotId
                + " slotId=" + slotId
                + " simState=" + simState
                + " simState=" + simState
                + " updated SIM-loaded certs=" + updatedUiccCerts);
                + " updated SIM-loaded rules=" + updatedUiccRules);
        maybeUpdateCertsAndNotifyRegistrants(mUiccCerts, updatedUiccCerts);
        maybeUpdateRulesAndNotifyRegistrants(mUiccRules, updatedUiccRules);
    }
    }


    private Set<String> getSimCerts() {
    private List<UiccAccessRule> getSimRules() {
        Set<String> updatedUiccCerts = Collections.EMPTY_SET;
        if (!mTelephonyManager.hasIccCard(mPhone.getPhoneId())) {
        TelephonyManager telMan = mTelephonyManager.createForSubscriptionId(mPhone.getSubId());
            return Collections.EMPTY_LIST;

        if (telMan.hasIccCard(mPhone.getPhoneId())) {
            updatedUiccCerts = new ArraySet<>();
            List<String> uiccCerts = telMan.getCertsFromCarrierPrivilegeAccessRules();
            if (uiccCerts != null) {
                for (String cert : uiccCerts) {
                    updatedUiccCerts.add(cert.toUpperCase());
        }
        }
        UiccCard uiccCard = mPhone.getUiccCard();
        if (uiccCard == null) {
            Rlog.w(
                    TAG,
                    "Null UiccCard, but hasIccCard was true for phoneId " + mPhone.getPhoneId());
            return Collections.EMPTY_LIST;
        }
        }
        UiccProfile uiccProfile = uiccCard.getUiccProfile();
        if (uiccProfile == null) {
            Rlog.w(
                    TAG,
                    "Null UiccProfile, but hasIccCard was true for phoneId " + mPhone.getPhoneId());
            return Collections.EMPTY_LIST;
        }
        }
        return updatedUiccCerts;
        return uiccProfile.getCarrierPrivilegeAccessRules();
    }
    }


    private void handlePackageAddedOrReplaced(String pkgName) {
    private void handlePackageAddedOrReplaced(String pkgName) {
@@ -406,11 +413,11 @@ public class CarrierPrivilegesTracker extends Handler {
    }
    }


    private void handleInitializeTracker() {
    private void handleInitializeTracker() {
        // Cache CarrierConfig Certs
        // Cache CarrierConfig rules
        mCarrierConfigCerts.addAll(getCarrierConfigCerts(mPhone.getSubId()));
        mCarrierConfigRules.addAll(getCarrierConfigRules(mPhone.getSubId()));


        // Cache SIM certs
        // Cache SIM rules
        mUiccCerts.addAll(getSimCerts());
        mUiccRules.addAll(getSimRules());


        // Cache all installed packages and their certs
        // Cache all installed packages and their certs
        int flags =
        int flags =
@@ -428,8 +435,8 @@ public class CarrierPrivilegesTracker extends Handler {
        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
        maybeUpdatePrivilegedUidsAndNotifyRegistrants();


        String msg = "Initializing state:"
        String msg = "Initializing state:"
                + " CarrierConfig certs=" + mCarrierConfigCerts
                + " CarrierConfig rules=" + mCarrierConfigRules
                + " SIM-loaded certs=" + mUiccCerts;
                + " SIM-loaded rules=" + mUiccRules;
        if (VDBG) {
        if (VDBG) {
            msg += " installed pkgs=" + getObfuscatedPackages();
            msg += " installed pkgs=" + getObfuscatedPackages();
        }
        }
@@ -444,22 +451,12 @@ public class CarrierPrivilegesTracker extends Handler {
        return obfuscatedPkgs.toString();
        return obfuscatedPkgs.toString();
    }
    }


    private void maybeUpdateCertsAndNotifyRegistrants(
    private void maybeUpdateRulesAndNotifyRegistrants(
            Set<String> currentCerts, Set<String> updatedCerts) {
            List<UiccAccessRule> currentRules, List<UiccAccessRule> updatedRules) {
        if (currentCerts.equals(updatedCerts)) return;
        if (currentRules.equals(updatedRules)) return;

        currentCerts.clear();
        currentCerts.addAll(updatedCerts);

        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
    }

    private void maybeUpdateCertsAndNotifyRegistrants(
            List<UiccAccessRule> currentCerts, List<UiccAccessRule> updatedCerts) {
        if (currentCerts.equals(updatedCerts)) return;


        currentCerts.clear();
        currentRules.clear();
        currentCerts.addAll(updatedCerts);
        currentRules.addAll(updatedRules);


        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
    }
    }
@@ -494,16 +491,25 @@ public class CarrierPrivilegesTracker extends Handler {


    /**
    /**
     * Returns true iff there is an overlap between the provided certificate hashes and the
     * Returns true iff there is an overlap between the provided certificate hashes and the
     * certificate hashes stored in mCarrierConfigCerts and mUiccCerts.
     * certificate hashes stored in mCarrierConfigRules and mUiccRules.
     */
     */
    private boolean isPackagePrivileged(String pkgName, Set<String> certs) {
    private boolean isPackagePrivileged(String pkgName, Set<String> certs) {
        // Double-nested for loops, but each collection should contain at most 2 elements in nearly
        // every case.
        // TODO(b/184382310) find a way to speed this up
        for (String cert : certs) {
        for (String cert : certs) {
            if (mCarrierConfigCerts.stream().anyMatch(rule -> rule.matches(cert, pkgName))) {
            for (UiccAccessRule rule : mCarrierConfigRules) {
                if (rule.matches(cert, pkgName)) {
                    return true;
                    return true;
                }
                }
            }
            }

            for (UiccAccessRule rule : mUiccRules) {
        return !Collections.disjoint(mUiccCerts, certs);
                if (rule.matches(cert, pkgName)) {
                    return true;
                }
            }
        }
        return false;
    }
    }


    private Set<Integer> getUidsForPackage(String pkgName) {
    private Set<Integer> getUidsForPackage(String pkgName) {
@@ -536,8 +542,8 @@ public class CarrierPrivilegesTracker extends Handler {
        pw.println("CarrierPrivilegesTracker - Log End ----");
        pw.println("CarrierPrivilegesTracker - Log End ----");
        pw.println("CarrierPrivilegesTracker - Privileged UIDs: "
        pw.println("CarrierPrivilegesTracker - Privileged UIDs: "
                + Arrays.toString(mPrivilegedUids));
                + Arrays.toString(mPrivilegedUids));
        pw.println("CarrierPrivilegesTracker - SIM-loaded Certs: " + mUiccCerts);
        pw.println("CarrierPrivilegesTracker - SIM-loaded rules: " + mUiccRules);
        pw.println("CarrierPrivilegesTracker - CarrierPrivileged Certs: " + mCarrierConfigCerts);
        pw.println("CarrierPrivilegesTracker - Carrier config rules: " + mCarrierConfigRules);
        if (VDBG) {
        if (VDBG) {
            pw.println("CarrierPrivilegesTracker - Obfuscated Pkgs + Certs: "
            pw.println("CarrierPrivilegesTracker - Obfuscated Pkgs + Certs: "
                    + getObfuscatedPackages());
                    + getObfuscatedPackages());
+4 −4
Original line number Original line Diff line number Diff line
@@ -150,7 +150,8 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";
    public static final String DATA_DISABLED_ON_BOOT_KEY = "disabled_on_boot_key";


    // Key used to read/write data_roaming_is_user_setting pref
    // Key used to read/write data_roaming_is_user_setting pref
    public static final String DATA_ROAMING_IS_USER_SETTING_KEY = "data_roaming_is_user_setting_key";
    public static final String DATA_ROAMING_IS_USER_SETTING_KEY =
            "data_roaming_is_user_setting_key";


    // Default value when there has been no last emergency SMS time recorded yet.
    // Default value when there has been no last emergency SMS time recorded yet.
    private static final int EMERGENCY_SMS_NO_TIME_RECORDED = -1;
    private static final int EMERGENCY_SMS_NO_TIME_RECORDED = -1;
@@ -453,7 +454,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
    protected boolean mIsCarrierNrSupported = false;
    protected boolean mIsCarrierNrSupported = false;


    private boolean mUnitTestMode;
    private boolean mUnitTestMode;
    private final CarrierPrivilegesTracker mCarrierPrivilegesTracker;
    private CarrierPrivilegesTracker mCarrierPrivilegesTracker = null;


    protected VoiceCallSessionStats mVoiceCallSessionStats;
    protected VoiceCallSessionStats mVoiceCallSessionStats;
    protected SmsStats mSmsStats;
    protected SmsStats mSmsStats;
@@ -581,8 +582,6 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
        mIsVoiceCapable = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
        mIsVoiceCapable = ((TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE))
                .isVoiceCapable();
                .isVoiceCapable();


        mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(mLooper, this, mContext);

        /**
        /**
         *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
         *  Some RIL's don't always send RIL_UNSOL_CALL_RING so it needs
         *  to be generated locally. Ideally all ring tones should be loops
         *  to be generated locally. Ideally all ring tones should be loops
@@ -618,6 +617,7 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
        mSimActivationTracker = mTelephonyComponentFactory
        mSimActivationTracker = mTelephonyComponentFactory
                .inject(SimActivationTracker.class.getName())
                .inject(SimActivationTracker.class.getName())
                .makeSimActivationTracker(this);
                .makeSimActivationTracker(this);
        mCarrierPrivilegesTracker = new CarrierPrivilegesTracker(mLooper, this, mContext);
        if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) {
        if (getPhoneType() != PhoneConstants.PHONE_TYPE_SIP) {
            mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
            mCi.registerForSrvccStateChanged(this, EVENT_SRVCC_STATE_CHANGED, null);
        }
        }
+9 −0
Original line number Original line Diff line number Diff line
@@ -1733,6 +1733,15 @@ public class UiccProfile extends IccCard {
        return certs.isEmpty() ? null : certs;
        return certs.isEmpty() ? null : certs;
    }
    }


    /** @return a list of {@link UiccAccessRule}s, or an empty list if none have been loaded yet. */
    public List<UiccAccessRule> getCarrierPrivilegeAccessRules() {
        UiccCarrierPrivilegeRules carrierPrivilegeRules = getCarrierPrivilegeRules();
        if (carrierPrivilegeRules == null) {
            return Collections.EMPTY_LIST;
        }
        return new ArrayList<>(carrierPrivilegeRules.getAccessRules());
    }

    /**
    /**
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
     */
     */
+105 −33
Original line number Original line Diff line number Diff line
@@ -46,6 +46,7 @@ import android.os.Message;
import android.os.PersistableBundle;
import android.os.PersistableBundle;
import android.telephony.CarrierConfigManager;
import android.telephony.CarrierConfigManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.telephony.UiccAccessRule;
import android.testing.AndroidTestingRunner;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper;
import android.util.ArraySet;
import android.util.ArraySet;
@@ -114,8 +115,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        mHandler = new CarrierPrivilegesTrackerTestHandler();
        mHandler = new CarrierPrivilegesTrackerTestHandler();


        // set mock behavior so CarrierPrivilegeTracker initializes with no privileged UIDs
        // set mock behavior so CarrierPrivilegeTracker initializes with no privileged UIDs
        setupCarrierConfigCerts();
        setupCarrierConfigRules();
        setupSimLoadedCerts();
        setupSimLoadedRules();
        setupInstalledPackages();
        setupInstalledPackages();
    }
    }


@@ -124,16 +125,33 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        super.tearDown();
        super.tearDown();
    }
    }


    private void setupCarrierConfigCerts(String... certHashes) {
    /** @param rules can either be "hash" or "hash:package[,package...]" */
        mCarrierConfigs.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, certHashes);
    private void setupCarrierConfigRules(String... rules) {
        mCarrierConfigs.putStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY, rules);
        mCarrierConfigs.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
        mCarrierConfigs.putBoolean(KEY_CARRIER_CONFIG_APPLIED_BOOL, true);
        when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfigs);
        when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfigs);
    }
    }


    private void setupSimLoadedCerts(String... certHashes) {
    private static String carrierConfigRuleString(String certificateHash, String... packageNames) {
        if (packageNames == null || packageNames.length == 0) {
            return certificateHash;
        }
        return certificateHash + ':' + String.join(",", packageNames);
    }

    private void setupSimLoadedRules(UiccAccessRule... certHashes) {
        when(mTelephonyManager.hasIccCard(PHONE_ID)).thenReturn(true);
        when(mTelephonyManager.hasIccCard(PHONE_ID)).thenReturn(true);
        when(mTelephonyManager.getCertsFromCarrierPrivilegeAccessRules())
        when(mUiccProfile.getCarrierPrivilegeAccessRules()).thenReturn(Arrays.asList(certHashes));
                .thenReturn(Arrays.asList(certHashes));
    }

    private static UiccAccessRule ruleWithHashOnly(String certificateHash) {
        return ruleWithHashAndPackage(certificateHash, null /* packageName */);
    }

    private static UiccAccessRule ruleWithHashAndPackage(
            String certificateHash, String packageName) {
        return new UiccAccessRule(
                IccUtils.hexStringToBytes(certificateHash), packageName, /* accessType= */ 0L);
    }
    }


    private void setupInstalledPackages(PackageCertInfo... pkgCertInfos) throws Exception {
    private void setupInstalledPackages(PackageCertInfo... pkgCertInfos) throws Exception {
@@ -165,7 +183,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
     * <p>The initial configuration of the CarrierPrivilegesTracker will be based on the current
     * <p>The initial configuration of the CarrierPrivilegesTracker will be based on the current
     * state of certificate hashes and installed packages.
     * state of certificate hashes and installed packages.
     *
     *
     * See #setupCarrierConfigCerts, #setupSimLoadedCerts, #setupInstalledPackages.
     * <p>See {@link #setupCarrierConfigRules}, {@link #setupSimLoadedRules}, {@link
     * #setupInstalledPackages}.
     */
     */
    private CarrierPrivilegesTracker createCarrierPrivilegesTracker() throws Exception {
    private CarrierPrivilegesTracker createCarrierPrivilegesTracker() throws Exception {
        CarrierPrivilegesTracker cpt =
        CarrierPrivilegesTracker cpt =
@@ -180,7 +199,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
    }
    }


    private void setupCarrierPrivilegesTrackerWithCarrierConfigUids() throws Exception {
    private void setupCarrierPrivilegesTrackerWithCarrierConfigUids() throws Exception {
        setupCarrierConfigCerts(getHash(CERT_1), getHash(CERT_2));
        setupCarrierConfigRules(
                carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
        setupInstalledPackages(
        setupInstalledPackages(
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
@@ -188,7 +208,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
    }
    }


    private void setupCarrierPrivilegesTrackerWithSimLoadedUids() throws Exception {
    private void setupCarrierPrivilegesTrackerWithSimLoadedUids() throws Exception {
        setupSimLoadedCerts(getHash(CERT_1), getHash(CERT_2));
        setupSimLoadedRules(ruleWithHashOnly(getHash(CERT_1)), ruleWithHashOnly(getHash(CERT_2)));
        setupInstalledPackages(
        setupInstalledPackages(
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
@@ -202,17 +222,15 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        @Override
        @Override
        public void handleMessage(Message msg) {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            switch (msg.what) {
                case REGISTRANT_WHAT: {
                case REGISTRANT_WHAT:
                    AsyncResult asyncResult = (AsyncResult) msg.obj;
                    AsyncResult asyncResult = (AsyncResult) msg.obj;
                    privilegedUids = (int[]) asyncResult.result;
                    privilegedUids = (int[]) asyncResult.result;
                    numUidUpdates++;
                    numUidUpdates++;
                    break;
                    break;
                }
                default:
                default: {
                    fail("Unexpected msg received. what=" + msg.what);
                    fail("Unexpected msg received. what=" + msg.what);
            }
            }
        }
        }
        }


        void reset() {
        void reset() {
            privilegedUids = null;
            privilegedUids = null;
@@ -271,10 +289,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
        mCarrierConfigs.putStringArray(
        setupCarrierConfigRules(
                KEY_CARRIER_CERTIFICATE_STRING_ARRAY,
                carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
                new String[] {getHash(CERT_1), getHash(CERT_2)});
        when(mCarrierConfigManager.getConfigForSubId(SUB_ID)).thenReturn(mCarrierConfigs);


        sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
        sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
        mTestableLooper.processAllMessages();
        mTestableLooper.processAllMessages();
@@ -318,6 +334,34 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        verifyPrivilegedUids(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
        verifyPrivilegedUids(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
    }
    }


    @Test
    public void testCarrierConfigUpdatedExplicitPackageNames() throws Exception {
        // Start with privileges specified just by wildcard certificate hashes, verify specifying
        // package names clears privileges on UIDs that don't match the updated rules.
        setupCarrierPrivilegesTrackerWithCarrierConfigUids();

        // Package 1 keeps its privileges by matching the first rule; the second rule no longer
        // matches package 2.
        setupCarrierConfigRules(
                carrierConfigRuleString(getHash(CERT_1), PACKAGE_1),
                carrierConfigRuleString(getHash(CERT_2), PACKAGE_1));

        sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
        mTestableLooper.processAllMessages();

        verifyPrivilegedUids(new int[] {UID_1} /* expectedUids */, 1 /* expectedUidUpdates */);

        // Give package 2 privileges again.
        setupCarrierConfigRules(
                carrierConfigRuleString(getHash(CERT_1), PACKAGE_1),
                carrierConfigRuleString(getHash(CERT_2), PACKAGE_1, PACKAGE_2));

        sendCarrierConfigChangedIntent(SUB_ID, PHONE_ID);
        mTestableLooper.processAllMessages();

        verifyPrivilegedUids(PRIVILEGED_UIDS /* expectedUids */, 2 /* expectedUidUpdates */);
    }

    @Test
    @Test
    public void testSimCardStateChanged() throws Exception {
    public void testSimCardStateChanged() throws Exception {
        // Start with packages installed and no certs
        // Start with packages installed and no certs
@@ -326,9 +370,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();


        when(mTelephonyManager.getCertsFromCarrierPrivilegeAccessRules())
        setupSimLoadedRules(ruleWithHashOnly(getHash(CERT_1)), ruleWithHashOnly(getHash(CERT_2)));
                .thenReturn(Arrays.asList(getHash(CERT_1), getHash(CERT_2)));
        when(mTelephonyManager.hasIccCard(PHONE_ID)).thenReturn(true);


        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
        mTestableLooper.processAllMessages();
        mTestableLooper.processAllMessages();
@@ -344,9 +386,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();


        when(mTelephonyManager.getCertsFromCarrierPrivilegeAccessRules())
        setupSimLoadedRules(ruleWithHashOnly(getHash(CERT_1)), ruleWithHashOnly(getHash(CERT_2)));
                .thenReturn(Arrays.asList(getHash(CERT_1), getHash(CERT_2)));
        when(mTelephonyManager.hasIccCard(PHONE_ID)).thenReturn(true);


        sendSimApplicationStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
        sendSimApplicationStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
        mTestableLooper.processAllMessages();
        mTestableLooper.processAllMessages();
@@ -391,10 +431,39 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        verifyPrivilegedUids(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
        verifyPrivilegedUids(new int[0] /* expectedUids */, 1 /* expectedUidUpdates */);
    }
    }


    @Test
    public void testSimStateChangedExplicitPackageNames() throws Exception {
        // Start with privileges specified just by wildcard certificate hashes, verify specifying
        // package names clears privileges on UIDs that don't match the updated rules.
        setupCarrierPrivilegesTrackerWithSimLoadedUids();

        // Package 1 keeps its privileges by matching the first rule; the second rule no longer
        // matches package 2.
        setupSimLoadedRules(
                ruleWithHashAndPackage(getHash(CERT_1), PACKAGE_1),
                ruleWithHashAndPackage(getHash(CERT_2), PACKAGE_1));

        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
        mTestableLooper.processAllMessages();

        verifyPrivilegedUids(new int[] {UID_1} /* expectedUids */, 1 /* expectedUidUpdates */);

        // Give package 2 privileges again.
        setupSimLoadedRules(
                ruleWithHashAndPackage(getHash(CERT_1), PACKAGE_1),
                ruleWithHashAndPackage(getHash(CERT_2), PACKAGE_1),
                ruleWithHashAndPackage(getHash(CERT_2), PACKAGE_2));

        sendSimCardStateChangedIntent(PHONE_ID, SIM_STATE_LOADED);
        mTestableLooper.processAllMessages();

        verifyPrivilegedUids(PRIVILEGED_UIDS /* expectedUids */, 2 /* expectedUidUpdates */);
    }

    @Test
    @Test
    public void testPackageAdded() throws Exception {
    public void testPackageAdded() throws Exception {
        // Start with certs and no packages installed
        // Start with certs and no packages installed
        setupCarrierConfigCerts(getHash(CERT_1));
        setupCarrierConfigRules(carrierConfigRuleString(getHash(CERT_1)));
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();


        setupInstalledPackages(new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1));
        setupInstalledPackages(new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1));
@@ -408,7 +477,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
    @Test
    @Test
    public void testPackageAddedMultipleUsers() throws Exception {
    public void testPackageAddedMultipleUsers() throws Exception {
        // Start with certs and no packages installed
        // Start with certs and no packages installed
        setupCarrierConfigCerts(getHash(CERT_1), getHash(CERT_2));
        setupCarrierConfigRules(
                carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();


        setupInstalledPackages(
        setupInstalledPackages(
@@ -424,7 +494,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
    @Test
    @Test
    public void testPackageReplaced() throws Exception {
    public void testPackageReplaced() throws Exception {
        // Start with certs and an unmatched package
        // Start with certs and an unmatched package
        setupCarrierConfigCerts(getHash(CERT_1), getHash(CERT_2));
        setupCarrierConfigRules(
                carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
        setupInstalledPackages(new PackageCertInfo(PACKAGE_1, CERT_3, USER_1, UID_1));
        setupInstalledPackages(new PackageCertInfo(PACKAGE_1, CERT_3, USER_1, UID_1));
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();


@@ -441,7 +512,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
    @Test
    @Test
    public void testPackageAddedOrReplacedNoSignatures() throws Exception {
    public void testPackageAddedOrReplacedNoSignatures() throws Exception {
        // Start with certs and packages installed
        // Start with certs and packages installed
        setupCarrierConfigCerts(getHash(CERT_1), getHash(CERT_2));
        setupCarrierConfigRules(
                carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
        setupInstalledPackages(
        setupInstalledPackages(
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
@@ -462,7 +534,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
    @Test
    @Test
    public void testPackageAddedOrReplacedSignatureChanged() throws Exception {
    public void testPackageAddedOrReplacedSignatureChanged() throws Exception {
        // Start with certs and packages installed
        // Start with certs and packages installed
        setupCarrierConfigCerts(getHash(CERT_1), getHash(CERT_2));
        setupCarrierConfigRules(
                carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
        setupInstalledPackages(
        setupInstalledPackages(
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
@@ -482,7 +555,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
    @Test
    @Test
    public void testPackageRemoved() throws Exception {
    public void testPackageRemoved() throws Exception {
        // Start with certs and packages installed
        // Start with certs and packages installed
        setupCarrierConfigCerts(getHash(CERT_1), getHash(CERT_2));
        setupCarrierConfigRules(
                carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
        setupInstalledPackages(
        setupInstalledPackages(
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
@@ -531,9 +605,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        mContext.sendBroadcast(new Intent(action, new Uri.Builder().path(pkgName).build()));
        mContext.sendBroadcast(new Intent(action, new Uri.Builder().path(pkgName).build()));
    }
    }


    /**
    /** Returns the SHA-1 hash (as a hex String) for the given hex String. */
     * Returns the SHA-1 hash (as a hex String) for the given hex String.
     */
    private static String getHash(String hexString) throws Exception {
    private static String getHash(String hexString) throws Exception {
        MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
        MessageDigest sha1 = MessageDigest.getInstance(SHA_1);
        byte[] result = sha1.digest(IccUtils.hexStringToBytes(hexString));
        byte[] result = sha1.digest(IccUtils.hexStringToBytes(hexString));