Merge changes from topics "ENFORCE_SUBSCRIPTION_USER_ASSOCIATION", "sim_state_string"

* changes:
  Add subscription-user association check.
  Moved SimStateToString to TelephonyManager
This commit is contained in:
Treehugger Robot
2023-03-24 17:27:13 +00:00
committed by Gerrit Code Review
6 changed files with 184 additions and 0 deletions

View File

@@ -45,6 +45,7 @@ import android.telephony.TelephonyManager;
import android.util.Slog; import android.util.Slog;
import com.android.internal.telephony.IMms; import com.android.internal.telephony.IMms;
import com.android.internal.telephony.TelephonyPermissions;
import com.android.server.uri.NeededUriGrants; import com.android.server.uri.NeededUriGrants;
import com.android.server.uri.UriGrantsManagerInternal; import com.android.server.uri.UriGrantsManagerInternal;
@@ -337,6 +338,14 @@ public class MmsServiceBroker extends SystemService {
throws RemoteException { throws RemoteException {
Slog.d(TAG, "sendMessage() by " + callingPkg); Slog.d(TAG, "sendMessage() by " + callingPkg);
mContext.enforceCallingPermission(Manifest.permission.SEND_SMS, "Send MMS message"); 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(), if (getAppOpsManager().noteOp(AppOpsManager.OP_SEND_SMS, Binder.getCallingUid(),
callingPkg, attributionTag, null) != AppOpsManager.MODE_ALLOWED) { callingPkg, attributionTag, null) != AppOpsManager.MODE_ALLOWED) {
Slog.e(TAG, callingPkg + " is not allowed to call sendMessage()"); Slog.e(TAG, callingPkg + " is not allowed to call sendMessage()");

View File

@@ -18,6 +18,7 @@ package com.android.internal.telephony;
import static android.content.pm.PackageManager.PERMISSION_GRANTED; import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import android.Manifest; import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.app.AppOpsManager; import android.app.AppOpsManager;
import android.content.Context; import android.content.Context;
@@ -822,4 +823,35 @@ public final class TelephonyPermissions {
} }
return Integer.MAX_VALUE; 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;
}
} }

View File

@@ -2245,6 +2245,7 @@ public final class SmsManager {
RESULT_SMS_SEND_RETRY_FAILED, RESULT_SMS_SEND_RETRY_FAILED,
RESULT_REMOTE_EXCEPTION, RESULT_REMOTE_EXCEPTION,
RESULT_NO_DEFAULT_SMS_APP, RESULT_NO_DEFAULT_SMS_APP,
RESULT_USER_NOT_ALLOWED,
RESULT_RIL_RADIO_NOT_AVAILABLE, RESULT_RIL_RADIO_NOT_AVAILABLE,
RESULT_RIL_SMS_SEND_FAIL_RETRY, RESULT_RIL_SMS_SEND_FAIL_RETRY,
RESULT_RIL_NETWORK_REJECT, RESULT_RIL_NETWORK_REJECT,
@@ -2425,6 +2426,13 @@ public final class SmsManager {
*/ */
public static final int RESULT_NO_DEFAULT_SMS_APP = 32; 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 // Radio Error results
/** /**

View File

@@ -4394,5 +4394,70 @@ public class SubscriptionManager {
} }
return null; 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<>();
}
} }

View File

@@ -17027,4 +17027,44 @@ public class TelephonyManager {
} }
return TelephonyManager.SIM_STATE_UNKNOWN; return TelephonyManager.SIM_STATE_UNKNOWN;
} }
/**
* Convert SIM state into string.
*
* @param state SIM state.
* @return SIM state in string format.
*
* @hide
*/
@NonNull
public static String simStateToString(@SimState int state) {
switch (state) {
case TelephonyManager.SIM_STATE_UNKNOWN:
return "UNKNOWN";
case TelephonyManager.SIM_STATE_ABSENT:
return "ABSENT";
case TelephonyManager.SIM_STATE_PIN_REQUIRED:
return "PIN_REQUIRED";
case TelephonyManager.SIM_STATE_PUK_REQUIRED:
return "PUK_REQUIRED";
case TelephonyManager.SIM_STATE_NETWORK_LOCKED:
return "NETWORK_LOCKED";
case TelephonyManager.SIM_STATE_READY:
return "READY";
case TelephonyManager.SIM_STATE_NOT_READY:
return "NOT_READY";
case TelephonyManager.SIM_STATE_PERM_DISABLED:
return "PERM_DISABLED";
case TelephonyManager.SIM_STATE_CARD_IO_ERROR:
return "CARD_IO_ERROR";
case TelephonyManager.SIM_STATE_CARD_RESTRICTED:
return "CARD_RESTRICTED";
case TelephonyManager.SIM_STATE_LOADED:
return "LOADED";
case TelephonyManager.SIM_STATE_PRESENT:
return "PRESENT";
default:
return "UNKNOWN(" + state + ")";
}
}
} }

View File

@@ -326,4 +326,34 @@ interface ISub {
* @throws IllegalArgumentException if subId is invalid. * @throws IllegalArgumentException if subId is invalid.
*/ */
UserHandle getSubscriptionUserHandle(int subId); 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);
} }