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

Commit a7719379 authored by Hunter Knepshield's avatar Hunter Knepshield Committed by Gerrit Code Review
Browse files

Merge "Migrate CarrierPrivilegesTracker to UiccAccessRule."

parents 9cc70d6f 2fde259f
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
@@ -149,7 +149,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;
@@ -451,7 +452,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;
@@ -577,8 +578,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
@@ -614,6 +613,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));