• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2011 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 
17 package com.android.cellbroadcastreceiver;
18 
19 import static com.android.cellbroadcastreceiver.CellBroadcastReceiver.VDBG;
20 
21 import android.app.IntentService;
22 import android.content.Intent;
23 import android.content.SharedPreferences;
24 import android.content.res.Resources;
25 import android.preference.PreferenceManager;
26 import android.telephony.CarrierConfigManager;
27 import android.telephony.SmsManager;
28 import android.telephony.SubscriptionManager;
29 import android.util.Log;
30 
31 import com.android.cellbroadcastreceiver.CellBroadcastAlertService.AlertType;
32 import com.android.cellbroadcastreceiver.CellBroadcastChannelManager.CellBroadcastChannelRange;
33 import com.android.internal.annotations.VisibleForTesting;
34 import com.android.internal.telephony.cdma.sms.SmsEnvelope;
35 import com.android.internal.telephony.gsm.SmsCbConstants;
36 
37 import java.util.ArrayList;
38 
39 /**
40  * This service manages enabling and disabling ranges of message identifiers
41  * that the radio should listen for. It operates independently of the other
42  * services and runs at boot time and after exiting airplane mode.
43  *
44  * Note that the entire range of emergency channels is enabled. Test messages
45  * and lower priority broadcasts are filtered out in CellBroadcastAlertService
46  * if the user has not enabled them in settings.
47  *
48  * TODO: add notification to re-enable channels after a radio reset.
49  */
50 public class CellBroadcastConfigService extends IntentService {
51     private static final String TAG = "CellBroadcastConfigService";
52 
53     static final String ACTION_ENABLE_CHANNELS = "ACTION_ENABLE_CHANNELS";
54 
CellBroadcastConfigService()55     public CellBroadcastConfigService() {
56         super(TAG);          // use class name for worker thread name
57     }
58 
59     @Override
onHandleIntent(Intent intent)60     protected void onHandleIntent(Intent intent) {
61         if (ACTION_ENABLE_CHANNELS.equals(intent.getAction())) {
62             try {
63 
64                 SubscriptionManager subManager = SubscriptionManager.from(getApplicationContext());
65                 int subId = SubscriptionManager.getDefaultSmsSubscriptionId();
66                 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
67                     subId = SubscriptionManager.getDefaultSubscriptionId();
68                     if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID &&
69                             subManager != null) {
70                         int [] subIds = subManager.getActiveSubscriptionIdList();
71                         if (subIds.length != 0) {
72                             subId = subIds[0];
73                         }
74                     }
75                 }
76 
77                 if (subManager != null) {
78                     // Retrieve all the active sub ids. We only want to enable
79                     // cell broadcast on the sub we are interested in and we'll disable
80                     // it on other subs so the users will not receive duplicate messages from
81                     // multiple carriers (e.g. for multi-sim users).
82                     int [] subIds = subManager.getActiveSubscriptionIdList();
83                     if (subIds.length != 0)
84                     {
85                         for (int id : subIds) {
86                             SmsManager manager = SmsManager.getSmsManagerForSubscriptionId(id);
87                             if (manager != null) {
88                                 if (id == subId) {
89                                     // Enable cell broadcast messages on this sub.
90                                     log("Enable CellBroadcast on sub " + id);
91                                     setCellBroadcastOnSub(manager, true);
92                                 }
93                                 else {
94                                     // Disable all cell broadcast message on this sub.
95                                     // This is only for multi-sim scenario. For single SIM device
96                                     // we should not reach here.
97                                     log("Disable CellBroadcast on sub " + id);
98                                     setCellBroadcastOnSub(manager, false);
99                                 }
100                             }
101                         }
102                     }
103                     else {
104                         // For no sim scenario.
105                         SmsManager manager = SmsManager.getDefault();
106                         if (manager != null) {
107                             setCellBroadcastOnSub(manager, true);
108                         }
109                     }
110                 }
111             } catch (Exception ex) {
112                 Log.e(TAG, "exception enabling cell broadcast channels", ex);
113             }
114         }
115     }
116 
117     /**
118      * Enable/disable cell broadcast messages id on one subscription
119      * This includes all ETWS and CMAS alerts.
120      * @param manager SMS manager
121      * @param enableForSub True if want to enable messages on this sub (e.g default SMS). False
122      *                     will disable all messages
123      */
124     @VisibleForTesting
setCellBroadcastOnSub(SmsManager manager, boolean enableForSub)125     public void setCellBroadcastOnSub(SmsManager manager, boolean enableForSub) {
126 
127         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
128 
129         // boolean for each user preference checkbox, true for checked, false for unchecked
130         // Note: If enableEmergencyAlerts is false, it disables ALL emergency broadcasts
131         // except for CMAS presidential. i.e. to receive CMAS severe alerts, both
132         // enableEmergencyAlerts AND enableCmasSevereAlerts must be true.
133         boolean enableEmergencyAlerts = enableForSub && prefs.getBoolean(
134                 CellBroadcastSettings.KEY_ENABLE_EMERGENCY_ALERTS, true);
135 
136         boolean enableEtwsAlerts = enableEmergencyAlerts;
137 
138         // CMAS Presidential must be always on (See 3GPP TS 22.268 Section 6.2) regardless
139         // user's preference
140         boolean enablePresidential = enableForSub;
141 
142         boolean enableCmasExtremeAlerts = enableEmergencyAlerts && prefs.getBoolean(
143                 CellBroadcastSettings.KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS, true);
144 
145         boolean enableCmasSevereAlerts = enableEmergencyAlerts && prefs.getBoolean(
146                 CellBroadcastSettings.KEY_ENABLE_CMAS_SEVERE_THREAT_ALERTS, true);
147 
148         boolean enableCmasAmberAlerts = enableEmergencyAlerts && prefs.getBoolean(
149                 CellBroadcastSettings.KEY_ENABLE_CMAS_AMBER_ALERTS, true);
150 
151         // Check if ETWS/CMAS test message is forced disabled on the device.
152         boolean forceDisableEtwsCmasTest =
153                 CellBroadcastSettings.isFeatureEnabled(this,
154                         CarrierConfigManager.KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false);
155 
156         boolean enableEtwsTestAlerts = !forceDisableEtwsCmasTest &&
157                 enableEmergencyAlerts &&
158                 prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_ETWS_TEST_ALERTS, false);
159 
160         boolean enableCmasTestAlerts = !forceDisableEtwsCmasTest &&
161                 enableEmergencyAlerts &&
162                 prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_CMAS_TEST_ALERTS, false);
163 
164         boolean enableAreaUpdateInfoAlerts = Resources.getSystem().getBoolean(
165                 com.android.internal.R.bool.config_showAreaUpdateInfoSettings)
166                 && prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_AREA_UPDATE_INFO_ALERTS,
167                 false);
168 
169         if (VDBG) {
170             log("enableEmergencyAlerts = " + enableEmergencyAlerts);
171             log("enableEtwsAlerts = " + enableEtwsAlerts);
172             log("enablePresidential = " + enablePresidential);
173             log("enableCmasExtremeAlerts = " + enableCmasExtremeAlerts);
174             log("enableCmasSevereAlerts = " + enableCmasExtremeAlerts);
175             log("enableCmasAmberAlerts = " + enableCmasAmberAlerts);
176             log("forceDisableEtwsCmasTest = " + forceDisableEtwsCmasTest);
177             log("enableEtwsTestAlerts = " + enableEtwsTestAlerts);
178             log("enableCmasTestAlerts = " + enableCmasTestAlerts);
179             log("enableAreaUpdateInfoAlerts = " + enableAreaUpdateInfoAlerts);
180         }
181 
182         /** Enable CDMA CMAS series messages. */
183 
184         // Enable/Disable CDMA Presidential messages.
185         setCellBroadcastRange(manager, enablePresidential,
186                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
187                 SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
188                 SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT);
189 
190         // Enable/Disable CDMA CMAS extreme messages.
191         setCellBroadcastRange(manager, enableCmasExtremeAlerts,
192                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
193                 SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
194                 SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT);
195 
196         // Enable/Disable CDMA CMAS severe messages.
197         setCellBroadcastRange(manager, enableCmasSevereAlerts,
198                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
199                 SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT,
200                 SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT);
201 
202         // Enable/Disable CDMA CMAS amber alert messages.
203         setCellBroadcastRange(manager, enableCmasAmberAlerts,
204                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
205                 SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
206                 SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY);
207 
208         // Enable/Disable CDMA CMAS test messages.
209         setCellBroadcastRange(manager, enableCmasTestAlerts,
210                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
211                 SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE,
212                 SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
213 
214         // Enable GSM ETWS series messages.
215 
216         // Enable/Disable GSM ETWS messages (4352~4354).
217         setCellBroadcastRange(manager, enableEtwsAlerts,
218                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
219                 SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING,
220                 SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_AND_TSUNAMI_WARNING);
221 
222         // Enable/Disable GSM ETWS messages (4356)
223         setCellBroadcastRange(manager, enableEtwsAlerts,
224                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
225                 SmsCbConstants.MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE,
226                 SmsCbConstants.MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE);
227 
228         // Enable/Disable GSM ETWS test messages (4355).
229         setCellBroadcastRange(manager, enableEtwsTestAlerts,
230                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
231                 SmsCbConstants.MESSAGE_ID_ETWS_TEST_MESSAGE,
232                 SmsCbConstants.MESSAGE_ID_ETWS_TEST_MESSAGE);
233 
234         // Enable GSM CMAS series messages.
235 
236         // Enable/Disable GSM CMAS presidential message (4370).
237         setCellBroadcastRange(manager, enablePresidential,
238                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
239                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL,
240                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL);
241 
242         // Enable/Disable GSM CMAS extreme messages (4371~4372).
243         setCellBroadcastRange(manager, enableCmasExtremeAlerts,
244                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
245                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED,
246                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY);
247 
248         // Enable/Disable GSM CMAS severe messages (4373~4378).
249         setCellBroadcastRange(manager, enableCmasSevereAlerts,
250                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
251                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED,
252                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY);
253 
254         // Enable/Disable GSM CMAS amber alert messages (4379).
255         setCellBroadcastRange(manager, enableCmasAmberAlerts,
256                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
257                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY,
258                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY);
259 
260         // Enable/Disable GSM CMAS test messages (4380~4382).
261         setCellBroadcastRange(manager, enableCmasTestAlerts,
262                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
263                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST,
264                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE);
265 
266 
267         // Enable GSM CMAS series messages for additional languages.
268 
269         // Enable/Disable GSM CMAS presidential messages for additional languages (4383).
270         setCellBroadcastRange(manager, enablePresidential,
271                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
272                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE,
273                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE);
274 
275         // Enable/Disable GSM CMAS extreme messages for additional languages (4384~4385).
276         setCellBroadcastRange(manager, enableCmasExtremeAlerts,
277                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
278                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE,
279                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE);
280 
281         // Enable/Disable GSM CMAS severe messages for additional languages (4386~4391).
282         setCellBroadcastRange(manager, enableCmasSevereAlerts,
283                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
284                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE,
285                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE);
286 
287         // Enable/Disable GSM CMAS amber alert messages for additional languages (4392).
288         setCellBroadcastRange(manager, enableCmasAmberAlerts,
289                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
290                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE,
291                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE);
292 
293         // Enable/Disable GSM CMAS test messages for additional languages (4393~4395).
294         setCellBroadcastRange(manager, enableCmasTestAlerts,
295                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
296                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST_LANGUAGE,
297                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE_LANGUAGE);
298 
299         // Enable/Disable additional channels based on carrier specific requirement.
300         ArrayList<CellBroadcastChannelRange> ranges = CellBroadcastChannelManager
301                 .getInstance().getCellBroadcastChannelRanges(this);
302 
303         if (ranges != null) {
304             for (CellBroadcastChannelRange range: ranges) {
305                 if (range.mAlertType == AlertType.AREA && !enableAreaUpdateInfoAlerts) {
306                     // Skip area update info channels if it's not enabled.
307                     continue;
308                 }
309                 setCellBroadcastRange(manager, enableEmergencyAlerts,
310                         SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
311                         range.mStartId, range.mEndId);
312             }
313         }
314     }
315     /**
316      * Enable/disable cell broadcast with messages id range
317      * @param manager SMS manager
318      * @param enable True for enabling cell broadcast with id range, otherwise for disabling.
319      * @param type GSM or CDMA
320      * @param start Cell broadcast id range start
321      * @param end Cell broadcast id range end
322      */
setCellBroadcastRange( SmsManager manager, boolean enable, int type, int start, int end)323     private boolean setCellBroadcastRange(
324             SmsManager manager, boolean enable, int type, int start, int end) {
325         if (enable) {
326             return manager.enableCellBroadcastRange(start, end, type);
327         } else {
328             return manager.disableCellBroadcastRange(start, end, type);
329         }
330     }
331 
log(String msg)332     private static void log(String msg) {
333         Log.d(TAG, msg);
334     }
335 }
336