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

Commit 0d2993e1 authored by Rambo Wang's avatar Rambo Wang Committed by Automerger Merge Worker
Browse files

Merge "Support test override carrier privilege in CarrierPrivilegeTracker" am: a0ac05da

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

Change-Id: I021a5f69d37852a6eb9009313f7a3ea2872467ae
parents 0e9a6c92 a0ac05da
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)