CellBroadcastConfigService.java revision 8524c0a36abccf29818d6e18c1080208cfee3ec4
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 17package com.android.cellbroadcastreceiver; 18 19import android.app.IntentService; 20import android.content.Context; 21import android.content.Intent; 22import android.content.SharedPreferences; 23import android.content.res.Resources; 24import android.os.SystemProperties; 25import android.preference.PreferenceManager; 26import android.telephony.CellBroadcastMessage; 27import android.telephony.SmsManager; 28import android.telephony.TelephonyManager; 29import android.text.TextUtils; 30import android.util.Log; 31 32import com.android.internal.telephony.gsm.SmsCbConstants; 33 34import static com.android.cellbroadcastreceiver.CellBroadcastReceiver.DBG; 35 36/** 37 * This service manages enabling and disabling ranges of message identifiers 38 * that the radio should listen for. It operates independently of the other 39 * services and runs at boot time and after exiting airplane mode. 40 * 41 * Note that the entire range of emergency channels is enabled. Test messages 42 * and lower priority broadcasts are filtered out in CellBroadcastAlertService 43 * if the user has not enabled them in settings. 44 * 45 * TODO: add notification to re-enable channels after a radio reset. 46 */ 47public class CellBroadcastConfigService extends IntentService { 48 private static final String TAG = "CellBroadcastConfigService"; 49 50 static final String ACTION_ENABLE_CHANNELS = "ACTION_ENABLE_CHANNELS"; 51 52 public CellBroadcastConfigService() { 53 super(TAG); // use class name for worker thread name 54 } 55 56 private static void setChannelRange(SmsManager manager, String ranges, boolean enable) { 57 try { 58 for (String channelRange : ranges.split(",")) { 59 int dashIndex = channelRange.indexOf('-'); 60 if (dashIndex != -1) { 61 int startId = Integer.decode(channelRange.substring(0, dashIndex)); 62 int endId = Integer.decode(channelRange.substring(dashIndex + 1)); 63 if (enable) { 64 if (DBG) log("enabling emergency IDs " + startId + '-' + endId); 65 manager.enableCellBroadcastRange(startId, endId); 66 } else { 67 if (DBG) log("disabling emergency IDs " + startId + '-' + endId); 68 manager.disableCellBroadcastRange(startId, endId); 69 } 70 } else { 71 int messageId = Integer.decode(channelRange); 72 if (enable) { 73 if (DBG) log("enabling emergency message ID " + messageId); 74 manager.enableCellBroadcast(messageId); 75 } else { 76 if (DBG) log("disabling emergency message ID " + messageId); 77 manager.disableCellBroadcast(messageId); 78 } 79 } 80 } 81 } catch (NumberFormatException e) { 82 Log.e(TAG, "Number Format Exception parsing emergency channel range", e); 83 } 84 } 85 86 /** 87 * Returns true if this is a standard or operator-defined emergency alert message. 88 * This includes all ETWS and CMAS alerts, except for AMBER alerts. 89 * @param message the message to test 90 * @return true if the message is an emergency alert; false otherwise 91 */ 92 static boolean isEmergencyAlertMessage(CellBroadcastMessage message) { 93 if (message.isEmergencyAlertMessage()) { 94 return true; 95 } 96 97 // Check for system property defining the emergency channel ranges to enable 98 String emergencyIdRange = SystemProperties.get("ro.cellbroadcast.emergencyids"); 99 if (TextUtils.isEmpty(emergencyIdRange)) { 100 return false; 101 } 102 try { 103 int messageId = message.getServiceCategory(); 104 for (String channelRange : emergencyIdRange.split(",")) { 105 int dashIndex = channelRange.indexOf('-'); 106 if (dashIndex != -1) { 107 int startId = Integer.decode(channelRange.substring(0, dashIndex)); 108 int endId = Integer.decode(channelRange.substring(dashIndex + 1)); 109 if (messageId >= startId && messageId <= endId) { 110 return true; 111 } 112 } else { 113 int emergencyMessageId = Integer.decode(channelRange); 114 if (emergencyMessageId == messageId) { 115 return true; 116 } 117 } 118 } 119 } catch (NumberFormatException e) { 120 Log.e(TAG, "Number Format Exception parsing emergency channel range", e); 121 } 122 return false; 123 } 124 125 @Override 126 protected void onHandleIntent(Intent intent) { 127 if (ACTION_ENABLE_CHANNELS.equals(intent.getAction())) { 128 try { 129 SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this); 130 Resources res = getResources(); 131 132 // Check for system property defining the emergency channel ranges to enable 133 String emergencyIdRange = SystemProperties.get("ro.cellbroadcast.emergencyids"); 134 135 boolean enableEmergencyAlerts = prefs.getBoolean( 136 CellBroadcastSettings.KEY_ENABLE_EMERGENCY_ALERTS, true); 137 138 TelephonyManager tm = (TelephonyManager) getSystemService( 139 Context.TELEPHONY_SERVICE); 140 141 boolean enableChannel50Support = res.getBoolean(R.bool.show_brazil_settings) || 142 "br".equals(tm.getSimCountryIso()); 143 144 boolean enableChannel50Alerts = enableChannel50Support && 145 prefs.getBoolean(CellBroadcastSettings.KEY_ENABLE_CHANNEL_50_ALERTS, true); 146 147 SmsManager manager = SmsManager.getDefault(); 148 if (enableEmergencyAlerts) { 149 if (DBG) log("enabling emergency cell broadcast channels"); 150 if (!TextUtils.isEmpty(emergencyIdRange)) { 151 setChannelRange(manager, emergencyIdRange, true); 152 } else { 153 // No emergency channel system property, enable all emergency channels 154 manager.enableCellBroadcastRange( 155 SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER, 156 SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER); 157 } 158 if (DBG) log("enabled emergency cell broadcast channels"); 159 } else { 160 // we may have enabled these channels previously, so try to disable them 161 if (DBG) log("disabling emergency cell broadcast channels"); 162 if (!TextUtils.isEmpty(emergencyIdRange)) { 163 setChannelRange(manager, emergencyIdRange, false); 164 } else { 165 // No emergency channel system property, disable all emergency channels 166 manager.disableCellBroadcastRange( 167 SmsCbConstants.MESSAGE_ID_PWS_FIRST_IDENTIFIER, 168 SmsCbConstants.MESSAGE_ID_PWS_LAST_IDENTIFIER); 169 } 170 if (DBG) log("disabled emergency cell broadcast channels"); 171 } 172 173 if (enableChannel50Alerts) { 174 if (DBG) log("enabling cell broadcast channel 50"); 175 manager.enableCellBroadcast(50); 176 if (DBG) log("enabled cell broadcast channel 50"); 177 } else { 178 if (DBG) log("disabling cell broadcast channel 50"); 179 manager.disableCellBroadcast(50); 180 if (DBG) log("disabled cell broadcast channel 50"); 181 } 182 } catch (Exception ex) { 183 Log.e(TAG, "exception enabling cell broadcast channels", ex); 184 } 185 } 186 } 187 188 private static void log(String msg) { 189 Log.d(TAG, msg); 190 } 191} 192