1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * 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, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.cellbroadcastreceiver; 18 19 import android.content.Context; 20 import android.graphics.Typeface; 21 import android.telephony.CellBroadcastMessage; 22 import android.telephony.SmsCbCmasInfo; 23 import android.telephony.SmsCbEtwsInfo; 24 import android.text.Spannable; 25 import android.text.SpannableStringBuilder; 26 import android.text.style.StyleSpan; 27 28 import com.android.cellbroadcastreceiver.CellBroadcastChannelManager.CellBroadcastChannelRange; 29 30 import java.util.ArrayList; 31 32 /** 33 * Returns the string resource ID's for CMAS and ETWS emergency alerts. 34 */ 35 public class CellBroadcastResources { 36 37 private CellBroadcastResources() { 38 } 39 40 /** 41 * Returns a styled CharSequence containing the message date/time and alert details. 42 * @param context a Context for resource string access 43 * @return a CharSequence for display in the broadcast alert dialog 44 */ 45 public static CharSequence getMessageDetails(Context context, CellBroadcastMessage cbm) { 46 SpannableStringBuilder buf = new SpannableStringBuilder(); 47 48 // Alert date/time 49 int start = buf.length(); 50 buf.append(context.getString(R.string.delivery_time_heading)); 51 int end = buf.length(); 52 buf.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 53 buf.append(" "); 54 buf.append(cbm.getDateString(context)); 55 56 if (cbm.isCmasMessage()) { 57 // CMAS category, response type, severity, urgency, certainty 58 appendCmasAlertDetails(context, buf, cbm.getCmasWarningInfo()); 59 } 60 61 return buf; 62 } 63 64 private static void appendCmasAlertDetails(Context context, SpannableStringBuilder buf, 65 SmsCbCmasInfo cmasInfo) { 66 // CMAS category 67 int categoryId = getCmasCategoryResId(cmasInfo); 68 if (categoryId != 0) { 69 appendMessageDetail(context, buf, R.string.cmas_category_heading, categoryId); 70 } 71 72 // CMAS response type 73 int responseId = getCmasResponseResId(cmasInfo); 74 if (responseId != 0) { 75 appendMessageDetail(context, buf, R.string.cmas_response_heading, responseId); 76 } 77 78 // CMAS severity 79 int severityId = getCmasSeverityResId(cmasInfo); 80 if (severityId != 0) { 81 appendMessageDetail(context, buf, R.string.cmas_severity_heading, severityId); 82 } 83 84 // CMAS urgency 85 int urgencyId = getCmasUrgencyResId(cmasInfo); 86 if (urgencyId != 0) { 87 appendMessageDetail(context, buf, R.string.cmas_urgency_heading, urgencyId); 88 } 89 90 // CMAS certainty 91 int certaintyId = getCmasCertaintyResId(cmasInfo); 92 if (certaintyId != 0) { 93 appendMessageDetail(context, buf, R.string.cmas_certainty_heading, certaintyId); 94 } 95 } 96 97 private static void appendMessageDetail(Context context, SpannableStringBuilder buf, 98 int typeId, int valueId) { 99 if (buf.length() != 0) { 100 buf.append("\n"); 101 } 102 int start = buf.length(); 103 buf.append(context.getString(typeId)); 104 int end = buf.length(); 105 buf.setSpan(new StyleSpan(Typeface.BOLD), start, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); 106 buf.append(" "); 107 buf.append(context.getString(valueId)); 108 } 109 110 /** 111 * Returns the string resource ID for the CMAS category. 112 * @return a string resource ID, or 0 if the CMAS category is unknown or not present 113 */ 114 private static int getCmasCategoryResId(SmsCbCmasInfo cmasInfo) { 115 switch (cmasInfo.getCategory()) { 116 case SmsCbCmasInfo.CMAS_CATEGORY_GEO: 117 return R.string.cmas_category_geo; 118 119 case SmsCbCmasInfo.CMAS_CATEGORY_MET: 120 return R.string.cmas_category_met; 121 122 case SmsCbCmasInfo.CMAS_CATEGORY_SAFETY: 123 return R.string.cmas_category_safety; 124 125 case SmsCbCmasInfo.CMAS_CATEGORY_SECURITY: 126 return R.string.cmas_category_security; 127 128 case SmsCbCmasInfo.CMAS_CATEGORY_RESCUE: 129 return R.string.cmas_category_rescue; 130 131 case SmsCbCmasInfo.CMAS_CATEGORY_FIRE: 132 return R.string.cmas_category_fire; 133 134 case SmsCbCmasInfo.CMAS_CATEGORY_HEALTH: 135 return R.string.cmas_category_health; 136 137 case SmsCbCmasInfo.CMAS_CATEGORY_ENV: 138 return R.string.cmas_category_env; 139 140 case SmsCbCmasInfo.CMAS_CATEGORY_TRANSPORT: 141 return R.string.cmas_category_transport; 142 143 case SmsCbCmasInfo.CMAS_CATEGORY_INFRA: 144 return R.string.cmas_category_infra; 145 146 case SmsCbCmasInfo.CMAS_CATEGORY_CBRNE: 147 return R.string.cmas_category_cbrne; 148 149 case SmsCbCmasInfo.CMAS_CATEGORY_OTHER: 150 return R.string.cmas_category_other; 151 152 default: 153 return 0; 154 } 155 } 156 157 /** 158 * Returns the string resource ID for the CMAS response type. 159 * @return a string resource ID, or 0 if the CMAS response type is unknown or not present 160 */ 161 private static int getCmasResponseResId(SmsCbCmasInfo cmasInfo) { 162 switch (cmasInfo.getResponseType()) { 163 case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_SHELTER: 164 return R.string.cmas_response_shelter; 165 166 case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_EVACUATE: 167 return R.string.cmas_response_evacuate; 168 169 case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_PREPARE: 170 return R.string.cmas_response_prepare; 171 172 case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_EXECUTE: 173 return R.string.cmas_response_execute; 174 175 case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_MONITOR: 176 return R.string.cmas_response_monitor; 177 178 case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_AVOID: 179 return R.string.cmas_response_avoid; 180 181 case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_ASSESS: 182 return R.string.cmas_response_assess; 183 184 case SmsCbCmasInfo.CMAS_RESPONSE_TYPE_NONE: 185 return R.string.cmas_response_none; 186 187 default: 188 return 0; 189 } 190 } 191 192 /** 193 * Returns the string resource ID for the CMAS severity. 194 * @return a string resource ID, or 0 if the CMAS severity is unknown or not present 195 */ 196 private static int getCmasSeverityResId(SmsCbCmasInfo cmasInfo) { 197 switch (cmasInfo.getSeverity()) { 198 case SmsCbCmasInfo.CMAS_SEVERITY_EXTREME: 199 return R.string.cmas_severity_extreme; 200 201 case SmsCbCmasInfo.CMAS_SEVERITY_SEVERE: 202 return R.string.cmas_severity_severe; 203 204 default: 205 return 0; 206 } 207 } 208 209 /** 210 * Returns the string resource ID for the CMAS urgency. 211 * @return a string resource ID, or 0 if the CMAS urgency is unknown or not present 212 */ 213 private static int getCmasUrgencyResId(SmsCbCmasInfo cmasInfo) { 214 switch (cmasInfo.getUrgency()) { 215 case SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE: 216 return R.string.cmas_urgency_immediate; 217 218 case SmsCbCmasInfo.CMAS_URGENCY_EXPECTED: 219 return R.string.cmas_urgency_expected; 220 221 default: 222 return 0; 223 } 224 } 225 226 /** 227 * Returns the string resource ID for the CMAS certainty. 228 * @return a string resource ID, or 0 if the CMAS certainty is unknown or not present 229 */ 230 private static int getCmasCertaintyResId(SmsCbCmasInfo cmasInfo) { 231 switch (cmasInfo.getCertainty()) { 232 case SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED: 233 return R.string.cmas_certainty_observed; 234 235 case SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY: 236 return R.string.cmas_certainty_likely; 237 238 default: 239 return 0; 240 } 241 } 242 243 public static int getDialogTitleResource(Context context, CellBroadcastMessage cbm) { 244 // ETWS warning types 245 SmsCbEtwsInfo etwsInfo = cbm.getEtwsWarningInfo(); 246 if (etwsInfo != null) { 247 switch (etwsInfo.getWarningType()) { 248 case SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE: 249 return R.string.etws_earthquake_warning; 250 251 case SmsCbEtwsInfo.ETWS_WARNING_TYPE_TSUNAMI: 252 return R.string.etws_tsunami_warning; 253 254 case SmsCbEtwsInfo.ETWS_WARNING_TYPE_EARTHQUAKE_AND_TSUNAMI: 255 return R.string.etws_earthquake_and_tsunami_warning; 256 257 case SmsCbEtwsInfo.ETWS_WARNING_TYPE_TEST_MESSAGE: 258 return R.string.etws_test_message; 259 260 case SmsCbEtwsInfo.ETWS_WARNING_TYPE_OTHER_EMERGENCY: 261 default: 262 return R.string.etws_other_emergency_type; 263 } 264 } 265 266 // CMAS warning types 267 SmsCbCmasInfo cmasInfo = cbm.getCmasWarningInfo(); 268 if (cmasInfo != null) { 269 switch (cmasInfo.getMessageClass()) { 270 case SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT: 271 return R.string.cmas_presidential_level_alert; 272 273 case SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT: 274 return R.string.cmas_extreme_alert; 275 276 case SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT: 277 return R.string.cmas_severe_alert; 278 279 case SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY: 280 return R.string.cmas_amber_alert; 281 282 case SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST: 283 return R.string.cmas_required_monthly_test; 284 285 case SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE: 286 return R.string.cmas_exercise_alert; 287 288 case SmsCbCmasInfo.CMAS_CLASS_OPERATOR_DEFINED_USE: 289 return R.string.cmas_operator_defined_alert; 290 291 default: 292 return R.string.pws_other_message_identifiers; 293 } 294 } 295 296 if (CellBroadcastAlertService.isEmergencyMessage(context, cbm)) { 297 ArrayList<CellBroadcastChannelRange> ranges = CellBroadcastChannelManager 298 .getInstance().getCellBroadcastChannelRanges(context); 299 if (ranges != null) { 300 for (CellBroadcastChannelRange range : ranges) { 301 if (cbm.getServiceCategory() >= range.mStartId && 302 cbm.getServiceCategory() <= range.mEndId) { 303 // Apply the closest title to the specified tones. 304 switch (range.mAlertType) { 305 case CMAS_DEFAULT: 306 return R.string.pws_other_message_identifiers; 307 case EARTHQUAKE: 308 return R.string.etws_earthquake_warning; 309 case TSUNAMI: 310 return R.string.etws_tsunami_warning; 311 case ETWS_DEFAULT: 312 case OTHER: 313 return R.string.etws_other_emergency_type; 314 } 315 } 316 } 317 318 } 319 return R.string.pws_other_message_identifiers; 320 } else { 321 return R.string.cb_other_message_identifiers; 322 } 323 } 324 } 325