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

Commit f10bfbce authored by Cody Kesting's avatar Cody Kesting
Browse files

Cache all certs and installed packages when initialized.

When CarrierPrivilegeTracker is initialized, it does not initially know
what the current CarrierConfig certs, SIM-loaded certs, or installed
packages are - each must be loaded before the Tracker can begin. These
values are fetched on the Handler thread to avoid blocking the Thread
used to instantiate the Tracker.

Bug: 147391402
Test: Tested on crosshatch build
Change-Id: I0605510af247ad591a37097b0ec2a6bcd5588556
Merged-In: I0605510af247ad591a37097b0ec2a6bcd5588556
(cherry picked from commit 29712053)
parent 0590ea27
Loading
Loading
Loading
Loading
+86 −31
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.os.Message;
import android.os.PersistableBundle;
import android.os.Registrant;
import android.os.RegistrantList;
import android.os.UserHandle;
import android.os.UserManager;
import android.telephony.CarrierConfigManager;
import android.telephony.SubscriptionManager;
@@ -59,6 +60,7 @@ import android.util.Log;
import com.android.internal.telephony.uicc.IccUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -112,6 +114,11 @@ public class CarrierPrivilegesTracker extends Handler {
     */
    private static final int ACTION_PACKAGE_REMOVED = 6;

    /**
     * Action used to initialize the state of the Tracker.
     */
    private static final int ACTION_INITIALIZE_TRACKER = 7;

    private final Context mContext;
    private final Phone mPhone;
    private final CarrierConfigManager mCarrierConfigManager;
@@ -212,6 +219,8 @@ public class CarrierPrivilegesTracker extends Handler {
        mInstalledPackageCerts = new ArrayMap<>();
        mCachedUids = new ArrayMap<>();
        mPrivilegedUids = new int[0];

        sendMessage(obtainMessage(ACTION_INITIALIZE_TRACKER));
    }

    @Override
@@ -243,6 +252,10 @@ public class CarrierPrivilegesTracker extends Handler {
                handlePackageRemoved(pkgName);
                break;
            }
            case ACTION_INITIALIZE_TRACKER: {
                handleInitializeTracker();
                break;
            }
            default: {
                Log.e(TAG, "Received unknown msg type: " + msg.what);
                break;
@@ -262,13 +275,24 @@ public class CarrierPrivilegesTracker extends Handler {
    private void handleCarrierConfigUpdated(int subId, int slotIndex) {
        if (slotIndex != mPhone.getPhoneId()) return;

        Set<String> updatedCarrierConfigCerts = new ArraySet<>();
        Set<String> updatedCarrierConfigCerts = Collections.EMPTY_SET;

        // 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.
        if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
            updatedCarrierConfigCerts = getCarrierConfigCerts(subId);
        }

        maybeUpdateCertsAndNotifyRegistrants(mCarrierConfigCerts, updatedCarrierConfigCerts);
    }

    private Set<String> getCarrierConfigCerts(int subId) {
        PersistableBundle carrierConfigs = mCarrierConfigManager.getConfigForSubId(subId);
            if (mCarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) {
        if (!mCarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfigs)) {
            return Collections.EMPTY_SET;
        }

        Set<String> updatedCarrierConfigCerts = new ArraySet<>();
        String[] carrierConfigCerts =
                carrierConfigs.getStringArray(KEY_CARRIER_CERTIFICATE_STRING_ARRAY);

@@ -277,21 +301,28 @@ public class CarrierPrivilegesTracker extends Handler {
                updatedCarrierConfigCerts.add(cert.toUpperCase());
            }
        }
            }
        }

        maybeUpdateCertsAndNotifyRegistrants(mCarrierConfigCerts, updatedCarrierConfigCerts);
        return updatedCarrierConfigCerts;
    }

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

        Set<String> updatedUiccCerts = new ArraySet<>();
        Set<String> updatedUiccCerts = Collections.EMPTY_SET;

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

        maybeUpdateCertsAndNotifyRegistrants(mUiccCerts, updatedUiccCerts);
    }

    private Set<String> getSimCerts() {
        Set<String> updatedUiccCerts = Collections.EMPTY_SET;
        TelephonyManager telMan = mTelephonyManager.createForSubscriptionId(mPhone.getSubId());

        if (telMan.hasIccCard(mPhone.getPhoneId())) {
            updatedUiccCerts = new ArraySet<>();
            List<String> uiccCerts = telMan.getCertsFromCarrierPrivilegeAccessRules();
            if (uiccCerts != null) {
                for (String cert : uiccCerts) {
@@ -299,9 +330,7 @@ public class CarrierPrivilegesTracker extends Handler {
                }
            }
        }
        }

        maybeUpdateCertsAndNotifyRegistrants(mUiccCerts, updatedUiccCerts);
        return updatedUiccCerts;
    }

    private void handlePackageAddedOrReplaced(String pkgName) {
@@ -313,6 +342,18 @@ public class CarrierPrivilegesTracker extends Handler {
            return;
        }

        updateCertsForPackage(pkg);
        try {
            mCachedUids.put(pkg.packageName, getUidsForPackage(pkg.packageName));
        } catch (NameNotFoundException exception) {
            // Didn't find package. Continue looking at other packages
            Log.e(TAG, "Unable to find uid for package: " + pkg.packageName);
        }

        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
    }

    private void updateCertsForPackage(PackageInfo pkg) {
        Set<String> certs = new ArraySet<>();
        List<Signature> signatures = UiccAccessRule.getSignatures(pkg);
        for (Signature signature : signatures) {
@@ -324,15 +365,6 @@ public class CarrierPrivilegesTracker extends Handler {
        }

        mInstalledPackageCerts.put(pkg.packageName, certs);

        try {
            mCachedUids.put(pkg.packageName, getUidsForPackage(pkg.packageName));
        } catch (NameNotFoundException exception) {
            // Didn't find package. Continue looking at other packages
            Log.e(TAG, "Unable to find uid for package: " + pkg.packageName);
        }

        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
    }

    private void handlePackageRemoved(String pkgName) {
@@ -345,6 +377,29 @@ public class CarrierPrivilegesTracker extends Handler {
        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
    }

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

        // Cache SIM certs
        mUiccCerts.addAll(getSimCerts());

        // 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);
        }

        // Okay because no registrants exist yet
        maybeUpdatePrivilegedUidsAndNotifyRegistrants();
    }

    private void maybeUpdateCertsAndNotifyRegistrants(
            Set<String> currentCerts, Set<String> updatedCerts) {
        if (!currentCerts.equals(updatedCerts)) {