• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CellBroadcastResources()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      */
getMessageDetails(Context context, CellBroadcastMessage cbm)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 
appendCmasAlertDetails(Context context, SpannableStringBuilder buf, SmsCbCmasInfo cmasInfo)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 
appendMessageDetail(Context context, SpannableStringBuilder buf, int typeId, int valueId)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      */
getCmasCategoryResId(SmsCbCmasInfo cmasInfo)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      */
getCmasResponseResId(SmsCbCmasInfo cmasInfo)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      */
getCmasSeverityResId(SmsCbCmasInfo cmasInfo)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      */
getCmasUrgencyResId(SmsCbCmasInfo cmasInfo)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      */
getCmasCertaintyResId(SmsCbCmasInfo cmasInfo)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 
getDialogTitleResource(Context context, CellBroadcastMessage cbm)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         SmsCbCmasInfo cmasInfo = cbm.getCmasWarningInfo();
267         int subId = cbm.getSubId();
268         final int serviceCategory = cbm.getServiceCategory();
269         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
270                 serviceCategory,
271                 R.array.emergency_alerts_channels_range_strings, context)) {
272             return R.string.pws_other_message_identifiers;
273         }
274         // CMAS warning types
275         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
276                 serviceCategory,
277                 R.array.cmas_presidential_alerts_channels_range_strings, context)) {
278             return R.string.cmas_presidential_level_alert;
279         }
280         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
281                 serviceCategory,
282                 R.array.cmas_alert_extreme_channels_range_strings, context)) {
283             if (cmasInfo.getSeverity() == SmsCbCmasInfo.CMAS_SEVERITY_EXTREME
284                     && cmasInfo.getUrgency() == SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE) {
285                 if (cmasInfo.getCertainty() == SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED) {
286                     return R.string.cmas_extreme_immediate_observed_alert;
287                 } else if (cmasInfo.getCertainty() == SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY) {
288                     return R.string.cmas_extreme_immediate_likely_alert;
289                 }
290             }
291             return R.string.cmas_extreme_alert;
292         }
293         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
294                 serviceCategory, R.array.cmas_alerts_severe_range_strings, context)) {
295             return R.string.cmas_severe_alert;
296         }
297         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
298                 serviceCategory,
299                 R.array.cmas_amber_alerts_channels_range_strings, context)) {
300             return R.string.cmas_amber_alert;
301         }
302         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
303                 serviceCategory, R.array.required_monthly_test_range_strings, context)) {
304             return R.string.cmas_required_monthly_test;
305         }
306         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
307                 serviceCategory, R.array.exercise_alert_range_strings, context)) {
308             return R.string.cmas_exercise_alert;
309         }
310         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
311                 serviceCategory, R.array.operator_defined_alert_range_strings, context)) {
312             return R.string.cmas_operator_defined_alert;
313         }
314         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
315                 serviceCategory, R.array.public_safety_messages_channels_range_strings, context)) {
316             return R.string.public_safety_message;
317         }
318         if (CellBroadcastChannelManager.checkCellBroadcastChannelRange(subId,
319                 serviceCategory, R.array.state_local_test_alert_range_strings, context)) {
320             return R.string.state_local_test_alert;
321         }
322 
323         if (CellBroadcastChannelManager.isEmergencyMessage(context, cbm)) {
324             ArrayList<CellBroadcastChannelRange> ranges = CellBroadcastChannelManager
325                     .getInstance().getCellBroadcastChannelRanges(context,
326                     R.array.additional_cbs_channels_strings);
327             if (ranges != null) {
328                 for (CellBroadcastChannelRange range : ranges) {
329                     if (serviceCategory >= range.mStartId && serviceCategory <= range.mEndId) {
330                         // Apply the closest title to the specified tones.
331                         switch (range.mAlertType) {
332                             case DEFAULT:
333                                 return R.string.pws_other_message_identifiers;
334                             case ETWS_EARTHQUAKE:
335                                 return R.string.etws_earthquake_warning;
336                             case ETWS_TSUNAMI:
337                                 return R.string.etws_tsunami_warning;
338                             case TEST:
339                                 return R.string.etws_test_message;
340                             case ETWS_DEFAULT:
341                             case OTHER:
342                                 return R.string.etws_other_emergency_type;
343                         }
344                     }
345                 }
346 
347             }
348             return R.string.pws_other_message_identifiers;
349         } else {
350             return R.string.cb_other_message_identifiers;
351         }
352     }
353 }
354