Merge "Disallow making a call to emergency numbers"
diff --git a/src/com/android/messaging/datamodel/data/ConversationData.java b/src/com/android/messaging/datamodel/data/ConversationData.java
index 55d5bfc..5bddfeb 100644
--- a/src/com/android/messaging/datamodel/data/ConversationData.java
+++ b/src/com/android/messaging/datamodel/data/ConversationData.java
@@ -700,7 +700,7 @@
         final ParticipantData participant = this.getOtherParticipant();
         if (participant != null) {
             final String phoneNumber = participant.getSendDestination();
-            if (!TextUtils.isEmpty(phoneNumber) && MmsSmsUtils.isPhoneNumber(phoneNumber)) {
+            if (!TextUtils.isEmpty(phoneNumber) && MmsSmsUtils.isDialable(phoneNumber)) {
                 return phoneNumber;
             }
         }
diff --git a/src/com/android/messaging/sms/MmsSmsUtils.java b/src/com/android/messaging/sms/MmsSmsUtils.java
index 1a0ef99..aa20395 100644
--- a/src/com/android/messaging/sms/MmsSmsUtils.java
+++ b/src/com/android/messaging/sms/MmsSmsUtils.java
@@ -100,19 +100,27 @@
         return match.matches();
     }
 
+    /** True if c is ISO-LATIN characters 0-9, *, # , + */
+    public static final boolean isDialable(char c) {
+        return (c >= '0' && c <= '9') || c == '*' || c == '#' || c == '+';
+    }
+
     /**
-     * Returns true if the number is a Phone number
+     * Returns true if the address is a dialable phone number.
      *
-     * @param number the input number to be tested
-     * @return true if number is a Phone number
+     * @param address the input address to be tested
+     * @return true if address is a dialable phone number
      */
-    public static boolean isPhoneNumber(final String number) {
-        if (TextUtils.isEmpty(number)) {
+    public static boolean isDialable(final String address) {
+        if (TextUtils.isEmpty(address)) {
             return false;
         }
-
-        final Matcher match = Patterns.PHONE.matcher(number);
-        return match.matches();
+        for (int i = 0, count = address.length(); i < count; i++) {
+            if (!isDialable(address.charAt(i))) {
+                return false;
+            }
+        }
+        return true;
     }
 
     /**
diff --git a/src/com/android/messaging/sms/MmsUtils.java b/src/com/android/messaging/sms/MmsUtils.java
index 01b1e7e..a519972 100644
--- a/src/com/android/messaging/sms/MmsUtils.java
+++ b/src/com/android/messaging/sms/MmsUtils.java
@@ -1925,10 +1925,9 @@
             final long expiry, final RetrieveConf retrieveConf) {
         final byte[] notificationTransactionId = stringToBytes(transactionId, "UTF-8");
         Uri messageUri = null;
-        int status = MMS_REQUEST_MANUAL_RETRY;
-        int retrieveStatus = PDU_HEADER_VALUE_UNDEFINED;
+        final int status;
+        final int retrieveStatus = retrieveConf.getRetrieveStatus();
 
-        retrieveStatus = retrieveConf.getRetrieveStatus();
         if (retrieveStatus == PduHeaders.RETRIEVE_STATUS_OK) {
             status = MMS_REQUEST_SUCCEEDED;
         } else if (retrieveStatus >= PduHeaders.RETRIEVE_STATUS_ERROR_TRANSIENT_FAILURE &&
@@ -1963,17 +1962,9 @@
             final Uri inboxUri = MmsUtils.insertReceivedMmsMessage(context, retrieveConf, subId,
                     subPhoneNumber, receivedTimestampInSeconds, expiry, transactionId);
             messageUri = ContentUris.withAppendedId(Mms.CONTENT_URI, ContentUris.parseId(inboxUri));
-        } else if (status == MMS_REQUEST_AUTO_RETRY) {
-            // For a retry do nothing
-        } else if (status == MMS_REQUEST_MANUAL_RETRY && autoDownload) {
-            // Failure from autodownload - just treat like manual download
-            sendNotifyResponseForMmsDownload(
-                    context,
-                    subId,
-                    notificationTransactionId,
-                    contentLocation,
-                    PduHeaders.STATUS_DEFERRED);
         }
+        // Do nothing for MMS_REQUEST_AUTO_RETRY and MMS_REQUEST_NO_RETRY.
+
         return new StatusPlusUri(status, retrieveStatus, messageUri);
     }
 
@@ -2143,7 +2134,7 @@
 
     public static StatusPlusUri updateSentMmsMessageStatus(final Context context,
             final Uri messageUri, final SendConf sendConf) {
-        int status = MMS_REQUEST_MANUAL_RETRY;
+        final int status;
         final int respStatus = sendConf.getResponseStatus();
 
         final ContentValues values = new ContentValues(2);
@@ -2156,12 +2147,16 @@
                 messageUri, values, null, null);
         if (respStatus == PduHeaders.RESPONSE_STATUS_OK) {
             status = MMS_REQUEST_SUCCEEDED;
-        } else if (respStatus == PduHeaders.RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE ||
-                respStatus == PduHeaders.RESPONSE_STATUS_ERROR_TRANSIENT_NETWORK_PROBLEM ||
-                respStatus == PduHeaders.RESPONSE_STATUS_ERROR_TRANSIENT_PARTIAL_SUCCESS) {
+        } else if (respStatus >= PduHeaders.RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE
+                && respStatus < PduHeaders.RESPONSE_STATUS_ERROR_PERMANENT_FAILURE) {
+            // Only RESPONSE_STATUS_ERROR_TRANSIENT_FAILURE and RESPONSE_STATUS_ERROR_TRANSIENT
+            // _NETWORK_PROBLEM are used in the M-Send.conf. But for others transient failures
+            // including reserved values for future purposes, it should work same as transient
+            // failure always. (OMA-MMS-ENC-V1_2, 7.2.37. X-Mms-Response-Status field)
             status = MMS_REQUEST_AUTO_RETRY;
         } else {
             // else permanent failure
+            status = MMS_REQUEST_MANUAL_RETRY;
             LogUtil.e(TAG, "MmsUtils: failed to send message; respStatus = "
                     + String.format("0x%X", respStatus));
         }