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