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