Loading api/system-current.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -8488,7 +8488,7 @@ package android.telephony { } } public class CellBroadcastIntents { public class CellBroadcastIntents { method public static void sendOrderedBroadcastForBackgroundReceivers(@NonNull android.content.Context, @Nullable android.os.UserHandle, @NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method public static void sendSmsCbReceivedBroadcast(@NonNull android.content.Context, @Nullable android.os.UserHandle, @NonNull android.telephony.SmsCbMessage, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, int); } } public abstract class CellBroadcastService extends android.app.Service { public abstract class CellBroadcastService extends android.app.Service { core/java/android/telephony/CellBroadcastIntents.java +56 −32 Original line number Original line Diff line number Diff line Loading @@ -16,22 +16,23 @@ package android.telephony; package android.telephony; import android.Manifest; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.SystemApi; import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.os.Handler; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Telephony; /** /** * A static helper class used to send Intents with prepopulated flags. * A static helper class used to send Intents with prepopulated flags. * <p> * <p> * This is intended to be used by the CellBroadcastService and will throw a security exception if * This is intended to be used by the CellBroadcastService and does nothing if the caller does not * used from a UID besides the network stack UID. * have permission to broadcast {@link Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION}. * * * @hide * @hide */ */ Loading @@ -39,6 +40,8 @@ import android.os.UserHandle; public class CellBroadcastIntents { public class CellBroadcastIntents { private static final String LOG_TAG = "CellBroadcastIntents"; private static final String LOG_TAG = "CellBroadcastIntents"; private static final String EXTRA_MESSAGE = "message"; /** /** * @hide * @hide */ */ Loading @@ -46,50 +49,71 @@ public class CellBroadcastIntents { } } /** /** * Returns an intent which can be received by background BroadcastReceivers. This is only * Broadcasts an SMS_CB_RECEIVED_ACTION intent which can be received by background * intended to be used by the CellBroadcastService and will throw a security exception if called * BroadcastReceivers. This is only intended to be used by the CellBroadcastService and will * from another UID. * do nothing if the caller does not have permission to broadcast * {@link Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION}. * * * @param context The context from which to send the broadcast * @param context The context from which to send the broadcast * @param user The user from which to send the broadcast * @param user The user from which to send the broadcast * @param intent The Intent to broadcast; all receivers matching this Intent will * @param smsCbMessage The SmsCbMessage to include with the intent * receive the broadcast. * @param receiverPermission String naming a permissions that a receiver must hold in order to * receive your broadcast. If null, no permission is required. * @param receiverAppOp The app op associated with the broadcast. If null, no appOp is * required. If both receiverAppOp and receiverPermission are * non-null, a receiver must have both of them to receive the * broadcast * @param resultReceiver Your own BroadcastReceiver to treat as the final receiver of the * @param resultReceiver Your own BroadcastReceiver to treat as the final receiver of the * broadcast. * broadcast. * @param scheduler A custom Handler with which to schedule the resultReceiver * @param scheduler A custom Handler with which to schedule the resultReceiver * callback; if null it will be scheduled in the Context's main * callback; if null it will be scheduled in the Context's main * thread. * thread. * @param initialCode An initial value for the result code. Often Activity.RESULT_OK. * @param initialCode An initial value for the result code. Often Activity.RESULT_OK. * @param initialData An initial value for the result data. Often null. * @param slotIndex The slot index to include in the intent * @param initialExtras An initial value for the result extras. Often null. */ */ public static void sendOrderedBroadcastForBackgroundReceivers(@NonNull Context context, public static void sendSmsCbReceivedBroadcast(@NonNull Context context, @Nullable UserHandle user, @NonNull Intent intent, @Nullable String receiverPermission, @Nullable UserHandle user, @NonNull SmsCbMessage smsCbMessage, @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver, @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, int initialCode, int slotIndex) { @Nullable Bundle initialExtras) { Intent backgroundIntent = new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION); int status = context.checkCallingOrSelfPermission( backgroundIntent.putExtra(EXTRA_MESSAGE, smsCbMessage); "android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS"); if (status == PackageManager.PERMISSION_DENIED) { throw new SecurityException( "Caller does not have permission to send broadcast for background receivers"); } Intent backgroundIntent = new Intent(intent); backgroundIntent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); backgroundIntent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); putPhoneIdAndSubIdExtra(context, backgroundIntent, slotIndex); String receiverPermission = Manifest.permission.RECEIVE_SMS; String receiverAppOp = AppOpsManager.OPSTR_RECEIVE_SMS; if (user != null) { if (user != null) { context.createContextAsUser(user, 0).sendOrderedBroadcast(backgroundIntent, context.createContextAsUser(user, 0).sendOrderedBroadcast(backgroundIntent, receiverPermission, receiverAppOp, resultReceiver, scheduler, initialCode, receiverPermission, receiverAppOp, resultReceiver, scheduler, initialCode, initialData, initialExtras); null, null); } else { } else { context.sendOrderedBroadcast(backgroundIntent, receiverPermission, context.sendOrderedBroadcast(backgroundIntent, receiverPermission, receiverAppOp, resultReceiver, scheduler, initialCode, initialData, receiverAppOp, resultReceiver, scheduler, initialCode, null, null); initialExtras); } } /** * Put the phone ID and sub ID into an intent as extras. */ private static void putPhoneIdAndSubIdExtra(Context context, Intent intent, int phoneId) { int subId = getSubIdForPhone(context, phoneId); if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { intent.putExtra("subscription", subId); intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); } intent.putExtra("phone", phoneId); intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId); } /** * Get the subscription ID for a phone ID, or INVALID_SUBSCRIPTION_ID if the phone does not * have an active sub * @param phoneId the phoneId to use * @return the associated sub id */ private static int getSubIdForPhone(Context context, int phoneId) { SubscriptionManager subMan = (SubscriptionManager) context.getSystemService( Context.TELEPHONY_SUBSCRIPTION_SERVICE); int[] subIds = subMan.getSubscriptionIds(phoneId); if (subIds != null) { return subIds[0]; } else { return SubscriptionManager.INVALID_SUBSCRIPTION_ID; } } } } } } Loading
api/system-current.txt +1 −1 Original line number Original line Diff line number Diff line Loading @@ -8488,7 +8488,7 @@ package android.telephony { } } public class CellBroadcastIntents { public class CellBroadcastIntents { method public static void sendOrderedBroadcastForBackgroundReceivers(@NonNull android.content.Context, @Nullable android.os.UserHandle, @NonNull android.content.Intent, @Nullable String, @Nullable String, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, @Nullable String, @Nullable android.os.Bundle); method public static void sendSmsCbReceivedBroadcast(@NonNull android.content.Context, @Nullable android.os.UserHandle, @NonNull android.telephony.SmsCbMessage, @Nullable android.content.BroadcastReceiver, @Nullable android.os.Handler, int, int); } } public abstract class CellBroadcastService extends android.app.Service { public abstract class CellBroadcastService extends android.app.Service {
core/java/android/telephony/CellBroadcastIntents.java +56 −32 Original line number Original line Diff line number Diff line Loading @@ -16,22 +16,23 @@ package android.telephony; package android.telephony; import android.Manifest; import android.annotation.NonNull; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.Nullable; import android.annotation.SystemApi; import android.annotation.SystemApi; import android.app.AppOpsManager; import android.content.BroadcastReceiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Context; import android.content.Intent; import android.content.Intent; import android.content.pm.PackageManager; import android.os.Bundle; import android.os.Handler; import android.os.Handler; import android.os.UserHandle; import android.os.UserHandle; import android.provider.Telephony; /** /** * A static helper class used to send Intents with prepopulated flags. * A static helper class used to send Intents with prepopulated flags. * <p> * <p> * This is intended to be used by the CellBroadcastService and will throw a security exception if * This is intended to be used by the CellBroadcastService and does nothing if the caller does not * used from a UID besides the network stack UID. * have permission to broadcast {@link Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION}. * * * @hide * @hide */ */ Loading @@ -39,6 +40,8 @@ import android.os.UserHandle; public class CellBroadcastIntents { public class CellBroadcastIntents { private static final String LOG_TAG = "CellBroadcastIntents"; private static final String LOG_TAG = "CellBroadcastIntents"; private static final String EXTRA_MESSAGE = "message"; /** /** * @hide * @hide */ */ Loading @@ -46,50 +49,71 @@ public class CellBroadcastIntents { } } /** /** * Returns an intent which can be received by background BroadcastReceivers. This is only * Broadcasts an SMS_CB_RECEIVED_ACTION intent which can be received by background * intended to be used by the CellBroadcastService and will throw a security exception if called * BroadcastReceivers. This is only intended to be used by the CellBroadcastService and will * from another UID. * do nothing if the caller does not have permission to broadcast * {@link Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION}. * * * @param context The context from which to send the broadcast * @param context The context from which to send the broadcast * @param user The user from which to send the broadcast * @param user The user from which to send the broadcast * @param intent The Intent to broadcast; all receivers matching this Intent will * @param smsCbMessage The SmsCbMessage to include with the intent * receive the broadcast. * @param receiverPermission String naming a permissions that a receiver must hold in order to * receive your broadcast. If null, no permission is required. * @param receiverAppOp The app op associated with the broadcast. If null, no appOp is * required. If both receiverAppOp and receiverPermission are * non-null, a receiver must have both of them to receive the * broadcast * @param resultReceiver Your own BroadcastReceiver to treat as the final receiver of the * @param resultReceiver Your own BroadcastReceiver to treat as the final receiver of the * broadcast. * broadcast. * @param scheduler A custom Handler with which to schedule the resultReceiver * @param scheduler A custom Handler with which to schedule the resultReceiver * callback; if null it will be scheduled in the Context's main * callback; if null it will be scheduled in the Context's main * thread. * thread. * @param initialCode An initial value for the result code. Often Activity.RESULT_OK. * @param initialCode An initial value for the result code. Often Activity.RESULT_OK. * @param initialData An initial value for the result data. Often null. * @param slotIndex The slot index to include in the intent * @param initialExtras An initial value for the result extras. Often null. */ */ public static void sendOrderedBroadcastForBackgroundReceivers(@NonNull Context context, public static void sendSmsCbReceivedBroadcast(@NonNull Context context, @Nullable UserHandle user, @NonNull Intent intent, @Nullable String receiverPermission, @Nullable UserHandle user, @NonNull SmsCbMessage smsCbMessage, @Nullable String receiverAppOp, @Nullable BroadcastReceiver resultReceiver, @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler, @Nullable Handler scheduler, int initialCode, @Nullable String initialData, int initialCode, int slotIndex) { @Nullable Bundle initialExtras) { Intent backgroundIntent = new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION); int status = context.checkCallingOrSelfPermission( backgroundIntent.putExtra(EXTRA_MESSAGE, smsCbMessage); "android.permission.GRANT_RUNTIME_PERMISSIONS_TO_TELEPHONY_DEFAULTS"); if (status == PackageManager.PERMISSION_DENIED) { throw new SecurityException( "Caller does not have permission to send broadcast for background receivers"); } Intent backgroundIntent = new Intent(intent); backgroundIntent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); backgroundIntent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND); putPhoneIdAndSubIdExtra(context, backgroundIntent, slotIndex); String receiverPermission = Manifest.permission.RECEIVE_SMS; String receiverAppOp = AppOpsManager.OPSTR_RECEIVE_SMS; if (user != null) { if (user != null) { context.createContextAsUser(user, 0).sendOrderedBroadcast(backgroundIntent, context.createContextAsUser(user, 0).sendOrderedBroadcast(backgroundIntent, receiverPermission, receiverAppOp, resultReceiver, scheduler, initialCode, receiverPermission, receiverAppOp, resultReceiver, scheduler, initialCode, initialData, initialExtras); null, null); } else { } else { context.sendOrderedBroadcast(backgroundIntent, receiverPermission, context.sendOrderedBroadcast(backgroundIntent, receiverPermission, receiverAppOp, resultReceiver, scheduler, initialCode, initialData, receiverAppOp, resultReceiver, scheduler, initialCode, null, null); initialExtras); } } /** * Put the phone ID and sub ID into an intent as extras. */ private static void putPhoneIdAndSubIdExtra(Context context, Intent intent, int phoneId) { int subId = getSubIdForPhone(context, phoneId); if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) { intent.putExtra("subscription", subId); intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId); } intent.putExtra("phone", phoneId); intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId); } /** * Get the subscription ID for a phone ID, or INVALID_SUBSCRIPTION_ID if the phone does not * have an active sub * @param phoneId the phoneId to use * @return the associated sub id */ private static int getSubIdForPhone(Context context, int phoneId) { SubscriptionManager subMan = (SubscriptionManager) context.getSystemService( Context.TELEPHONY_SUBSCRIPTION_SERVICE); int[] subIds = subMan.getSubscriptionIds(phoneId); if (subIds != null) { return subIds[0]; } else { return SubscriptionManager.INVALID_SUBSCRIPTION_ID; } } } } } }