Merge "Retry SMS over IMS up to MAX_SEND_RETRIES"
diff --git a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
index eb96af2..748cca7 100644
--- a/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
+++ b/src/java/com/android/internal/telephony/ImsSmsDispatcher.java
@@ -18,6 +18,7 @@
 
 import android.content.Context;
 import android.os.Binder;
+import android.os.Message;
 import android.os.PersistableBundle;
 import android.os.RemoteException;
 import android.provider.Telephony.Sms.Intents;
@@ -169,8 +170,14 @@
                         mTrackers.remove(token);
                         break;
                     case ImsSmsImplBase.SEND_STATUS_ERROR_RETRY:
-                        tracker.mRetryCount += 1;
-                        sendSms(tracker);
+                        if (tracker.mRetryCount < MAX_SEND_RETRIES) {
+                            tracker.mRetryCount += 1;
+                            sendMessageDelayed(
+                                    obtainMessage(EVENT_SEND_RETRY, tracker), SEND_RETRY_DELAY);
+                        } else {
+                            tracker.onFailed(mContext, reason, networkReasonCode);
+                            mTrackers.remove(token);
+                        }
                         break;
                     case ImsSmsImplBase.SEND_STATUS_ERROR_FALLBACK:
                         tracker.mRetryCount += 1;
@@ -260,6 +267,18 @@
         }
     };
 
+    @Override
+    public void handleMessage(Message msg) {
+        switch (msg.what) {
+            case EVENT_SEND_RETRY:
+                logd("SMS retry..");
+                sendSms((SmsTracker) msg.obj);
+                break;
+            default:
+                super.handleMessage(msg);
+        }
+    }
+
     public ImsSmsDispatcher(Phone phone, SmsDispatchersController smsDispatchersController,
             FeatureConnectorFactory factory) {
         super(phone, smsDispatchersController);
@@ -416,7 +435,7 @@
         boolean isRetry = tracker.mRetryCount > 0;
         String format = getFormat();
 
-        if (SmsConstants.FORMAT_3GPP.equals(format) && tracker.mRetryCount > 0) {
+        if (SmsConstants.FORMAT_3GPP.equals(format) && isRetry) {
             // per TS 23.040 Section 9.2.3.6:  If TP-MTI SMS-SUBMIT (0x01) type
             //   TP-RD (bit 2) is 1 for retry
             //   and TP-MR is set to previously failed sms TP-MR
diff --git a/src/java/com/android/internal/telephony/SMSDispatcher.java b/src/java/com/android/internal/telephony/SMSDispatcher.java
index 3600e85..b52fce3 100644
--- a/src/java/com/android/internal/telephony/SMSDispatcher.java
+++ b/src/java/com/android/internal/telephony/SMSDispatcher.java
@@ -111,7 +111,7 @@
     protected static final int EVENT_SEND_SMS_COMPLETE = 2;
 
     /** Retry sending a previously failed SMS message */
-    private static final int EVENT_SEND_RETRY = 3;
+    protected static final int EVENT_SEND_RETRY = 3;
 
     /** Confirmation required for sending a large number of messages. */
     private static final int EVENT_SEND_LIMIT_REACHED_CONFIRMATION = 4;
@@ -151,9 +151,10 @@
     protected final TelephonyManager mTelephonyManager;
 
     /** Maximum number of times to retry sending a failed SMS. */
-    private static final int MAX_SEND_RETRIES = 3;
+    protected static final int MAX_SEND_RETRIES = 3;
     /** Delay before next send attempt on a failed SMS, in milliseconds. */
-    private static final int SEND_RETRY_DELAY = 2000;
+    @VisibleForTesting
+    public static final int SEND_RETRY_DELAY = 2000;
     /** Message sending queue limit */
     private static final int MO_MSG_QUEUE_LIMIT = 5;
 
diff --git a/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java b/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
index d4ac4d5..90b6e36 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/ImsSmsDispatcherTest.java
@@ -16,6 +16,8 @@
 
 package com.android.internal.telephony;
 
+import static com.android.internal.telephony.TelephonyTestUtils.waitForMs;
+
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
@@ -150,9 +152,11 @@
         mImsSmsDispatcher.mTrackers.put(token, mSmsTracker);
         when(mPhone.getPhoneType()).thenReturn(PhoneConstants.PHONE_TYPE_GSM);
 
-        // Fallback over GSM
+        // Retry over IMS
         mImsSmsDispatcher.getSmsListener().onSendSmsResult(token, 0,
                 ImsSmsImplBase.SEND_STATUS_ERROR_RETRY, 0, SmsResponse.NO_ERROR_CODE);
+        waitForMs(SMSDispatcher.SEND_RETRY_DELAY + 200);
+        processAllMessages();
 
         // Make sure retry bit set
         ArgumentCaptor<byte[]> byteCaptor = ArgumentCaptor.forClass(byte[].class);