blob: 2e0810835a52bdaf5381d84081222190e353aa5d [file] [log] [blame]
Jordan Liu45c0d542019-11-22 11:00:05 -08001/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.telephony;
18
Jordan Liu2bc01a82020-01-16 11:01:48 -080019import android.Manifest;
Jordan Liu45c0d542019-11-22 11:00:05 -080020import android.annotation.NonNull;
21import android.annotation.Nullable;
22import android.annotation.SystemApi;
Jordan Liu2bc01a82020-01-16 11:01:48 -080023import android.app.AppOpsManager;
Jordan Liu45c0d542019-11-22 11:00:05 -080024import android.content.BroadcastReceiver;
25import android.content.Context;
26import android.content.Intent;
Jordan Liu45c0d542019-11-22 11:00:05 -080027import android.os.Handler;
28import android.os.UserHandle;
Jordan Liu2bc01a82020-01-16 11:01:48 -080029import android.provider.Telephony;
Jordan Liu45c0d542019-11-22 11:00:05 -080030
31/**
32 * A static helper class used to send Intents with prepopulated flags.
33 * <p>
Jordan Liu2bc01a82020-01-16 11:01:48 -080034 * This is intended to be used by the CellBroadcastService and does nothing if the caller does not
35 * have permission to broadcast {@link Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION}.
Jordan Liu45c0d542019-11-22 11:00:05 -080036 *
37 * @hide
38 */
39@SystemApi
40public class CellBroadcastIntents {
41 private static final String LOG_TAG = "CellBroadcastIntents";
42
Jordan Liu2bc01a82020-01-16 11:01:48 -080043 private static final String EXTRA_MESSAGE = "message";
44
Jordan Liu45c0d542019-11-22 11:00:05 -080045 /**
46 * @hide
47 */
48 private CellBroadcastIntents() {
49 }
50
51 /**
Jordan Liu2bc01a82020-01-16 11:01:48 -080052 * Broadcasts an SMS_CB_RECEIVED_ACTION intent which can be received by background
53 * BroadcastReceivers. This is only intended to be used by the CellBroadcastService and will
54 * do nothing if the caller does not have permission to broadcast
55 * {@link Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION}.
Jordan Liu45c0d542019-11-22 11:00:05 -080056 *
57 * @param context The context from which to send the broadcast
58 * @param user The user from which to send the broadcast
Jordan Liu2bc01a82020-01-16 11:01:48 -080059 * @param smsCbMessage The SmsCbMessage to include with the intent
Jordan Liu45c0d542019-11-22 11:00:05 -080060 * @param resultReceiver Your own BroadcastReceiver to treat as the final receiver of the
61 * broadcast.
62 * @param scheduler A custom Handler with which to schedule the resultReceiver
63 * callback; if null it will be scheduled in the Context's main
64 * thread.
65 * @param initialCode An initial value for the result code. Often Activity.RESULT_OK.
Jordan Liu2bc01a82020-01-16 11:01:48 -080066 * @param slotIndex The slot index to include in the intent
Jordan Liu45c0d542019-11-22 11:00:05 -080067 */
Jordan Liu2bc01a82020-01-16 11:01:48 -080068 public static void sendSmsCbReceivedBroadcast(@NonNull Context context,
69 @Nullable UserHandle user, @NonNull SmsCbMessage smsCbMessage,
70 @Nullable BroadcastReceiver resultReceiver, @Nullable Handler scheduler,
71 int initialCode, int slotIndex) {
72 Intent backgroundIntent = new Intent(Telephony.Sms.Intents.SMS_CB_RECEIVED_ACTION);
73 backgroundIntent.putExtra(EXTRA_MESSAGE, smsCbMessage);
Jordan Liue1b7ab12019-12-09 13:45:07 -080074 backgroundIntent.setFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
Jordan Liu2bc01a82020-01-16 11:01:48 -080075 putPhoneIdAndSubIdExtra(context, backgroundIntent, slotIndex);
76
77 String receiverPermission = Manifest.permission.RECEIVE_SMS;
78 String receiverAppOp = AppOpsManager.OPSTR_RECEIVE_SMS;
Jordan Liu45c0d542019-11-22 11:00:05 -080079 if (user != null) {
Jordan Liue1b7ab12019-12-09 13:45:07 -080080 context.createContextAsUser(user, 0).sendOrderedBroadcast(backgroundIntent,
81 receiverPermission, receiverAppOp, resultReceiver, scheduler, initialCode,
Jordan Liu2bc01a82020-01-16 11:01:48 -080082 null, null);
Jordan Liu45c0d542019-11-22 11:00:05 -080083 } else {
Jordan Liue1b7ab12019-12-09 13:45:07 -080084 context.sendOrderedBroadcast(backgroundIntent, receiverPermission,
Jordan Liu2bc01a82020-01-16 11:01:48 -080085 receiverAppOp, resultReceiver, scheduler, initialCode, null, null);
86 }
87 }
88
89 /**
90 * Put the phone ID and sub ID into an intent as extras.
91 */
92 private static void putPhoneIdAndSubIdExtra(Context context, Intent intent, int phoneId) {
93 int subId = getSubIdForPhone(context, phoneId);
94 if (subId != SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
95 intent.putExtra("subscription", subId);
96 intent.putExtra(SubscriptionManager.EXTRA_SUBSCRIPTION_INDEX, subId);
97 }
98 intent.putExtra("phone", phoneId);
99 intent.putExtra(SubscriptionManager.EXTRA_SLOT_INDEX, phoneId);
100 }
101
102 /**
103 * Get the subscription ID for a phone ID, or INVALID_SUBSCRIPTION_ID if the phone does not
104 * have an active sub
105 * @param phoneId the phoneId to use
106 * @return the associated sub id
107 */
108 private static int getSubIdForPhone(Context context, int phoneId) {
109 SubscriptionManager subMan =
110 (SubscriptionManager) context.getSystemService(
111 Context.TELEPHONY_SUBSCRIPTION_SERVICE);
112 int[] subIds = subMan.getSubscriptionIds(phoneId);
113 if (subIds != null) {
114 return subIds[0];
115 } else {
116 return SubscriptionManager.INVALID_SUBSCRIPTION_ID;
Jordan Liu45c0d542019-11-22 11:00:05 -0800117 }
118 }
119}