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

Commit 18eadbba authored by Hunter Knepshield's avatar Hunter Knepshield Committed by Rambo Wang
Browse files

Move carrier privilege intent resolution to CarrierPrivilegesTracker.

These methods now use CarrierPrivilegesTracker as the source of truth,
and the Uicc{Port,Profile,CarrierPrivilegeRules} redundancies have been
removed.

This implicitly adds a caching layer that should result in noticeable
performance increases. While the PackageManager intent resolution
queries are still per-call, we now have a caching layer that allows
instantly determining whether a resolved component has privileges, and
we don't have to perform redundant PackageManager queries to get that
status.

Bug: 211796398
Test: atest com.android.internal.telephony.CarrierPrivilegesTrackerTest
Test: atest android.telephony.cts.TelephonyManagerTest
Change-Id: I2aa23f075b4536be2e372b95bff6f78171ad1319
Merged-In: Icdf82d070662eeac07fdaa3299163937a64fc563
(cherry picked from commit a99c48b0)
parent 3d29ad44
Loading
Loading
Loading
Loading
+46 −0
Original line number Diff line number Diff line
@@ -37,6 +37,7 @@ import android.content.IntentFilter;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.content.pm.UserInfo;
import android.net.Uri;
@@ -788,4 +789,49 @@ public class CarrierPrivilegesTracker extends Handler {
            mPrivilegedPackageInfoLock.readLock().unlock();
        }
    }

    /**
     * Backing of {@link TelephonyManager#getCarrierPackageNamesForIntent} and {@link
     * TelephonyManager#getCarrierPackageNamesForIntentAndPhone}.
     */
    public List<String> getCarrierPackageNamesForIntent(Intent intent) {
        // Do the PackageManager queries before we take the lock, as these are the longest-running
        // pieces of this method and don't depend on the set of carrier apps.
        List<ResolveInfo> resolveInfos = new ArrayList<>();
        resolveInfos.addAll(mPackageManager.queryBroadcastReceivers(intent, 0));
        resolveInfos.addAll(mPackageManager.queryIntentActivities(intent, 0));
        resolveInfos.addAll(mPackageManager.queryIntentServices(intent, 0));
        resolveInfos.addAll(mPackageManager.queryIntentContentProviders(intent, 0));

        // Now actually check which of the resolved packages have carrier privileges.
        mPrivilegedPackageInfoLock.readLock().lock();
        try {
            Set<String> packageNames = new ArraySet<>(); // For deduping purposes
            for (ResolveInfo resolveInfo : resolveInfos) {
                String packageName = getPackageName(resolveInfo);
                if (packageName == null) continue;
                switch (getCarrierPrivilegeStatusForPackage(packageName)) {
                    case TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS:
                        packageNames.add(packageName);
                        break;
                    case TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS:
                        continue;
                    default:
                        // Any other status is considered an error.
                        return Collections.emptyList();
                }
            }
            return new ArrayList<>(packageNames);
        } finally {
            mPrivilegedPackageInfoLock.readLock().unlock();
        }
    }

    private static @Nullable String getPackageName(ResolveInfo resolveInfo) {
        // Note: activityInfo covers both activities + broadcast receivers
        if (resolveInfo.activityInfo != null) return resolveInfo.activityInfo.packageName;
        if (resolveInfo.serviceInfo != null) return resolveInfo.serviceInfo.packageName;
        if (resolveInfo.providerInfo != null) return resolveInfo.providerInfo.packageName;
        return null;
    }
}
+5 −7
Original line number Diff line number Diff line
@@ -31,8 +31,6 @@ import android.telephony.AnomalyReporter;
import android.util.LocalLog;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccPort;
import com.android.telephony.Rlog;

import java.util.ArrayList;
@@ -143,10 +141,10 @@ public class CarrierServicesSmsFilter {

    private Optional<String> getCarrierAppPackageForFiltering() {
        List<String> carrierPackages = null;
        UiccPort port = UiccController.getInstance().getUiccPort(mPhone.getPhoneId());
        if (port != null) {
            carrierPackages = port.getCarrierPackageNamesForIntent(
                    mContext.getPackageManager(),
        CarrierPrivilegesTracker cpt = mPhone.getCarrierPrivilegesTracker();
        if (cpt != null) {
            carrierPackages =
                    cpt.getCarrierPackageNamesForIntent(
                            new Intent(CarrierMessagingService.SERVICE_INTERFACE));
        } else {
            loge("getCarrierAppPackageForFiltering: UiccCard not initialized");
+5 −7
Original line number Diff line number Diff line
@@ -79,8 +79,6 @@ import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.GsmAlphabet.TextEncodingDetails;
import com.android.internal.telephony.cdma.sms.UserData;
import com.android.internal.telephony.uicc.UiccController;
import com.android.internal.telephony.uicc.UiccPort;
import com.android.telephony.Rlog;

import java.io.FileDescriptor;
@@ -2541,13 +2539,13 @@ public abstract class SMSDispatcher extends Handler {

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    protected String getCarrierAppPackageName() {
        UiccPort port = UiccController.getInstance().getUiccPort(mPhone.getPhoneId());
        if (port == null) {
        CarrierPrivilegesTracker cpt = mPhone.getCarrierPrivilegesTracker();
        if (cpt == null) {
            return null;
        }

        List<String> carrierPackages = port.getCarrierPackageNamesForIntent(
            mContext.getPackageManager(), new Intent(CarrierMessagingService.SERVICE_INTERFACE));
        List<String> carrierPackages =
                cpt.getCarrierPackageNamesForIntent(
                        new Intent(CarrierMessagingService.SERVICE_INTERFACE));
        if (carrierPackages != null && carrierPackages.size() == 1) {
            return carrierPackages.get(0);
        }
+0 −51
Original line number Diff line number Diff line
@@ -16,12 +16,9 @@

package com.android.internal.telephony.uicc;

import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
import android.os.AsyncResult;
import android.os.Binder;
@@ -392,54 +389,6 @@ public class UiccCarrierPrivilegeRules extends Handler {
        return TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS;
    }

    /**
     * Returns the package name of the carrier app that should handle the input intent.
     *
     * @param packageManager PackageManager for getting receivers.
     * @param intent Intent that will be sent.
     * @return list of carrier app package names that can handle the intent.
     *         Returns null if there is an error and an empty list if there
     *         are no matching packages.
     */
    public List<String> getCarrierPackageNamesForIntent(
            PackageManager packageManager, Intent intent) {
        List<String> packages = new ArrayList<String>();
        List<ResolveInfo> receivers = new ArrayList<ResolveInfo>();
        receivers.addAll(packageManager.queryBroadcastReceivers(intent, 0));
        receivers.addAll(packageManager.queryIntentContentProviders(intent, 0));
        receivers.addAll(packageManager.queryIntentActivities(intent, 0));
        receivers.addAll(packageManager.queryIntentServices(intent, 0));

        for (ResolveInfo resolveInfo : receivers) {
            String packageName = getPackageName(resolveInfo);
            if (packageName == null) {
                continue;
            }

            int status = getCarrierPrivilegeStatus(packageManager, packageName);
            if (status == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
                packages.add(packageName);
            } else if (status != TelephonyManager.CARRIER_PRIVILEGE_STATUS_NO_ACCESS) {
                // Any status apart from HAS_ACCESS and NO_ACCESS is considered an error.
                return null;
            }
        }

        return packages;
    }

    @Nullable
    private String getPackageName(ResolveInfo resolveInfo) {
        if (resolveInfo.activityInfo != null) {
            return resolveInfo.activityInfo.packageName;
        } else if (resolveInfo.serviceInfo != null) {
            return resolveInfo.serviceInfo.packageName;
        } else if (resolveInfo.providerInfo != null) {
            return resolveInfo.providerInfo.packageName;
        }
        return null;
    }

    /**
     * The following three situations could be due to logical channels temporarily unavailable, so
     * we retry up to MAX_RETRY times, with an interval of RETRY_INTERVAL_MS: 1. MISSING_RESOURCE,
+0 −16
Original line number Diff line number Diff line
@@ -17,7 +17,6 @@
package com.android.internal.telephony.uicc;

import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.Signature;
@@ -430,21 +429,6 @@ public class UiccPort {
        }
    }

    /**
     * Exposes {@link UiccCarrierPrivilegeRules#getCarrierPackageNamesForIntent}.
     * @deprecated Please use
     * {@link UiccProfile#getCarrierPackageNamesForIntent(PackageManager, Intent)} instead.
     */
    @Deprecated
    public List<String> getCarrierPackageNamesForIntent(
            PackageManager packageManager, Intent intent) {
        if (mUiccProfile != null) {
            return mUiccProfile.getCarrierPackageNamesForIntent(packageManager, intent);
        } else {
            return null;
        }
    }

    /**
     * @deprecated Please use {@link UiccProfile#setOperatorBrandOverride(String)} instead.
     */
Loading