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