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

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

Merge changes Ia6bab238,Id2e66c27,Ia57a2d8a

* changes:
  CPT: build carrier privileges cache when AccessRules are loaded
  CPT: always use same PackageManager flags to query installed packages
  Refresh carrier service state when carrier app is en/disabled
parents 19f9db87 fc686821
Loading
Loading
Loading
Loading
+86 −42
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ import static android.telephony.TelephonyManager.SIM_STATE_NOT_READY;
import static android.telephony.TelephonyManager.SIM_STATE_READY;
import static android.telephony.TelephonyManager.SIM_STATE_UNKNOWN;

import static com.android.internal.telephony.SubscriptionInfoUpdater.simStateString;

import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -112,6 +114,17 @@ public class CarrierPrivilegesTracker extends Handler {
     */
    private static final long CLEAR_UICC_RULES_DELAY_MILLIS = TimeUnit.SECONDS.toMillis(30);

    /**
     * PackageManager flags used to query installed packages.
     * Include DISABLED_UNTIL_USED components. This facilitates cases where a carrier app
     * is disabled by default, and some other component wants to enable it when it has
     * gained carrier privileges (as an indication that a matching SIM has been inserted).
     */
    private static final int INSTALLED_PACKAGES_QUERY_FLAGS =
            PackageManager.GET_SIGNING_CERTIFICATES
                    | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
                    | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;

    /**
     * Action to register a Registrant with this Tracker.
     * obj: Registrant that will be notified of Carrier Privileged UID changes.
@@ -139,16 +152,17 @@ public class CarrierPrivilegesTracker extends Handler {
    private static final int ACTION_SIM_STATE_UPDATED = 4;

    /**
     * Action for tracking when a package is installed or replaced on the device.
     * obj: String package name that was installed or replaced on the device.
     * Action for tracking when a package is installed, replaced or changed (exclude the case
     * disabled by user) on the device.
     * obj: String package name that was installed, replaced or changed on the device.
     */
    private static final int ACTION_PACKAGE_ADDED_OR_REPLACED = 5;
    private static final int ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED = 5;

    /**
     * Action for tracking when a package is uninstalled on the device.
     * obj: String package name that was installed on the device.
     * Action for tracking when a package is uninstalled or disabled by user on the device.
     * obj: String package name that was installed or disabled by user on the device.
     */
    private static final int ACTION_PACKAGE_REMOVED = 6;
    private static final int ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER = 6;

    /**
     * Action used to initialize the state of the Tracker.
@@ -166,6 +180,11 @@ public class CarrierPrivilegesTracker extends Handler {
     */
    private static final int ACTION_CLEAR_UICC_RULES = 9;

    /**
     * Action to handle the case when UiccAccessRules has been loaded.
     */
    private static final int ACTION_UICC_ACCESS_RULES_LOADED = 10;

    private final Context mContext;
    private final Phone mPhone;
    private final PackageManager mPackageManager;
@@ -306,11 +325,8 @@ public class CarrierPrivilegesTracker extends Handler {
                        }
                        case Intent.ACTION_PACKAGE_ADDED: // fall through
                        case Intent.ACTION_PACKAGE_REPLACED: // fall through
                        case Intent.ACTION_PACKAGE_REMOVED: {
                            int what =
                                    (action.equals(Intent.ACTION_PACKAGE_REMOVED))
                                            ? ACTION_PACKAGE_REMOVED
                                            : ACTION_PACKAGE_ADDED_OR_REPLACED;
                        case Intent.ACTION_PACKAGE_REMOVED: // fall through
                        case Intent.ACTION_PACKAGE_CHANGED: {
                            Uri uri = intent.getData();
                            String pkgName = (uri != null) ? uri.getSchemeSpecificPart() : null;
                            if (TextUtils.isEmpty(pkgName)) {
@@ -318,6 +334,24 @@ public class CarrierPrivilegesTracker extends Handler {
                                return;
                            }

                            boolean removed = action.equals(Intent.ACTION_PACKAGE_REMOVED);
                            boolean disabledByUser = false;
                            boolean notExist = false;
                            try {
                                disabledByUser = action.equals(Intent.ACTION_PACKAGE_CHANGED)
                                        && mPackageManager.getApplicationEnabledSetting(pkgName)
                                        == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
                            } catch (IllegalArgumentException iae) {
                                // Very rare case when package changed race with package removed
                                Rlog.w(TAG, "Package does not exist: " + pkgName);
                                notExist = true;
                            }
                            // When a package is explicitly disabled by the user or does not exist,
                            // treat them as if it was removed: clear it from the cache
                            int what = (removed || disabledByUser || notExist)
                                    ? ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER
                                    : ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED;

                            sendMessage(obtainMessage(what, pkgName));
                            break;
                        }
@@ -349,6 +383,7 @@ public class CarrierPrivilegesTracker extends Handler {
        packageFilter.addAction(Intent.ACTION_PACKAGE_ADDED);
        packageFilter.addAction(Intent.ACTION_PACKAGE_REPLACED);
        packageFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
        packageFilter.addAction(Intent.ACTION_PACKAGE_CHANGED);

        // For package-related broadcasts, specify the data scheme for "package" to receive the
        // package name along with the broadcast
@@ -379,14 +414,14 @@ public class CarrierPrivilegesTracker extends Handler {
                handleSimStateChanged(msg.arg1, msg.arg2);
                break;
            }
            case ACTION_PACKAGE_ADDED_OR_REPLACED: {
            case ACTION_PACKAGE_ADDED_REPLACED_OR_CHANGED: {
                String pkgName = (String) msg.obj;
                handlePackageAddedOrReplaced(pkgName);
                handlePackageAddedReplacedOrChanged(pkgName);
                break;
            }
            case ACTION_PACKAGE_REMOVED: {
            case ACTION_PACKAGE_REMOVED_OR_DISABLED_BY_USER: {
                String pkgName = (String) msg.obj;
                handlePackageRemoved(pkgName);
                handlePackageRemovedOrDisabledByUser(pkgName);
                break;
            }
            case ACTION_INITIALIZE_TRACKER: {
@@ -402,6 +437,10 @@ public class CarrierPrivilegesTracker extends Handler {
                handleClearUiccRules();
                break;
            }
            case ACTION_UICC_ACCESS_RULES_LOADED: {
                handleUiccAccessRulesLoaded();
                break;
            }
            default: {
                Rlog.e(TAG, "Received unknown msg type: " + msg.what);
                break;
@@ -474,16 +513,8 @@ public class CarrierPrivilegesTracker extends Handler {

        // Only include the UICC rules if the SIM is fully loaded
        if (simState == SIM_STATE_LOADED) {
            mClearUiccRulesUptimeMillis = CLEAR_UICC_RULE_NOT_SCHEDULED;
            removeMessages(ACTION_CLEAR_UICC_RULES);

            updatedUiccRules = getSimRules();

            mLocalLog.log("SIM fully loaded:"
                    + " slotId=" + slotId
                    + " simState=" + simState
                    + " updated SIM-loaded rules=" + updatedUiccRules);
            maybeUpdateRulesAndNotifyRegistrants(mUiccRules, updatedUiccRules);
            mLocalLog.log("SIM fully loaded, handleUiccAccessRulesLoaded.");
            handleUiccAccessRulesLoaded();
        } else {
            if (!mUiccRules.isEmpty()
                    && mClearUiccRulesUptimeMillis == CLEAR_UICC_RULE_NOT_SCHEDULED) {
@@ -491,7 +522,8 @@ public class CarrierPrivilegesTracker extends Handler {
                        SystemClock.uptimeMillis() + CLEAR_UICC_RULES_DELAY_MILLIS;
                sendMessageAtTime(obtainMessage(ACTION_CLEAR_UICC_RULES),
                        mClearUiccRulesUptimeMillis);
                mLocalLog.log("SIM is gone. Delay " + TimeUnit.MILLISECONDS.toSeconds(
                mLocalLog.log("SIM is gone, simState=" + simStateString(simState)
                        + ". Delay " + TimeUnit.MILLISECONDS.toSeconds(
                        CLEAR_UICC_RULES_DELAY_MILLIS) + " seconds to clear UICC rules.");
            } else {
                mLocalLog.log(
@@ -500,6 +532,21 @@ public class CarrierPrivilegesTracker extends Handler {
        }
    }

    private void handleUiccAccessRulesLoaded() {
        mClearUiccRulesUptimeMillis = CLEAR_UICC_RULE_NOT_SCHEDULED;
        removeMessages(ACTION_CLEAR_UICC_RULES);

        List<UiccAccessRule> updatedUiccRules = getSimRules();
        mLocalLog.log("UiccAccessRules loaded:"
                + " updated SIM-loaded rules=" + updatedUiccRules);
        maybeUpdateRulesAndNotifyRegistrants(mUiccRules, updatedUiccRules);
    }

    /** Called when UiccAccessRules has been loaded */
    public void onUiccAccessRulesLoaded() {
        sendEmptyMessage(ACTION_UICC_ACCESS_RULES_LOADED);
    }

    private void handleClearUiccRules() {
        mClearUiccRulesUptimeMillis = CLEAR_UICC_RULE_NOT_SCHEDULED;
        removeMessages(ACTION_CLEAR_UICC_RULES);
@@ -530,12 +577,12 @@ public class CarrierPrivilegesTracker extends Handler {
        return uiccProfile.getCarrierPrivilegeAccessRules();
    }

    private void handlePackageAddedOrReplaced(@Nullable String pkgName) {
    private void handlePackageAddedReplacedOrChanged(@Nullable String pkgName) {
        if (pkgName == null) return;

        PackageInfo pkg;
        try {
            pkg = mPackageManager.getPackageInfo(pkgName, PackageManager.GET_SIGNING_CERTIFICATES);
            pkg = mPackageManager.getPackageInfo(pkgName, INSTALLED_PACKAGES_QUERY_FLAGS);
        } catch (NameNotFoundException e) {
            Rlog.e(TAG, "Error getting installed package: " + pkgName, e);
            return;
@@ -546,9 +593,11 @@ public class CarrierPrivilegesTracker extends Handler {
        // installed for a user it wasn't installed in before, which means there will be an
        // additional UID.
        getUidsForPackage(pkg.packageName, /* invalidateCache= */ true);
        mLocalLog.log("Package added/replaced:"
        if (VDBG) {
            Rlog.d(TAG, "Package added/replaced/changed:"
                    + " pkg=" + Rlog.pii(TAG, pkgName)
                    + " cert hashes=" + mInstalledPackageCerts.get(pkgName));
        }

        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
    }
@@ -567,15 +616,17 @@ public class CarrierPrivilegesTracker extends Handler {
        mInstalledPackageCerts.put(pkg.packageName, certs);
    }

    private void handlePackageRemoved(@Nullable String pkgName) {
    private void handlePackageRemovedOrDisabledByUser(@Nullable String pkgName) {
        if (pkgName == null) return;

        if (mInstalledPackageCerts.remove(pkgName) == null || mCachedUids.remove(pkgName) == null) {
            Rlog.e(TAG, "Unknown package was uninstalled: " + pkgName);
            Rlog.e(TAG, "Unknown package was uninstalled or disabled by user: " + pkgName);
            return;
        }

        mLocalLog.log("Package removed: pkg=" + Rlog.pii(TAG, pkgName));
        if (VDBG) {
            Rlog.d(TAG, "Package removed or disabled by user: pkg=" + Rlog.pii(TAG, pkgName));
        }

        maybeUpdatePrivilegedPackagesAndNotifyRegistrants();
    }
@@ -607,16 +658,9 @@ public class CarrierPrivilegesTracker extends Handler {
    }

    private void refreshInstalledPackageCache() {
        // Include DISABLED_UNTIL_USED components. This facilitates cases where a carrier app
        // is disabled by default, and some other component wants to enable it when it has
        // gained carrier privileges (as an indication that a matching SIM has been inserted).
        int flags =
                PackageManager.GET_SIGNING_CERTIFICATES
                        | PackageManager.MATCH_DISABLED_UNTIL_USED_COMPONENTS
                        | PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS;
        List<PackageInfo> installedPackages =
                mPackageManager.getInstalledPackagesAsUser(
                        flags, UserHandle.SYSTEM.getIdentifier());
                        INSTALLED_PACKAGES_QUERY_FLAGS, UserHandle.SYSTEM.getIdentifier());
        for (PackageInfo pkg : installedPackages) {
            updateCertsForPackage(pkg);
            // This may be unnecessary before initialization, but invalidate the cache all the time
+8 −0
Original line number Diff line number Diff line
@@ -55,6 +55,7 @@ import android.util.ArraySet;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.CarrierAppUtils;
import com.android.internal.telephony.CarrierPrivilegesTracker;
import com.android.internal.telephony.CommandsInterface;
import com.android.internal.telephony.IccCard;
import com.android.internal.telephony.IccCardConstants;
@@ -240,6 +241,13 @@ public class UiccProfile extends IccCard {

                case EVENT_CARRIER_PRIVILEGES_LOADED:
                    if (VDBG) log("handleMessage: EVENT_CARRIER_PRIVILEGES_LOADED");
                    Phone phone = PhoneFactory.getPhone(mPhoneId);
                    if (phone != null) {
                        CarrierPrivilegesTracker cpt = phone.getCarrierPrivilegesTracker();
                        if (cpt != null) {
                            cpt.onUiccAccessRulesLoaded();
                        }
                    }
                    onCarrierPrivilegesLoadedMessage();
                    updateExternalState();
                    break;
+59 −3
Original line number Diff line number Diff line
@@ -16,7 +16,6 @@

package com.android.internal.telephony;

import static android.content.pm.PackageManager.GET_SIGNING_CERTIFICATES;
import static android.os.UserHandle.SYSTEM;
import static android.telephony.CarrierConfigManager.EXTRA_SLOT_INDEX;
import static android.telephony.CarrierConfigManager.EXTRA_SUBSCRIPTION_INDEX;
@@ -200,7 +199,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
            pkg.signatures = new Signature[] {new Signature(pkgCertInfo.cert)};

            when(mPackageManager.getPackageInfo(
                    eq(pkgCertInfo.pkgName), eq(GET_SIGNING_CERTIFICATES)))
                    eq(pkgCertInfo.pkgName), eq(PM_FLAGS)))
                    .thenReturn(pkg);
            when(mPackageManager.getPackageUidAsUser(
                    eq(pkgCertInfo.pkgName), eq(pkgCertInfo.userInfo.id)))
@@ -313,6 +312,22 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        }
    }

    private void verifyCarrierServicesChangedUpdates(List<Pair<String, Integer>> expectedUpdates) {
        if (expectedUpdates.isEmpty()) {
            verify(mTelephonyRegistryManager, never())
                    .notifyCarrierPrivilegesChanged(anyInt(), any(), any());
        } else {
            InOrder inOrder = inOrder(mTelephonyRegistryManager);
            for (Pair<String, Integer> expectedUpdate : expectedUpdates) {
                // By looking at TelephonyRegistryManager, we can see the full flow as
                // it evolves.
                inOrder.verify(mTelephonyRegistryManager)
                        .notifyCarrierServiceChanged(
                                eq(PHONE_ID), eq(expectedUpdate.first), eq(expectedUpdate.second));
            }
        }
    }

    @Test
    public void testRegisterListener() throws Exception {
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();
@@ -798,7 +813,7 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        // Update PACKAGE_1 to have no signatures
        PackageInfo pkg = new PackageInfo();
        pkg.packageName = PACKAGE_1;
        when(mPackageManager.getPackageInfo(eq(PACKAGE_1), eq(GET_SIGNING_CERTIFICATES)))
        when(mPackageManager.getPackageInfo(eq(PACKAGE_1), eq(PM_FLAGS)))
                .thenReturn(pkg);

        sendPackageChangedIntent(Intent.ACTION_PACKAGE_ADDED, PACKAGE_1);
@@ -867,6 +882,47 @@ public class CarrierPrivilegesTrackerTest extends TelephonyTest {
        verifyCarrierPrivilegesChangedUpdates(List.of());
    }

    @Test
    public void testPackageDisabledAndThenEnabled() throws Exception {
        // Start with certs and packages installed
        setupCarrierConfigRules(carrierConfigRuleString(getHash(CERT_1)));
        setupInstalledPackages(
                new PackageCertInfo(PACKAGE_1, CERT_1, USER_1, UID_1),
                new PackageCertInfo(PACKAGE_2, CERT_2, USER_1, UID_2));
        when(mPackageManager.getPackageUid(eq(PACKAGE_1), anyInt())).thenReturn(UID_1);
        when(mPackageManager.getPackageUid(eq(PACKAGE_2), anyInt())).thenReturn(UID_2);
        ResolveInfo resolveInfoPkg1 = new ResolveInfoBuilder().setService(PACKAGE_1).build();
        doReturn(List.of(resolveInfoPkg1))
                .when(mPackageManager)
                .queryIntentServices(any(), anyInt());
        mCarrierPrivilegesTracker = createCarrierPrivilegesTracker();

        // Package_1 is disabled
        when(mPackageManager.getApplicationEnabledSetting(eq(PACKAGE_1))).thenReturn(
                PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER);
        doReturn(List.of()).when(
                mPackageManager).queryIntentServices(any(), anyInt());
        sendPackageChangedIntent(Intent.ACTION_PACKAGE_CHANGED, PACKAGE_1);
        mTestableLooper.processAllMessages();

        verifyCurrentState(Set.of(), new int[0]);
        verifyCarrierPrivilegesChangedUpdates(List.of(new Pair<>(Set.of(), Set.of())));
        verifyCarrierServicesChangedUpdates(List.of(new Pair<>(null, -1)));

        // Package_1 is re-enabled
        when(mPackageManager.getApplicationEnabledSetting(eq(PACKAGE_1))).thenReturn(
                PackageManager.COMPONENT_ENABLED_STATE_ENABLED);
        doReturn(List.of(resolveInfoPkg1)).when(
                mPackageManager).queryIntentServices(any(), anyInt());
        sendPackageChangedIntent(Intent.ACTION_PACKAGE_CHANGED, PACKAGE_1);
        mTestableLooper.processAllMessages();

        verifyCurrentState(Set.of(PACKAGE_1), new int[] {UID_1});
        verifyCarrierPrivilegesChangedUpdates(
                List.of(new Pair<>(Set.of(PACKAGE_1), Set.of(UID_1))));
        verifyCarrierServicesChangedUpdates(List.of(new Pair<>(PACKAGE_1, UID_1)));
    }

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