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

Commit 29a6bb7f authored by rambowang's avatar rambowang
Browse files

Introduce utility method SubscripitonManager.canManageSubscriptionAsUser

SubscriptionManager.canManageSubscription always uses the user context
created from SubscriptionManager to query packages. It is usually the
system user in phone process services. When the carrier app is installed
on secondary users (e.g. main user in HSUM) only, the query will fail.

The new utility method allows phone process components to query packages
as designed user and avoid duplicated logic in services side.

Bug: 371452139
Test: FrameworksTelephonyTests
Flag: com.android.internal.telephony.flags.hsum_package_manager
Change-Id: Icc1376744de356e2bb3dcf2e7bf68d89b97c16ad
parent e8b7d81f
Loading
Loading
Loading
Loading
+51 −3
Original line number Diff line number Diff line
@@ -3474,6 +3474,9 @@ public class SubscriptionManager {
    @SystemApi
    public boolean canManageSubscription(@NonNull SubscriptionInfo info,
            @NonNull String packageName) {
        if (Flags.hsumPackageManager()) {
            return canManageSubscriptionAsUser(info, packageName, mContext.getUser());
        } else {
            if (info == null || info.getAccessRules() == null || packageName == null) {
                return false;
            }
@@ -3494,6 +3497,51 @@ public class SubscriptionManager {
            }
            return false;
        }
    }

    /**
     * Checks whether the given app is authorized to manage the given subscription for given user.
     *
     * <p>An app can only be authorized if it is available to the given user and included in the
     * {@link android.telephony.UiccAccessRule} of the {@link android.telephony.SubscriptionInfo}
     * with the access status.
     *
     * <p>Only supported for embedded subscriptions (if {@link SubscriptionInfo#isEmbedded} returns
     * true). To check for permissions for non-embedded subscription as well,
     * see {@link android.telephony.TelephonyManager#hasCarrierPrivileges}.
     *
     * @param info        The subscription to check.
     * @param packageName Package name of the app to check.
     * @param user        UserHandle to check
     * @return whether the app is authorized to manage this subscription per its access rules.
     *
     * @see android.telephony.TelephonyManager#hasCarrierPrivileges
     * @hide
     */
    public boolean canManageSubscriptionAsUser(@NonNull SubscriptionInfo info,
            @NonNull String packageName, @NonNull UserHandle user) {
        if (info == null || info.getAccessRules() == null || packageName == null) {
            return false;
        }
        PackageManager pm = mContext.getUser().equals(user)
                ? mContext.getPackageManager()
                : mContext.createContextAsUser(user, 0).getPackageManager();
        PackageInfo packageInfo;
        try {
            packageInfo = pm.getPackageInfo(packageName,
                    PackageManager.GET_SIGNING_CERTIFICATES);
        } catch (PackageManager.NameNotFoundException e) {
            logd("Unknown package: " + packageName);
            return false;
        }
        for (UiccAccessRule rule : info.getAccessRules()) {
            if (rule.getCarrierPrivilegeStatus(packageInfo)
                    == TelephonyManager.CARRIER_PRIVILEGE_STATUS_HAS_ACCESS) {
                return true;
            }
        }
        return false;
    }

    /**
     * Set which subscription is preferred for cellular data.