1 /* 2 * Copyright (C) 2018 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.tests; 18 19 import android.Manifest; 20 import android.app.Activity; 21 import android.app.AppOpsManager; 22 import android.content.Context; 23 import android.content.Intent; 24 import android.os.UserHandle; 25 import android.provider.Telephony; 26 import android.telephony.SmsCbCmasInfo; 27 import android.telephony.SmsCbLocation; 28 import android.telephony.SmsCbMessage; 29 import android.text.TextUtils; 30 31 import com.android.internal.telephony.CellBroadcastUtils; 32 import com.android.internal.telephony.gsm.SmsCbConstants; 33 34 /** 35 * Send some test GSM CMAS warning notifications. 36 */ 37 public class SendGsmCmasMessages { 38 39 private static final String PRES_ALERT = 40 "THE PRESIDENT HAS ISSUED AN EMERGENCY ALERT. CHECK LOCAL MEDIA FOR MORE DETAILS"; 41 42 private static final String EXTREME_ALERT = "FLASH FLOOD WARNING FOR SOUTH COCONINO COUNTY" 43 + " - NORTH CENTRAL ARIZONA UNTIL 415 PM MST"; 44 45 private static final String SEVERE_ALERT = "SEVERE WEATHER WARNING FOR SOMERSET COUNTY" 46 + " - NEW JERSEY UNTIL 415 PM MST"; 47 48 private static final String AMBER_ALERT = 49 "AMBER ALERT:Mountain View,CA VEH'07 Blue Honda Civic CA LIC 5ABC123. " 50 + "Check www.amberalert.gov/active.htm, call 858-123-4567, or email " 51 + "amberalert@mountainview.ca.gov for more information."; 52 53 private static final String MONTHLY_TEST_ALERT = "This is a test of the emergency alert system." 54 + " This is only a test. Call (123)456-7890."; 55 56 private static final String PUBLIC_SAFETY_MESSAGE = "This is a public safety message."; 57 58 private static final String STATE_LOCAL_ALERT = "This is a state/local test message."; 59 sendBroadcast(Context context, SmsCbMessage cbMessage)60 private static void sendBroadcast(Context context, SmsCbMessage cbMessage) { 61 Intent intent = new Intent(Telephony.Sms.Intents.ACTION_SMS_EMERGENCY_CB_RECEIVED); 62 intent.putExtra("message", cbMessage); 63 intent.setPackage(CellBroadcastUtils.getDefaultCellBroadcastReceiverPackageName(context)); 64 context.sendOrderedBroadcastAsUser(intent, UserHandle.ALL, 65 Manifest.permission.RECEIVE_EMERGENCY_BROADCAST, 66 AppOpsManager.OP_RECEIVE_EMERGECY_SMS, null, null, Activity.RESULT_OK, null, null); 67 } 68 testSendCmasAlertWithServiceCategory( Context context, int serviceCategory, int serialNumber, String messageBody, String languageCode, boolean isAdditionalLang)69 public static void testSendCmasAlertWithServiceCategory( 70 Context context, int serviceCategory, int serialNumber, String messageBody, 71 String languageCode, boolean isAdditionalLang) { 72 SmsCbMessage cbMessage = 73 createCmasSmsMessage( 74 serviceCategory, 75 serialNumber, 76 TextUtils.isEmpty(languageCode) ? "en" : languageCode, 77 TextUtils.isEmpty(messageBody) ? "This is an alert" : messageBody, 78 SmsCbCmasInfo.CMAS_SEVERITY_EXTREME, 79 SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, 80 SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY, 81 SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY); 82 83 sendBroadcast(context, cbMessage); 84 } 85 testSendCmasPresAlert( Context context, int serialNumber, String messageBody, String languageCode, boolean isAdditionalLang)86 public static void testSendCmasPresAlert( 87 Context context, int serialNumber, String messageBody, String languageCode, 88 boolean isAdditionalLang) { 89 SmsCbMessage cbMessage = 90 createCmasSmsMessage( 91 isAdditionalLang 92 ? SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE 93 : SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL, 94 serialNumber, 95 TextUtils.isEmpty(languageCode) ? "en" : languageCode, 96 TextUtils.isEmpty(messageBody) ? PRES_ALERT : messageBody, 97 SmsCbCmasInfo.CMAS_SEVERITY_EXTREME, 98 SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, 99 SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY, 100 SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY); 101 102 sendBroadcast(context, cbMessage); 103 } 104 testSendCmasExtremeAlert( Context context, int serialNumber, String messageBody, String languageCode, boolean isAdditionalLang)105 public static void testSendCmasExtremeAlert( 106 Context context, int serialNumber, String messageBody, String languageCode, 107 boolean isAdditionalLang) { 108 SmsCbMessage cbMessage = 109 createCmasSmsMessage( 110 isAdditionalLang 111 ? SmsCbConstants 112 .MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE 113 : SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED, 114 serialNumber, 115 TextUtils.isEmpty(languageCode) ? "en" : languageCode, 116 TextUtils.isEmpty(messageBody) ? EXTREME_ALERT : messageBody, 117 SmsCbCmasInfo.CMAS_SEVERITY_EXTREME, 118 SmsCbCmasInfo.CMAS_URGENCY_EXPECTED, 119 SmsCbCmasInfo.CMAS_CERTAINTY_OBSERVED, 120 SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY); 121 122 sendBroadcast(context, cbMessage); 123 } 124 testSendCmasSevereAlert( Context context, int serialNumber, String messageBody, String languageCode, boolean isAdditionalLang)125 public static void testSendCmasSevereAlert( 126 Context context, int serialNumber, String messageBody, String languageCode, 127 boolean isAdditionalLang) { 128 SmsCbMessage cbMessage = 129 createCmasSmsMessage( 130 isAdditionalLang 131 ? SmsCbConstants 132 .MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED_LANGUAGE 133 : SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED, 134 serialNumber, 135 TextUtils.isEmpty(languageCode) ? "en" : languageCode, 136 TextUtils.isEmpty(messageBody) ? SEVERE_ALERT : messageBody, 137 SmsCbCmasInfo.CMAS_SEVERITY_SEVERE, 138 SmsCbCmasInfo.CMAS_URGENCY_IMMEDIATE, 139 SmsCbCmasInfo.CMAS_CERTAINTY_LIKELY, 140 SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY); 141 142 sendBroadcast(context, cbMessage); 143 } 144 testSendCmasAmberAlert( Context context, int serialNumber, String messageBody, String languageCode, boolean isAdditionalLang)145 public static void testSendCmasAmberAlert( 146 Context context, int serialNumber, String messageBody, String languageCode, 147 boolean isAdditionalLang) { 148 SmsCbMessage cbMessage = 149 createCmasSmsMessage( 150 isAdditionalLang 151 ? SmsCbConstants 152 .MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE 153 : SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY, 154 serialNumber, 155 TextUtils.isEmpty(languageCode) ? "en" : languageCode, 156 TextUtils.isEmpty(messageBody) ? AMBER_ALERT : messageBody, 157 SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, 158 SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, 159 SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, 160 SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY); 161 162 sendBroadcast(context, cbMessage); 163 } 164 testSendCmasMonthlyTest( Context context, int serialNumber, String messageBody, String languageCode, boolean isAdditionalLang)165 public static void testSendCmasMonthlyTest( 166 Context context, int serialNumber, String messageBody, String languageCode, 167 boolean isAdditionalLang) { 168 SmsCbMessage cbMessage = 169 createCmasSmsMessage( 170 isAdditionalLang 171 ? SmsCbConstants 172 .MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST_LANGUAGE 173 : SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST, 174 serialNumber, 175 TextUtils.isEmpty(languageCode) ? "en" : languageCode, 176 TextUtils.isEmpty(messageBody) ? MONTHLY_TEST_ALERT : messageBody, 177 SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, 178 SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, 179 SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, 180 SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY); 181 182 sendBroadcast(context, cbMessage); 183 } 184 testSendCmasExerciseTest( Context context, int serialNumber, String messageBody, String languageCode, boolean isAdditionalLang)185 public static void testSendCmasExerciseTest( 186 Context context, int serialNumber, String messageBody, String languageCode, 187 boolean isAdditionalLang) { 188 SmsCbMessage cbMessage = 189 createCmasSmsMessage( 190 isAdditionalLang 191 ? SmsCbConstants 192 .MESSAGE_ID_CMAS_ALERT_EXERCISE_LANGUAGE 193 : SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE, 194 serialNumber, 195 TextUtils.isEmpty(languageCode) ? "en" : languageCode, 196 TextUtils.isEmpty(messageBody) ? MONTHLY_TEST_ALERT : messageBody, 197 SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, 198 SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, 199 SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, 200 SmsCbMessage.MESSAGE_PRIORITY_EMERGENCY); 201 202 sendBroadcast(context, cbMessage); 203 } 204 testSendPublicSafetyMessagesAlert( Context context, int serialNumber, String messageBody, String languageCode, boolean isAdditionalLang)205 public static void testSendPublicSafetyMessagesAlert( 206 Context context, int serialNumber, String messageBody, String languageCode, 207 boolean isAdditionalLang) { 208 SmsCbMessage cbMessage = 209 createCmasSmsMessage( 210 isAdditionalLang 211 ? SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PUBLIC_SAFETY_LANGUAGE 212 : SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PUBLIC_SAFETY, 213 serialNumber, 214 TextUtils.isEmpty(languageCode) ? "en" : languageCode, 215 TextUtils.isEmpty(messageBody) ? PUBLIC_SAFETY_MESSAGE : messageBody, 216 SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, 217 SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, 218 SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, 219 SmsCbMessage.MESSAGE_PRIORITY_NORMAL); 220 221 sendBroadcast(context, cbMessage); 222 } 223 testSendStateLocalTestAlert( Context context, int serialNumber, String messageBody, String languageCode, boolean isAdditionalLang)224 public static void testSendStateLocalTestAlert( 225 Context context, int serialNumber, String messageBody, String languageCode, 226 boolean isAdditionalLang) { 227 SmsCbMessage cbMessage = 228 createCmasSmsMessage( 229 isAdditionalLang 230 ? SmsCbConstants.MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST_LANGUAGE 231 : SmsCbConstants.MESSAGE_ID_CMAS_ALERT_STATE_LOCAL_TEST, 232 serialNumber, 233 TextUtils.isEmpty(languageCode) ? "en" : languageCode, 234 TextUtils.isEmpty(messageBody) ? STATE_LOCAL_ALERT : messageBody, 235 SmsCbCmasInfo.CMAS_SEVERITY_UNKNOWN, 236 SmsCbCmasInfo.CMAS_URGENCY_UNKNOWN, 237 SmsCbCmasInfo.CMAS_CERTAINTY_UNKNOWN, 238 SmsCbMessage.MESSAGE_PRIORITY_NORMAL); 239 240 sendBroadcast(context, cbMessage); 241 } 242 243 /** 244 * Create a new SmsCbMessage for testing GSM CMAS support. 245 * @param serviceCategory the GSM service category 246 * @param serialNumber the 16-bit message identifier 247 * @param language message language code 248 * @param body message body 249 * @param severity CMAS severity 250 * @param urgency CMAS urgency 251 * @param certainty CMAS certainty 252 * @return the newly created SmsMessage object 253 */ createCmasSmsMessage(int serviceCategory, int serialNumber, String language, String body, int severity, int urgency, int certainty, int priority)254 private static SmsCbMessage createCmasSmsMessage(int serviceCategory, int serialNumber, 255 String language, String body, int severity, int urgency, int certainty, int priority) { 256 int messageClass = getCmasMessageClass(serviceCategory); 257 SmsCbCmasInfo cmasInfo = 258 new SmsCbCmasInfo( 259 messageClass, 260 SmsCbCmasInfo.CMAS_CATEGORY_UNKNOWN, 261 SmsCbCmasInfo.CMAS_RESPONSE_TYPE_UNKNOWN, 262 severity, 263 urgency, 264 certainty); 265 return new SmsCbMessage(SmsCbMessage.MESSAGE_FORMAT_3GPP, 0, serialNumber, 266 new SmsCbLocation("123456"), serviceCategory, language, body, 267 priority, null, cmasInfo, 0, 1); 268 } 269 270 /** 271 * Returns the CMAS message class. 272 * 273 * @param messageId message identifier 274 * @return the CMAS message class as defined in {@link SmsCbCmasInfo} 275 */ getCmasMessageClass(int messageId)276 private static int getCmasMessageClass(int messageId) { 277 switch (messageId) { 278 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL: 279 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_PRESIDENTIAL_LEVEL_LANGUAGE: 280 return SmsCbCmasInfo.CMAS_CLASS_PRESIDENTIAL_LEVEL_ALERT; 281 282 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED: 283 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_OBSERVED_LANGUAGE: 284 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY: 285 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_IMMEDIATE_LIKELY_LANGUAGE: 286 return SmsCbCmasInfo.CMAS_CLASS_EXTREME_THREAT; 287 288 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED: 289 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_OBSERVED_LANGUAGE: 290 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY: 291 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXTREME_EXPECTED_LIKELY_LANGUAGE: 292 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED: 293 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_OBSERVED_LANGUAGE: 294 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY: 295 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_IMMEDIATE_LIKELY_LANGUAGE: 296 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED: 297 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_OBSERVED_LANGUAGE: 298 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY: 299 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_SEVERE_EXPECTED_LIKELY_LANGUAGE: 300 return SmsCbCmasInfo.CMAS_CLASS_SEVERE_THREAT; 301 302 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY: 303 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_CHILD_ABDUCTION_EMERGENCY_LANGUAGE: 304 return SmsCbCmasInfo.CMAS_CLASS_CHILD_ABDUCTION_EMERGENCY; 305 306 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST: 307 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_REQUIRED_MONTHLY_TEST_LANGUAGE: 308 return SmsCbCmasInfo.CMAS_CLASS_REQUIRED_MONTHLY_TEST; 309 310 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE: 311 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_EXERCISE_LANGUAGE: 312 return SmsCbCmasInfo.CMAS_CLASS_CMAS_EXERCISE; 313 314 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE: 315 case SmsCbConstants.MESSAGE_ID_CMAS_ALERT_OPERATOR_DEFINED_USE_LANGUAGE: 316 return SmsCbCmasInfo.CMAS_CLASS_OPERATOR_DEFINED_USE; 317 318 default: 319 return SmsCbCmasInfo.CMAS_CLASS_UNKNOWN; 320 } 321 } 322 } 323