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

Commit 58910c3d authored by Aishwarya Mallampati's avatar Aishwarya Mallampati Committed by Jack Yu
Browse files

Add subscription-user association check.

Bug: 250620312
Test: Manually sending/receiving SMS/MMS,
    atest com.android.internal.telephony.SmsControllerTest,
    atest com.android.internal.telephony.SubscriptionControllerTest,
    atest CtsTelephonyTestCases
Merged-In: Ieb22f8ef2f57d15f1e72874268216ec32b7d2026
Change-Id: Ieb22f8ef2f57d15f1e72874268216ec32b7d2026
parent 53b379b7
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import android.telephony.TelephonyManager;
import android.util.Slog;

import com.android.internal.telephony.IMms;
import com.android.internal.telephony.TelephonyPermissions;
import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal;

@@ -337,6 +338,14 @@ public class MmsServiceBroker extends SystemService {
                throws RemoteException {
            Slog.d(TAG, "sendMessage() by " + callingPkg);
            mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message");

            // Check if user is associated with the subscription
            if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
                    Binder.getCallingUserHandle())) {
                // TODO(b/258629881): Display error dialog.
		return;
            }

            if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
                    callingPkg, attributionTag, null) != AppOpsManager.MODE_ALLOWED) {
                Slog.e(TAG, callingPkg + " is not allowed to call sendMessage()");
+32 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.internal.telephony;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;

import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.content.Context;
@@ -822,4 +823,35 @@ public final class TelephonyPermissions {
        }
        return Integer.MAX_VALUE;
    }

    /**
     * Check if calling user is associated with the given subscription.
     * @param context Context
     * @param subId subscription ID
     * @param callerUserHandle caller user handle
     * @return  false if user is not associated with the subscription.
     */
    public static boolean checkSubscriptionAssociatedWithUser(@NonNull Context context, int subId,
            @NonNull UserHandle callerUserHandle) {
        if (!SubscriptionManager.isValidSubscriptionId(subId)) {
            // No subscription on device, return true.
            return true;
        }

        SubscriptionManager subManager = context.getSystemService(SubscriptionManager.class);
        final long token = Binder.clearCallingIdentity();
        try {
            if ((subManager != null) &&
                    (!subManager.isSubscriptionAssociatedWithUser(subId, callerUserHandle))) {
                // If subId is not associated with calling user, return false.
                Log.e(LOG_TAG,"User[User ID:" + callerUserHandle.getIdentifier()
                        + "] is not associated with Subscription ID:" + subId);
                return false;

            }
        } finally {
            Binder.restoreCallingIdentity(token);
        }
        return true;
    }
}
+8 −0
Original line number Diff line number Diff line
@@ -2245,6 +2245,7 @@ public final class SmsManager {
            RESULT_SMS_SEND_RETRY_FAILED,
            RESULT_REMOTE_EXCEPTION,
            RESULT_NO_DEFAULT_SMS_APP,
            RESULT_USER_NOT_ALLOWED,
            RESULT_RIL_RADIO_NOT_AVAILABLE,
            RESULT_RIL_SMS_SEND_FAIL_RETRY,
            RESULT_RIL_NETWORK_REJECT,
@@ -2425,6 +2426,13 @@ public final class SmsManager {
     */
    public static final int RESULT_NO_DEFAULT_SMS_APP = 32;

    /**
     * User is not associated with the subscription.
     * TODO(b/263279115): Make this error code public.
     * @hide
     */
    public static final int RESULT_USER_NOT_ALLOWED = 33;

    // Radio Error results

    /**
+65 −0
Original line number Diff line number Diff line
@@ -4394,5 +4394,70 @@ public class SubscriptionManager {
        }
        return null;
    }

    /**
     * Check if subscription and user are associated with each other.
     *
     * @param subscriptionId the subId of the subscription
     * @param userHandle user handle of the user
     * @return {@code true} if subscription is associated with user
     * {code true} if there are no subscriptions on device
     * else {@code false} if subscription is not associated with user.
     *
     * @throws IllegalArgumentException if subscription is invalid.
     * @throws SecurityException if the caller doesn't have permissions required.
     * @throws IllegalStateException if subscription service is not available.
     *
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
    public boolean isSubscriptionAssociatedWithUser(int subscriptionId,
            @NonNull UserHandle userHandle) {
        if (!isValidSubscriptionId(subscriptionId)) {
            throw new IllegalArgumentException("[isSubscriptionAssociatedWithUser]: "
                    + "Invalid subscriptionId: " + subscriptionId);
        }

        try {
            ISub iSub = TelephonyManager.getSubscriptionService();
            if (iSub != null) {
                return iSub.isSubscriptionAssociatedWithUser(subscriptionId, userHandle);
            } else {
                throw new IllegalStateException("[isSubscriptionAssociatedWithUser]: "
                        + "subscription service unavailable");
            }
        } catch (RemoteException ex) {
            ex.rethrowAsRuntimeException();
        }
        return false;
    }

    /**
     * Get list of subscriptions associated with user.
     *
     * @param userHandle user handle of the user
     * @return list of subscriptionInfo associated with the user.
     *
     * @throws SecurityException if the caller doesn't have permissions required.
     * @throws IllegalStateException if subscription service is not available.
     *
     * @hide
     */
    @RequiresPermission(Manifest.permission.MANAGE_SUBSCRIPTION_USER_ASSOCIATION)
    public @NonNull List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(
            @NonNull UserHandle userHandle) {
        try {
            ISub iSub = TelephonyManager.getSubscriptionService();
            if (iSub != null) {
                return iSub.getSubscriptionInfoListAssociatedWithUser(userHandle);
            } else {
                throw new IllegalStateException("[getSubscriptionInfoListAssociatedWithUser]: "
                        + "subscription service unavailable");
            }
        } catch (RemoteException ex) {
            ex.rethrowAsRuntimeException();
        }
        return new ArrayList<>();
    }
}
+30 −0
Original line number Diff line number Diff line
@@ -326,4 +326,34 @@ interface ISub {
     * @throws IllegalArgumentException if subId is invalid.
     */
     UserHandle getSubscriptionUserHandle(int subId);

     /**
      * Check if subscription and user are associated with each other.
      *
      * @param subscriptionId the subId of the subscription
      * @param userHandle user handle of the user
      * @return {@code true} if subscription is associated with user
      * {code true} if there are no subscriptions on device
      * else {@code false} if subscription is not associated with user.
      *
      * @throws IllegalArgumentException if subscription is invalid.
      * @throws SecurityException if the caller doesn't have permissions required.
      * @throws IllegalStateException if subscription service is not available.
      *
      * @hide
      */
      boolean isSubscriptionAssociatedWithUser(int subscriptionId, in UserHandle userHandle);

      /**
       * Get list of subscriptions associated with user.
       *
       * @param userHandle user handle of the user
       * @return list of subscriptionInfo associated with the user.
       *
       * @throws SecurityException if the caller doesn't have permissions required.
       * @throws IllegalStateException if subscription service is not available.
       *
       * @hide
       */
       List<SubscriptionInfo> getSubscriptionInfoListAssociatedWithUser(in UserHandle userHandle);
}