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

Commit a0ac05da authored by Rambo Wang's avatar Rambo Wang Committed by Gerrit Code Review
Browse files

Merge "Support test override carrier privilege in CarrierPrivilegeTracker"

parents 7586273c 97ee3184
Loading
Loading
Loading
Loading
+83 −21
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import static android.telephony.TelephonyManager.SIM_STATE_NOT_READY;
import static android.telephony.TelephonyManager.SIM_STATE_UNKNOWN;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -134,6 +135,12 @@ public class CarrierPrivilegesTracker extends Handler {
     */
    private static final int ACTION_INITIALIZE_TRACKER = 7;

    /**
     * Action to set the test override rule through {@link TelephonyManager#setCarrierTestOverride}.
     * obj: String of the carrierPrivilegeRules from method setCarrierTestOverride.
     */
    private static final int ACTION_SET_TEST_OVERRIDE_RULE = 8;

    private final Context mContext;
    private final Phone mPhone;
    private final PackageManager mPackageManager;
@@ -148,6 +155,11 @@ public class CarrierPrivilegesTracker extends Handler {
    private final List<UiccAccessRule> mCarrierConfigRules = new ArrayList<>();
    // Stores rules for SIM-loaded rules.
    private final List<UiccAccessRule> mUiccRules = new ArrayList<>();
    // Stores rule from test override (through TelephonyManager#setCarrierTestOverride).
    // - Null list indicates no test override (CC and UICC rules are respected)
    // - Empty list indicates test override to simulate no rules (CC and UICC rules are ignored)
    // - Non-empty list indicates test override with specific rules (CC and UICC rules are ignored)
    @Nullable private List<UiccAccessRule> mTestOverrideRules = null;
    // Map of PackageName -> Certificate hashes for that Package
    private final Map<String, Set<String>> mInstalledPackageCerts = new ArrayMap<>();
    // Map of PackageName -> UIDs for that Package
@@ -328,6 +340,11 @@ public class CarrierPrivilegesTracker extends Handler {
                handleInitializeTracker();
                break;
            }
            case ACTION_SET_TEST_OVERRIDE_RULE: {
                String carrierPrivilegeRules = (String) msg.obj;
                handleSetTestOverrideRules(carrierPrivilegeRules);
                break;
            }
            default: {
                Rlog.e(TAG, "Received unknown msg type: " + msg.what);
                break;
@@ -478,19 +495,7 @@ public class CarrierPrivilegesTracker extends Handler {
        mUiccRules.addAll(getSimRules());

        // Cache all installed packages and their certs
        int flags =
                PackageManager.MATCH_DISABLED_COMPONENTS
                        | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
                        | PackageManager.GET_SIGNING_CERTIFICATES;
        List<PackageInfo> installedPackages =
                mPackageManager.getInstalledPackagesAsUser(
                        flags, UserHandle.SYSTEM.getIdentifier());
        for (PackageInfo pkg : installedPackages) {
            updateCertsForPackage(pkg);
            // We shouldn't have any events coming in before initialization, but invalidate the
            // cache just in case to ensure consistency.
            getUidsForPackage(pkg.packageName, /* invalidateCache= */ true);
        }
        refreshInstalledPackageCache();

        // Okay because no registrants exist yet
        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
@@ -508,6 +513,22 @@ public class CarrierPrivilegesTracker extends Handler {
        mLocalLog.log(msg);
    }

    private void refreshInstalledPackageCache() {
        int flags =
                PackageManager.MATCH_DISABLED_COMPONENTS
                        | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
                        | PackageManager.GET_SIGNING_CERTIFICATES;
        List<PackageInfo> installedPackages =
                mPackageManager.getInstalledPackagesAsUser(
                        flags, UserHandle.SYSTEM.getIdentifier());
        for (PackageInfo pkg : installedPackages) {
            updateCertsForPackage(pkg);
            // This may be unnecessary before initialization, but invalidate the cache all the time
            // just in case to ensure consistency.
            getUidsForPackage(pkg.packageName, /* invalidateCache= */ true);
        }
    }

    private static <T> String getObfuscatedPackages(
            Collection<T> packageNames, Function<T, String> obfuscator) {
        StringJoiner obfuscated = new StringJoiner(", ", "{", "}");
@@ -576,13 +597,21 @@ public class CarrierPrivilegesTracker extends Handler {

    /**
     * Returns true iff there is an overlap between the provided certificate hashes and the
     * certificate hashes stored in mCarrierConfigRules and mUiccRules.
     * certificate hashes stored in mTestOverrideRules, mCarrierConfigRules and mUiccRules.
     */
    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) {
            // Non-null (whether empty or not) test override rule will ignore the UICC and CC rules
            if (mTestOverrideRules != null) {
                for (UiccAccessRule rule : mTestOverrideRules) {
                    if (rule.matches(cert, pkgName)) {
                        return true;
                    }
                }
            } else {
                for (UiccAccessRule rule : mCarrierConfigRules) {
                    if (rule.matches(cert, pkgName)) {
                        return true;
@@ -594,6 +623,7 @@ public class CarrierPrivilegesTracker extends Handler {
                    }
                }
            }
        }
        return false;
    }

@@ -635,6 +665,7 @@ public class CarrierPrivilegesTracker extends Handler {
        } finally {
            mPrivilegedPackageInfoLock.readLock().unlock();
        }
        pw.println("CarrierPrivilegesTracker - Test-override rules: " + mTestOverrideRules);
        pw.println("CarrierPrivilegesTracker - SIM-loaded rules: " + mUiccRules);
        pw.println("CarrierPrivilegesTracker - Carrier config rules: " + mCarrierConfigRules);
        if (VDBG) {
@@ -671,4 +702,35 @@ public class CarrierPrivilegesTracker extends Handler {
    public void unregisterCarrierPrivilegesListener(Handler handler) {
        sendMessage(obtainMessage(ACTION_UNREGISTER_LISTENER, handler));
    }

    /**
     * Set test carrier privilege rules which will override the actual rules on both Carrier Config
     * and SIM.
     *
     * <p>{@code carrierPrivilegeRules} can be null, in which case the rules on the Carrier Config
     * and SIM will be used and any previous overrides will be cleared.
     *
     * @see TelephonyManager#setCarrierTestOverride
     */
    public void setTestOverrideCarrierPrivilegeRules(@Nullable String carrierPrivilegeRules) {
        sendMessage(obtainMessage(ACTION_SET_TEST_OVERRIDE_RULE, carrierPrivilegeRules));
    }

    private void handleSetTestOverrideRules(@Nullable String carrierPrivilegeRules) {
        if (carrierPrivilegeRules == null) {
            mTestOverrideRules = null;
        } else if (carrierPrivilegeRules.isEmpty()) {
            mTestOverrideRules = Collections.emptyList();
        } else {
            mTestOverrideRules = Arrays.asList(UiccAccessRule.decodeRulesFromCarrierConfig(
                    new String[]{carrierPrivilegeRules}));
            // TODO(b/215239409): remove the additional cache refresh for test override cases.
            // Test override doesn't respect if the package for the specified cert has been removed
            // or hidden since initialization. Refresh the cache again to get the pkg/uid with the
            // best effort.
            refreshInstalledPackageCache();
        }

        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
    }
}
+66 −4
Original line number Diff line number Diff line
@@ -90,6 +90,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {

    private static final String PACKAGE_1 = "android.test.package1";
    private static final String PACKAGE_2 = "android.test.package2";
    private static final String PACKAGE_3 = "android.test.package3";
    private static final Set<String> PRIVILEGED_PACKAGES = Set.of(PACKAGE_1, PACKAGE_2);

    private static final String CERT_1 = "11223344";
@@ -100,6 +101,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {

    private static final int UID_1 = 10000001;
    private static final int UID_2 = 10000002;
    private static final int UID_3 = 10000003;
    private static final int[] PRIVILEGED_UIDS = {UID_1, UID_2};

    private static final int PM_FLAGS =
@@ -187,6 +189,11 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
                .thenReturn(installedPackages);
    }

    private void setupInstalledPackagesWithFlags(int flags, PackageCertInfo... pkgCertInfos)
            throws Exception {

    }

    /**
     * Creates and returns a CarrierPrivilegesTracker instance.
     *
@@ -213,7 +220,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
                carrierConfigRuleString(getHash(CERT_1)), carrierConfigRuleString(getHash(CERT_2)));
        setupInstalledPackages(
                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),
                new PackageCertInfo(PACKAGE_3, CERT_3, USER_1, UID_3));
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
    }

@@ -221,7 +229,8 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        setupSimLoadedRules(ruleWithHashOnly(getHash(CERT_1)), ruleWithHashOnly(getHash(CERT_2)));
        setupInstalledPackages(
                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),
                new PackageCertInfo(PACKAGE_3, CERT_3, USER_1, UID_3));
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
    }

@@ -660,6 +669,59 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        verifyCarrierPrivilegesChangedUpdates(List.of());
    }

    @Test
    public void testSetCarrierTestOverrideWithEmptyRule() throws Exception {
        // Start with PACKAGE_1 & PACKAGE_2 installed and have privileges from CarrierConfig
        setupCarrierPrivilegesTrackerWithCarrierConfigUids();

        // Set test override with EMPTY rule
        mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules("");
        mTestableLooper.processAllMessages();

        // Expect no package will have privilege at last
        verifyRegistrantUpdates(new int[0], 1 /* expectedUidUpdates */);
        verifyCarrierPrivilegesChangedUpdates(
                List.of(
                        new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS),
                        new Pair<>(Set.of(), new int[0])));

        // Set test override with null rule to revoke previous test override
        mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(null);
        mTestableLooper.processAllMessages();

        // Expect all privileges from Carrier Config come back
        verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */);
        verifyCarrierPrivilegesChangedUpdates(
                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS)));
    }

    @Test
    public void testSetCarrierTestOverrideWithNonEmptyRule() throws Exception {
        // Start with PACKAGE_1 & PACKAGE_2 installed and have privileges from UICC
        setupCarrierPrivilegesTrackerWithSimLoadedUids();

        // Set test override with non-EMPTY rule (PACKAGE_3)
        mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(getHash(CERT_3));
        mTestableLooper.processAllMessages();

        // Expect only PACKAGE_3 will have privilege at last
        verifyRegistrantUpdates(new int[]{UID_3}, 1 /* expectedUidUpdates */);
        verifyCarrierPrivilegesChangedUpdates(
                List.of(
                        new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS),
                        new Pair<>(Set.of(PACKAGE_3), new int[]{UID_3})));


        // Set test override with null rule to revoke previous test override
        mCarrierPrivilegesTracker.setTestOverrideCarrierPrivilegeRules(null);
        mTestableLooper.processAllMessages();

        // Expect all privileges from UICC come back
        verifyRegistrantUpdates(PRIVILEGED_UIDS, 2 /* expectedUidUpdates */);
        verifyCarrierPrivilegesChangedUpdates(
                List.of(new Pair<>(PRIVILEGED_PACKAGES, PRIVILEGED_UIDS)));
    }

    private void sendCarrierConfigChangedIntent(int subId, int phoneId) {
        mContext.sendBroadcast(
                new Intent(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED)