Show alert dialog for operator-defined Cell Broadcast messages.

Enable display of received SMS broadcast messages as emergency alerts
(warning sound and alert dialog notification) if they are listed in the
range defined in "ro.cellbroadcast.emergencyids".

Bug: 5516275
Change-Id: Ic26aa28fa2b2201f32bff780db40d76883cd0860
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java
index bb4745e..dafb391 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastAlertService.java
@@ -98,7 +98,8 @@
 
         // add notification to the bar
         addToNotificationBar(cbm);
-        if (cbm.isEmergencyAlertMessage()) {
+        if (cbm.isEmergencyAlertMessage() || CellBroadcastConfigService
+                .isOperatorDefinedEmergencyId(cbm.getMessageIdentifier())) {
             // start audio/vibration/speech service for emergency alerts
             Intent audioIntent = new Intent(this, CellBroadcastAlertAudio.class);
             audioIntent.setAction(CellBroadcastAlertAudio.ACTION_START_ALERT_AUDIO);
@@ -191,7 +192,8 @@
 
         notification.setLatestEventInfo(this, channelName, messageBody, pi);
 
-        if (message.isEmergencyAlertMessage()) {
+        if (message.isEmergencyAlertMessage() || CellBroadcastConfigService
+                .isOperatorDefinedEmergencyId(message.getMessageIdentifier())) {
             // Emergency: open notification immediately
             notification.fullScreenIntent = pi;
             // use default notification lights (CellBroadcastAlertAudio plays sound/vibration)
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastConfigService.java b/src/com/android/cellbroadcastreceiver/CellBroadcastConfigService.java
index e24d431..112dfc7 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastConfigService.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastConfigService.java
@@ -81,6 +81,34 @@
         }
     }
 
+    static boolean isOperatorDefinedEmergencyId(int messageId) {
+        // Check for system property defining the emergency channel ranges to enable
+        String emergencyIdRange = SystemProperties.get("ro.cellbroadcast.emergencyids");
+        if (TextUtils.isEmpty(emergencyIdRange)) {
+            return false;
+        }
+        try {
+            for (String channelRange : emergencyIdRange.split(",")) {
+                int dashIndex = channelRange.indexOf('-');
+                if (dashIndex != -1) {
+                    int startId = Integer.decode(channelRange.substring(0, dashIndex));
+                    int endId = Integer.decode(channelRange.substring(dashIndex + 1));
+                    if (messageId >= startId && messageId <= endId) {
+                        return true;
+                    }
+                } else {
+                    int emergencyMessageId = Integer.decode(channelRange);
+                    if (emergencyMessageId == messageId) {
+                        return true;
+                    }
+                }
+            }
+        } catch (NumberFormatException e) {
+            Log.e(TAG, "Number Format Exception parsing emergency channel range", e);
+        }
+        return false;
+    }
+
     @Override
     protected void onHandleIntent(Intent intent) {
         if (ACTION_ENABLE_CHANNELS.equals(intent.getAction())) {
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastListActivity.java b/src/com/android/cellbroadcastreceiver/CellBroadcastListActivity.java
index 2d25b99..eafeec2 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastListActivity.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastListActivity.java
@@ -183,10 +183,12 @@
 
     private void showDialogAndMarkRead(Cursor cursor) {
         CellBroadcastMessage cbm = CellBroadcastMessage.createFromCursor(cursor);
+        boolean isAlertMessage = cbm.isPublicAlertMessage() || CellBroadcastConfigService
+                .isOperatorDefinedEmergencyId(cbm.getMessageIdentifier());
         // show emergency alerts with the warning icon, but don't play alert tone
         CellBroadcastAlertDialog dialog = new CellBroadcastAlertDialog(this,
                 cbm.getDialogTitleResource(), cbm.getMessageBody(),
-                cbm.isPublicAlertMessage(), cbm.getDeliveryTime());
+                isAlertMessage, cbm.getDeliveryTime());
         dialog.show();
     }
 
@@ -268,7 +270,8 @@
             (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
         notificationManager.cancel(notificationId);
 
-        boolean isEmergencyAlert = cbm.isPublicAlertMessage();
+        boolean isEmergencyAlert = cbm.isPublicAlertMessage() || CellBroadcastConfigService
+                .isOperatorDefinedEmergencyId(cbm.getMessageIdentifier());
 
         CellBroadcastAlertDialog dialog = new CellBroadcastAlertDialog(this,
                 cbm.getDialogTitleResource(), cbm.getMessageBody(),
diff --git a/src/com/android/cellbroadcastreceiver/CellBroadcastMessage.java b/src/com/android/cellbroadcastreceiver/CellBroadcastMessage.java
index a4d3bc2..e38aa02 100644
--- a/src/com/android/cellbroadcastreceiver/CellBroadcastMessage.java
+++ b/src/com/android/cellbroadcastreceiver/CellBroadcastMessage.java
@@ -284,7 +284,9 @@
                 return R.string.cmas_operator_defined_alert;
 
             default:
-                if (SmsCbHeader.isEmergencyMessage(mMessageIdentifier)) {
+                if (SmsCbHeader.isEmergencyMessage(mMessageIdentifier) ||
+                        CellBroadcastConfigService.isOperatorDefinedEmergencyId(
+                                mMessageIdentifier)) {
                     return R.string.pws_other_message_identifiers;
                 } else {
                     return R.string.cb_other_message_identifiers;