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 android.app.IntentService;
20 import android.content.Context;
21 import android.content.Intent;
22 import android.content.SharedPreferences;
23 import android.content.res.Resources;
24 import android.preference.PreferenceManager;
25 import android.telephony.CarrierConfigManager;
26 import android.telephony.SmsManager;
27 import android.telephony.SubscriptionManager;
28 import android.telephony.TelephonyManager;
29 import android.util.Log;
30 
31 import com.android.cellbroadcastreceiver.CellBroadcastOtherChannelsManager.CellBroadcastChannelRange;
32 import com.android.internal.telephony.cdma.sms.SmsEnvelope;
33 import com.android.internal.telephony.gsm.SmsCbConstants;
34 
35 import java.util.ArrayList;
36 
37 import static com.android.cellbroadcastreceiver.CellBroadcastReceiver.VDBG;
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 
55     private static final String COUNTRY_TAIWAN = "tw";
56     private static final String COUNTRY_ISRAEL = "ir";
57     private static final String COUNTRY_BRAZIL = "br";
58 
CellBroadcastConfigService()59     public CellBroadcastConfigService() {
60         super(TAG);          // use class name for worker thread name
61     }
62 
63     @Override
onHandleIntent(Intent intent)64     protected void onHandleIntent(Intent intent) {
65         if (ACTION_ENABLE_CHANNELS.equals(intent.getAction())) {
66             try {
67 
68                 SubscriptionManager subManager = SubscriptionManager.from(getApplicationContext());
69                 int subId = SubscriptionManager.getDefaultSmsSubscriptionId();
70                 if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
71                     subId = SubscriptionManager.getDefaultSubscriptionId();
72                     if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID &&
73                             subManager != null) {
74                         int [] subIds = subManager.getActiveSubscriptionIdList();
75                         if (subIds.length != 0) {
76                             subId = subIds[0];
77                         }
78                     }
79                 }
80 
81                 if (subManager != null) {
82                     // Retrieve all the active sub ids. We only want to enable
83                     // cell broadcast on the sub we are interested in and we'll disable
84                     // it on other subs so the users will not receive duplicate messages from
85                     // multiple carriers (e.g. for multi-sim users).
86                     int [] subIds = subManager.getActiveSubscriptionIdList();
87                     if (subIds.length != 0)
88                     {
89                         for (int id : subIds) {
90                             SmsManager manager = SmsManager.getSmsManagerForSubscriptionId(id);
91                             if (manager != null) {
92                                 if (id == subId) {
93                                     // Enable cell broadcast messages on this sub.
94                                     log("Enable CellBroadcast on sub " + id);
95                                     setCellBroadcastOnSub(manager, id, true);
96                                 }
97                                 else {
98                                     // Disable all cell broadcast message on this sub.
99                                     // This is only for multi-sim scenario. For single SIM device
100                                     // we should not reach here.
101                                     log("Disable CellBroadcast on sub " + id);
102                                     setCellBroadcastOnSub(manager, id, false);
103                                 }
104                             }
105                         }
106                     }
107                     else {
108                         // For no sim scenario.
109                         SmsManager manager = SmsManager.getDefault();
110                         if (manager != null) {
111                             setCellBroadcastOnSub(manager,
112                                     SubscriptionManager.INVALID_SUBSCRIPTION_ID, true);
113                         }
114                     }
115                 }
116             } catch (Exception ex) {
117                 Log.e(TAG, "exception enabling cell broadcast channels", ex);
118             }
119         }
120     }
121 
122     /**
123      * Enable/disable cell broadcast messages id on one subscription
124      * This includes all ETWS and CMAS alerts.
125      * @param manager SMS manager
126      * @param subId Subscription id
127      * @param enableForSub True if want to enable messages on this sub (e.g default SMS). False
128      *                     will disable all messages
129      */
setCellBroadcastOnSub(SmsManager manager, int subId, boolean enableForSub)130     private void setCellBroadcastOnSub(SmsManager manager, int subId, boolean enableForSub) {
131 
132         SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
133         Resources res = getResources();
134 
135         // boolean for each user preference checkbox, true for checked, false for unchecked
136         // Note: If enableEmergencyAlerts is false, it disables ALL emergency broadcasts
137         // except for CMAS presidential. i.e. to receive CMAS severe alerts, both
138         // enableEmergencyAlerts AND enableCmasSevereAlerts must be true.
139         boolean enableEmergencyAlerts = enableForSub && prefs.getBoolean(
140                 CellBroadcastSettings.KEY_ENABLE_EMERGENCY_ALERTS, true);
141 
142         boolean enableEtwsAlerts = enableEmergencyAlerts;
143 
144         // CMAS Presidential must be always on (See 3GPP TS 22.268 Section 6.2) regardless
145         // user's preference
146         boolean enablePresidential = enableForSub;
147 
148         boolean enableCmasExtremeAlerts = enableEmergencyAlerts && prefs.getBoolean(
149                 CellBroadcastSettings.KEY_ENABLE_CMAS_EXTREME_THREAT_ALERTS, true);
150 
151         boolean enableCmasSevereAlerts = enableEmergencyAlerts && prefs.getBoolean(
152                 CellBroadcastSettings.KEY_ENABLE_CMAS_SEVERE_THREAT_ALERTS, true);
153 
154         boolean enableCmasAmberAlerts = enableEmergencyAlerts && prefs.getBoolean(
155                 CellBroadcastSettings.KEY_ENABLE_CMAS_AMBER_ALERTS, true);
156 
157         // Check if ETWS/CMAS test message is forced disabled on the device.
158         boolean forceDisableEtwsCmasTest =
159                 CellBroadcastSettings.isFeatureEnabled(this,
160                         CarrierConfigManager.KEY_CARRIER_FORCE_DISABLE_ETWS_CMAS_TEST_BOOL, false);
161 
162         boolean enableEtwsTestAlerts = !forceDisableEtwsCmasTest &&
163                 enableEmergencyAlerts &&
164                 prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_ETWS_TEST_ALERTS, false);
165 
166         boolean enableCmasTestAlerts = !forceDisableEtwsCmasTest &&
167                 enableEmergencyAlerts &&
168                 prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_CMAS_TEST_ALERTS, false);
169 
170         TelephonyManager tm = (TelephonyManager) getSystemService(
171                 Context.TELEPHONY_SERVICE);
172 
173         boolean enableChannel50Support = res.getBoolean(R.bool.show_brazil_settings) ||
174                 COUNTRY_BRAZIL.equals(tm.getSimCountryIso(subId));
175 
176         boolean enableChannel50Alerts = enableChannel50Support &&
177                 prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_CHANNEL_50_ALERTS, true);
178 
179         // Current Israel requires enable certain CMAS messages ids.
180         boolean supportIsraelPwsAlerts = (COUNTRY_ISRAEL.equals(tm.getSimCountryIso(subId))
181                 || COUNTRY_ISRAEL.equals(tm.getNetworkCountryIso(subId)));
182 
183         boolean supportTaiwanPwsAlerts = (COUNTRY_TAIWAN.equals(tm.getSimCountryIso(subId))
184                 || COUNTRY_TAIWAN.equals(tm.getNetworkCountryIso(subId)));
185 
186         if (VDBG) {
187             log("enableEmergencyAlerts = " + enableEmergencyAlerts);
188             log("enableEtwsAlerts = " + enableEtwsAlerts);
189             log("enablePresidential = " + enablePresidential);
190             log("enableCmasExtremeAlerts = " + enableCmasExtremeAlerts);
191             log("enableCmasSevereAlerts = " + enableCmasExtremeAlerts);
192             log("enableCmasAmberAlerts = " + enableCmasAmberAlerts);
193             log("forceDisableEtwsCmasTest = " + forceDisableEtwsCmasTest);
194             log("enableEtwsTestAlerts = " + enableEtwsTestAlerts);
195             log("enableCmasTestAlerts = " + enableCmasTestAlerts);
196             log("enableChannel50Alerts = " + enableChannel50Alerts);
197             log("supportIsraelPwsAlerts = " + supportIsraelPwsAlerts);
198             log("supportTaiwanPwsAlerts = " + supportTaiwanPwsAlerts);
199         }
200 
201         /** Enable CDMA CMAS series messages. */
202 
203         // Enable/Disable CDMA Presidential messages.
204         setCellBroadcastRange(manager, enablePresidential,
205                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
206                 SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT,
207                 SmsEnvelope.SERVICE_CATEGORY_CMAS_PRESIDENTIAL_LEVEL_ALERT);
208 
209         // Enable/Disable CDMA CMAS extreme messages.
210         setCellBroadcastRange(manager, enableCmasExtremeAlerts,
211                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
212                 SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT,
213                 SmsEnvelope.SERVICE_CATEGORY_CMAS_EXTREME_THREAT);
214 
215         // Enable/Disable CDMA CMAS severe messages.
216         setCellBroadcastRange(manager, enableCmasSevereAlerts,
217                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
218                 SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT,
219                 SmsEnvelope.SERVICE_CATEGORY_CMAS_SEVERE_THREAT);
220 
221         // Enable/Disable CDMA CMAS amber alert messages.
222         setCellBroadcastRange(manager, enableCmasAmberAlerts,
223                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
224                 SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY,
225                 SmsEnvelope.SERVICE_CATEGORY_CMAS_CHILD_ABDUCTION_EMERGENCY);
226 
227         // Enable/Disable CDMA CMAS test messages.
228         setCellBroadcastRange(manager, enableCmasTestAlerts,
229                 SmsManager.CELL_BROADCAST_RAN_TYPE_CDMA,
230                 SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE,
231                 SmsEnvelope.SERVICE_CATEGORY_CMAS_TEST_MESSAGE);
232 
233         /** Enable GSM ETWS series messages. */
234 
235         // Enable/Disable GSM ETWS messages (4352~4354).
236         setCellBroadcastRange(manager, enableEtwsAlerts,
237                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
238                 SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_WARNING,
239                 SmsCbConstants.MESSAGE_ID_ETWS_EARTHQUAKE_AND_TSUNAMI_WARNING);
240 
241         // Enable/Disable GSM ETWS messages (4356)
242         setCellBroadcastRange(manager, enableEtwsAlerts,
243                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
244                 SmsCbConstants.MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE,
245                 SmsCbConstants.MESSAGE_ID_ETWS_OTHER_EMERGENCY_TYPE);
246 
247         // Enable/Disable GSM ETWS test messages (4355).
248         setCellBroadcastRange(manager, enableEtwsTestAlerts,
249                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
250                 SmsCbConstants.MESSAGE_ID_ETWS_TEST_MESSAGE,
251                 SmsCbConstants.MESSAGE_ID_ETWS_TEST_MESSAGE);
252 
253         /** Enable GSM CMAS series messages. */
254 
255         // Enable/Disable GSM CMAS presidential message (4370).
256         setCellBroadcastRange(manager, enablePresidential,
257                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
258                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL,
259                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL);
260 
261         // Enable/Disable GSM CMAS extreme messages (4371~4372).
262         setCellBroadcastRange(manager, enableCmasExtremeAlerts,
263                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
264                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED,
265                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY);
266 
267         // Enable/Disable GSM CMAS severe messages (4373~4378).
268         setCellBroadcastRange(manager, enableCmasSevereAlerts,
269                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
270                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED,
271                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY);
272 
273         // Enable/Disable GSM CMAS amber alert messages (4379).
274         setCellBroadcastRange(manager, enableCmasAmberAlerts,
275                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
276                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY,
277                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY);
278 
279         // Enable/Disable GSM CMAS test messages (4380~4382).
280         setCellBroadcastRange(manager, enableCmasTestAlerts,
281                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
282                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST,
283                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE);
284 
285 
286         /** Enable GSM CMAS series messages for additional languages. */
287 
288         // Enable/Disable GSM CMAS presidential messages for additional languages (4383).
289         setCellBroadcastRange(manager, enablePresidential,
290                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
291                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE,
292                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE);
293 
294         // Enable/Disable GSM CMAS extreme messages for additional languages (4384~4385).
295         setCellBroadcastRange(manager, enableCmasExtremeAlerts,
296                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
297                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE,
298                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE);
299 
300         // Enable/Disable GSM CMAS severe messages for additional languages (4386~4391).
301         setCellBroadcastRange(manager, enableCmasSevereAlerts,
302                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
303                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE,
304                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE);
305 
306         // Enable/Disable GSM CMAS amber alert messages for additional languages (4392).
307         setCellBroadcastRange(manager, enableCmasAmberAlerts,
308                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
309                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE,
310                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE);
311 
312         // Enable/Disable GSM CMAS test messages for additional languages (4393~4395).
313         setCellBroadcastRange(manager, enableCmasTestAlerts,
314                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
315                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST_LANGUAGE,
316                 SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE_LANGUAGE);
317 
318         // Enable/Disable channel 50 messages for Brazil (50).
319         setCellBroadcastRange(manager, enableChannel50Alerts,
320                 SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
321                 SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50,
322                 SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_50);
323 
324         // Enable/Disable additional channels based on carrier specific requirement.
325         ArrayList<CellBroadcastChannelRange> ranges = CellBroadcastOtherChannelsManager.
326                 getInstance().getCellBroadcastChannelRanges(getApplicationContext(), subId);
327 
328         if (ranges != null) {
329             for (CellBroadcastChannelRange range: ranges) {
330                 setCellBroadcastRange(manager, enableEmergencyAlerts,
331                         SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
332                         range.mStartId, range.mEndId);
333             }
334         }
335 
336         // Enable/Disable additional channels based on country specific requirement.
337         if (supportIsraelPwsAlerts) {
338             // Enable/Disable Israel PWS channels (919~928).
339             setCellBroadcastRange(manager, enableEmergencyAlerts,
340                     SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
341                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_919,
342                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_928);
343         } else if (supportTaiwanPwsAlerts) {
344             // Enable/Disable Taiwan PWS Chinese channel (911).
345             setCellBroadcastRange(manager, enableEmergencyAlerts,
346                     SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
347                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_911,
348                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_911);
349 
350             // Enable/Disable Taiwan PWS English channel (919).
351             setCellBroadcastRange(manager, enableEmergencyAlerts,
352                     SmsManager.CELL_BROADCAST_RAN_TYPE_GSM,
353                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_919,
354                     SmsCbConstants.MESSAGE_ID_GSMA_ALLOCATED_CHANNEL_919);
355         }
356     }
357     /**
358      * Enable/disable cell broadcast with messages id range
359      * @param manager SMS manager
360      * @param enable True for enabling cell broadcast with id range, otherwise for disabling.
361      * @param type GSM or CDMA
362      * @param start Cell broadcast id range start
363      * @param end Cell broadcast id range end
364      */
setCellBroadcastRange( SmsManager manager, boolean enable, int type, int start, int end)365     private boolean setCellBroadcastRange(
366             SmsManager manager, boolean enable, int type, int start, int end) {
367         if (enable) {
368             return manager.enableCellBroadcastRange(start, end, type);
369         } else {
370             return manager.disableCellBroadcastRange(start, end, type);
371         }
372     }
373 
log(String msg)374     private static void log(String msg) {
375         Log.d(TAG, msg);
376     }
377 }
378