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

Commit 551a15b0 authored by rambowang's avatar rambowang Committed by Rambo Wang
Browse files

Support SubscriptionManager.canManagerSubscription for HSUM

SM.canManageSubscription depends on the user context created from the
SubscriptionManager object to query packages. The user context was
system user within EuiccController and SubscriptionManagerService and
thus only system user was supported.

The change supports secondary users (e.g. Main User in HSUM) by creating
a current user context before getting the SubscriptionManager object.

Bug: 371452139
Test: atest SubscriptionManagerTest FrameworksTelephonyTests
Flag: com.android.internal.telephony.flags.hsum_package_manager
Change-Id: I53a16b108a715e7f5e8528e7671be4be1cd0a69f
parent 25733b2e
Loading
Loading
Loading
Loading
+18 −8
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import android.Manifest;
import android.Manifest.permission;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.app.admin.DevicePolicyManager;
@@ -70,6 +71,7 @@ import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneFactory;
import com.android.internal.telephony.euicc.EuiccConnector.OtaStatusChangedCallback;
import com.android.internal.telephony.flags.FeatureFlags;
import com.android.internal.telephony.flags.Flags;
import com.android.internal.telephony.subscription.SubscriptionManagerService;
import com.android.internal.telephony.uicc.IccUtils;
import com.android.internal.telephony.uicc.UiccController;
@@ -1089,7 +1091,7 @@ public class EuiccController extends IEuiccController.Stub {
            // system or the caller manage the target subscription, we let it continue. This is
            // because deleting subscription won't change status of any other subscriptions.
            if (!callerCanWriteEmbeddedSubscriptions
                    && !mSubscriptionManager.canManageSubscription(sub, callingPackage)
                    && !canManageSubscription(sub, callingPackage)
                    && !adminOwned) {
                Log.e(TAG, "No permissions: " + subscriptionId + " adminOwned=" + adminOwned);
                sendResult(callbackIntent, ERROR, null /* extrasIntent */);
@@ -1208,7 +1210,7 @@ public class EuiccController extends IEuiccController.Stub {
                if (callerCanWriteEmbeddedSubscriptions) {
                    passConsent = true;
                } else {
                    if (!mSubscriptionManager.canManageSubscription(sub, callingPackage)) {
                    if (!canManageSubscription(sub, callingPackage)) {
                        Log.e(TAG, "Not permitted to switch to sub: " + subscriptionId);
                        sendResult(callbackIntent, ERROR, null /* extrasIntent */);
                        return;
@@ -1287,7 +1289,7 @@ public class EuiccController extends IEuiccController.Stub {
            if ((cardId == TelephonyManager.UNSUPPORTED_CARD_ID || subInfo.getCardId() == cardId)
                    && subInfo.isEmbedded()
                    && (callerCanWriteEmbeddedSubscriptions
                    || mSubscriptionManager.canManageSubscription(subInfo, callingPackage))) {
                    || canManageSubscription(subInfo, callingPackage))) {
                return subInfo.getPortIndex();
            }
        }
@@ -1558,7 +1560,7 @@ public class EuiccController extends IEuiccController.Stub {
            // system or the caller can manage the target subscription, we let it continue. This is
            // because updating subscription nickname won't affect any other subscriptions.
            if (!callerCanWriteEmbeddedSubscriptions
                    && !mSubscriptionManager.canManageSubscription(sub, callingPackage)) {
                    && !canManageSubscription(sub, callingPackage)) {
                Log.e(TAG, "No permissions: " + subscriptionId);
                sendResult(callbackIntent, ERROR, null /* extrasIntent */);
                return;
@@ -2067,7 +2069,7 @@ public class EuiccController extends IEuiccController.Stub {
            if ((cardId == TelephonyManager.UNSUPPORTED_CARD_ID || subInfo.getCardId() == cardId)
                    && subInfo.isEmbedded()
                    && (!usePortIndex || subInfo.getPortIndex() == targetPortIndex)
                    && mSubscriptionManager.canManageSubscription(subInfo, callingPackage)) {
                    && canManageSubscription(subInfo, callingPackage)) {
                return true;
            }
        }
@@ -2136,8 +2138,7 @@ public class EuiccController extends IEuiccController.Stub {
                    if (subInfo.isEmbedded()
                            && subInfo.getCardId() == cardId
                            && (!usePortIndex || subInfo.getPortIndex() == targetPortIndex)
                            && mSubscriptionManager.canManageSubscription(
                            subInfo, callingPackage)) {
                            && canManageSubscription(subInfo, callingPackage)) {
                        return true;
                    }
                }
@@ -2156,7 +2157,7 @@ public class EuiccController extends IEuiccController.Stub {
        } else {
            for (SubscriptionInfo subInfo : subInfoList) {
                if (subInfo.isEmbedded()
                        && mSubscriptionManager.canManageSubscription(subInfo, callingPackage)) {
                        && canManageSubscription(subInfo, callingPackage)) {
                    return true;
                }
            }
@@ -2391,4 +2392,13 @@ public class EuiccController extends IEuiccController.Stub {
                    methodName + " is unsupported without " + FEATURE_TELEPHONY_EUICC);
        }
    }

    private boolean canManageSubscription(SubscriptionInfo subInfo, String packageName) {
        if (Flags.hsumPackageManager() && UserManager.isHeadlessSystemUserMode()) {
            return mSubscriptionManager.canManageSubscriptionAsUser(subInfo, packageName,
                    UserHandle.of(ActivityManager.getCurrentUser()));
        } else {
            return mSubscriptionManager.canManageSubscription(subInfo, packageName);
        }
    }
}
+13 −3
Original line number Diff line number Diff line
@@ -27,6 +27,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.UserIdInt;
import android.app.ActivityManager;
import android.app.AppOpsManager;
import android.app.PendingIntent;
import android.app.compat.CompatChanges;
@@ -720,7 +721,7 @@ public class SubscriptionManagerService extends ISub.Stub {
                    return false;
                }
            } else {
                if (!mSubscriptionManager.canManageSubscription(subInfo.toSubscriptionInfo(),
                if (!canManageSubscription(subInfo.toSubscriptionInfo(),
                        callingPackage)) {
                    loge("checkCarrierPrivilegeOnSubList: cannot manage sub " + subId);
                    return false;
@@ -2268,7 +2269,7 @@ public class SubscriptionManagerService extends ISub.Stub {
        return getSubscriptionInfoStreamAsUser(BINDER_WRAPPER.getCallingUserHandle())
                .map(SubscriptionInfoInternal::toSubscriptionInfo)
                .filter(subInfo -> subInfo.isEmbedded()
                        && mSubscriptionManager.canManageSubscription(subInfo, callingPackage))
                        && canManageSubscription(subInfo, callingPackage))
                .sorted(Comparator.comparing(SubscriptionInfo::getSimSlotIndex)
                        .thenComparing(SubscriptionInfo::getSubscriptionId))
                .collect(Collectors.toList());
@@ -2994,7 +2995,7 @@ public class SubscriptionManagerService extends ISub.Stub {
        return mSubscriptionDatabaseManager.getAllSubscriptions().stream()
                .map(SubscriptionInfoInternal::toSubscriptionInfo)
                .filter(info -> groupUuid.equals(info.getGroupUuid())
                        && (mSubscriptionManager.canManageSubscription(info, callingPackage)
                        && (canManageSubscription(info, callingPackage)
                        || TelephonyPermissions.checkCallingOrSelfReadPhoneStateNoThrow(
                                mContext, info.getSubscriptionId(), callingPackage,
                        callingFeatureId, "getSubscriptionsInGroup")))
@@ -4903,6 +4904,15 @@ public class SubscriptionManagerService extends ISub.Stub {
        return cardNumber;
    }

    private boolean canManageSubscription(SubscriptionInfo subInfo, String packageName) {
        if (Flags.hsumPackageManager() && UserManager.isHeadlessSystemUserMode()) {
            return mSubscriptionManager.canManageSubscriptionAsUser(subInfo, packageName,
                    UserHandle.of(ActivityManager.getCurrentUser()));
        } else {
            return mSubscriptionManager.canManageSubscription(subInfo, packageName);
        }
    }

    /**
     * Log debug messages.
     *
+12 −0
Original line number Diff line number Diff line
@@ -1906,6 +1906,8 @@ public class EuiccControllerTest extends TelephonyTest {

        when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn(
                hasPrivileges);
        when(mSubscriptionManager.canManageSubscriptionAsUser(eq(subInfo), eq(PACKAGE_NAME), any()))
                .thenReturn(hasPrivileges);
        when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(
                Collections.singletonList(subInfo));
    }
@@ -1943,8 +1945,12 @@ public class EuiccControllerTest extends TelephonyTest {
                .build();
        when(mSubscriptionManager.canManageSubscription(subInfo1, PACKAGE_NAME)).thenReturn(
                hasPrivileges);
        when(mSubscriptionManager.canManageSubscriptionAsUser(eq(subInfo1), eq(PACKAGE_NAME),
                any())).thenReturn(hasPrivileges);
        when(mSubscriptionManager.canManageSubscription(subInfo2, PACKAGE_NAME)).thenReturn(
                hasPrivileges);
        when(mSubscriptionManager.canManageSubscriptionAsUser(eq(subInfo2), eq(PACKAGE_NAME),
                any())).thenReturn(hasPrivileges);
        ArrayList<SubscriptionInfo> subInfos = new ArrayList<>(Arrays.asList(subInfo1, subInfo2));
        when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(subInfos);
    }
@@ -1963,8 +1969,12 @@ public class EuiccControllerTest extends TelephonyTest {
                .build();
        when(mSubscriptionManager.canManageSubscription(subInfo1, PACKAGE_NAME)).thenReturn(
                false);
        when(mSubscriptionManager.canManageSubscriptionAsUser(eq(subInfo1), eq(PACKAGE_NAME),
                any())).thenReturn(false);
        when(mSubscriptionManager.canManageSubscription(subInfo2, PACKAGE_NAME)).thenReturn(
                true);
        when(mSubscriptionManager.canManageSubscriptionAsUser(eq(subInfo2), eq(PACKAGE_NAME),
                any())).thenReturn(true);
        ArrayList<SubscriptionInfo> subInfos = new ArrayList<>(Arrays.asList(subInfo1, subInfo2));
        when(mSubscriptionManager.getActiveSubscriptionInfoList(anyBoolean())).thenReturn(subInfos);
    }
@@ -1979,6 +1989,8 @@ public class EuiccControllerTest extends TelephonyTest {
                .build();
        when(mSubscriptionManager.canManageSubscription(subInfo, PACKAGE_NAME)).thenReturn(
                hasPrivileges);
        when(mSubscriptionManager.canManageSubscriptionAsUser(eq(subInfo), eq(PACKAGE_NAME), any()))
                .thenReturn(hasPrivileges);
        when(mSubscriptionManager.getAvailableSubscriptionInfoList()).thenReturn(
                Collections.singletonList(subInfo));
    }