Extend apn retry configurability to more apn types

Extend apn retry configurability to more apn types so
we can control each APN retry behavior.

bug: 31381899
Change-Id: I6453aa76ebf2f977f5e730d34a502be9d0913577
diff --git a/src/java/com/android/internal/telephony/RetryManager.java b/src/java/com/android/internal/telephony/RetryManager.java
index d7c374c..684de9a 100644
--- a/src/java/com/android/internal/telephony/RetryManager.java
+++ b/src/java/com/android/internal/telephony/RetryManager.java
@@ -40,7 +40,7 @@
  * The other configure method allows a series to be declared using
  * a string.
  *<p>
- * The format of the configuration string is a series of parameters
+ * The format of the configuration string is the apn type followed by a series of parameters
  * separated by a comma. There are two name value pair parameters plus a series
  * of delay times. The units of of these delay times is unspecified.
  * The name value pairs which may be specified are:
@@ -49,6 +49,9 @@
  *<li>default_randomizationTime=<value>
  *</ul>
  *<p>
+ * apn type specifies the APN type that the retry pattern will apply for. "others" is for all other
+ * APN types not specified in the config.
+ *
  * max_retries is the number of times that incrementRetryCount
  * maybe called before isRetryNeeded will return false. if value
  * is infinite then isRetryNeeded will always return true.
@@ -63,20 +66,20 @@
  *<p>
  * Examples:
  * <ul>
- * <li>3 retries with no randomization value which means its 0:
- * <ul><li><code>"1000, 2000, 3000"</code></ul>
+ * <li>3 retries for mms with no randomization value which means its 0:
+ * <ul><li><code>"mms:1000, 2000, 3000"</code></ul>
  *
- * <li>10 retries with a 500 default randomization value for each and
+ * <li>10 retries for default APN with a 500 default randomization value for each and
  * the 4..10 retries all using 3000 as the delay:
- * <ul><li><code>"max_retries=10, default_randomization=500, 1000, 2000, 3000"</code></ul>
+ * <ul><li><code>"default:max_retries=10, default_randomization=500, 1000, 2000, 3000"</code></ul>
  *
- * <li>4 retries with a 100 as the default randomization value for the first 2 values and
- * the other two having specified values of 500:
- * <ul><li><code>"default_randomization=100, 1000, 2000, 4000:500, 5000:500"</code></ul>
+ * <li>4 retries for supl APN with a 100 as the default randomization value for the first 2 values
+ * and the other two having specified values of 500:
+ * <ul><li><code>"supl:default_randomization=100, 1000, 2000, 4000:500, 5000:500"</code></ul>
  *
- * <li>Infinite number of retries with the first one at 1000, the second at 2000 all
- * others will be at 3000.
- * <ul><li><code>"max_retries=infinite,1000,2000,3000</code></ul>
+ * <li>Infinite number of retries for all other APNs with the first one at 1000, the second at 2000
+ * all others will be at 3000.
+ * <ul><li><code>"others:max_retries=infinite,1000,2000,3000</code></ul>
  * </ul>
  *
  * {@hide}
@@ -87,18 +90,14 @@
     public static final boolean VDBG = false; // STOPSHIP if true
 
     /**
-     * The default retry configuration for default type APN. See above for the syntax.
+     * The default retry configuration for APNs. See above for the syntax.
      */
-    private static final String DEFAULT_DATA_RETRY_CONFIG = "default_randomization=2000,"
-            + "5000,10000,20000,40000,80000:5000,160000:5000,"
-            + "320000:5000,640000:5000,1280000:5000,1800000:5000";
+    private static final String DEFAULT_DATA_RETRY_CONFIG = "max_retries=3, 5000, 5000, 5000";
 
     /**
-     * Retry configuration for networks other than default type, for example, mms. See above
-     * for the syntax.
+     * The APN type used for all other APNs retry configuration.
      */
-    private static final String OTHERS_DATA_RETRY_CONFIG =
-            "max_retries=3, 5000, 5000, 5000";
+    private static final String OTHERS_APN_TYPE = "others";
 
     /**
      * The default value (in milliseconds) for delay between APN trying (mInterApnDelay)
@@ -313,10 +312,11 @@
 
     /**
      * Configure the retry manager
-     * @param forDefault True if the APN support default type
      */
-    private void configureRetry(boolean forDefault) {
-        String configString = "";
+    private void configureRetry() {
+        String configString = null;
+        String otherConfigString = null;
+
         try {
             if (Build.IS_DEBUGGABLE) {
                 // Using system properties is easier for testing from command line.
@@ -338,22 +338,48 @@
                     CarrierConfigManager.KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG,
                     DEFAULT_INTER_APN_DELAY_FOR_PROVISIONING);
 
-            if (forDefault) {
-                configString = b.getString(
-                        CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                        DEFAULT_DATA_RETRY_CONFIG);
+            // Load all retry patterns for all different APNs.
+            String[] allConfigStrings = b.getStringArray(
+                    CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS);
+            if (allConfigStrings != null) {
+                for (String s : allConfigStrings) {
+                    if (!TextUtils.isEmpty(s)) {
+                        String splitStr[] = s.split(":", 2);
+                        if (splitStr.length == 2) {
+                            String apnType = splitStr[0].trim();
+                            // Check if this retry pattern is for the APN we want.
+                            if (apnType.equals(mApnType)) {
+                                // Extract the config string. Note that an empty string is valid
+                                // here, meaning no retry for the specified APN.
+                                configString = splitStr[1];
+                                break;
+                            } else if (apnType.equals(OTHERS_APN_TYPE)) {
+                                // Extract the config string. Note that an empty string is valid
+                                // here, meaning no retry for all other APNs.
+                                otherConfigString = splitStr[1];
+                            }
+                        }
+                    }
+                }
             }
-            else {
-                configString = b.getString(
-                        CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_OTHERS_STRING,
-                        OTHERS_DATA_RETRY_CONFIG);
+
+            if (configString == null) {
+                if (otherConfigString != null) {
+                    configString = otherConfigString;
+                } else {
+                    // We should never reach here. If we reach here, it must be a configuration
+                    // error bug.
+                    log("Invalid APN retry configuration!. Use the default one now.");
+                    configString = DEFAULT_DATA_RETRY_CONFIG;
+                }
             }
         } catch (NullPointerException ex) {
+            // We should never reach here unless there is a bug
             log("Failed to read configuration! Use the hardcoded default value.");
 
             mInterApnDelay = DEFAULT_INTER_APN_DELAY;
             mFailFastInterApnDelay = DEFAULT_INTER_APN_DELAY_FOR_PROVISIONING;
-            configString = (forDefault) ? DEFAULT_DATA_RETRY_CONFIG : OTHERS_DATA_RETRY_CONFIG;
+            configString = DEFAULT_DATA_RETRY_CONFIG;
         }
 
         if (VDBG) {
@@ -586,7 +612,7 @@
         mWaitingApns = waitingApns;
 
         // Since we replace the entire waiting APN list, we need to re-config this retry manager.
-        configureRetry(mApnType.equals(PhoneConstants.APN_TYPE_DEFAULT));
+        configureRetry();
 
         for (ApnSetting apn : mWaitingApns) {
             apn.permanentFailed = false;
diff --git a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
index 1a1455f..6b00289 100644
--- a/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
+++ b/tests/telephonytests/src/com/android/internal/telephony/dataconnection/RetryManagerTest.java
@@ -147,8 +147,8 @@
     @SmallTest
     public void testRetryManagerEmpty() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "2000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"default:2000"});
 
         RetryManager rm = new RetryManager(mPhone, "default");
 
@@ -168,8 +168,9 @@
     @SmallTest
     public void testRetryManagerOneApnNoRetry() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "");
+        mBundle.putStringArray(
+                CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"default:"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         waitingApns.add(new ApnSetting(mApn1));
@@ -190,13 +191,13 @@
     @SmallTest
     public void testRetryManagerOneApnTwoRetries() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "2000,3000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"supl:2000,3000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         waitingApns.add(new ApnSetting(mApn1));
 
-        RetryManager rm = new RetryManager(mPhone, "default");
+        RetryManager rm = new RetryManager(mPhone, "supl");
         rm.setWaitingApns(waitingApns);
 
         ApnSetting nextApn = rm.getNextApnSetting();
@@ -244,8 +245,8 @@
     @SmallTest
     public void testRetryManagerTwoApnsOneRetry() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "2000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"others:2000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         waitingApns.add(new ApnSetting(mApn1));
@@ -282,14 +283,14 @@
     @SmallTest
     public void testRetryManagerTwoApnsTwoRetries() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "2000,5000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"dun:2000,5000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         waitingApns.add(new ApnSetting(mApn1));
         waitingApns.add(new ApnSetting(mApn2));
 
-        RetryManager rm = new RetryManager(mPhone, "default");
+        RetryManager rm = new RetryManager(mPhone, "dun");
         rm.setWaitingApns(waitingApns);
 
         ApnSetting nextApn = rm.getNextApnSetting();
@@ -324,14 +325,14 @@
     }
 
     /**
-     * Test the basic retry scenario where two mms (non-default) APNs with two retries configured.
+     * Test the basic retry scenario where two mms APNs with two retries configured.
      */
     @Test
     @SmallTest
     public void testRetryManagerTwoMmsApnsTwoRetries() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_OTHERS_STRING,
-                "3000,6000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"mms:      3000,6000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         waitingApns.add(new ApnSetting(mApn1));
@@ -378,14 +379,14 @@
     @SmallTest
     public void testRetryManagerApnPermanentFailed() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "1000,4000,7000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"fota:1000,4000,7000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         ApnSetting apn = new ApnSetting(mApn1);
         waitingApns.add(apn);
 
-        RetryManager rm = new RetryManager(mPhone, "default");
+        RetryManager rm = new RetryManager(mPhone, "fota");
         rm.setWaitingApns(waitingApns);
 
         ApnSetting nextApn = rm.getNextApnSetting();
@@ -411,8 +412,8 @@
     @SmallTest
     public void testRetryManagerApnPermanentFailedWithTwoApns() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "1000,4000,7000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"xyz  :   1000,4000,7000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         ApnSetting myApn1 = new ApnSetting(mApn1);
@@ -420,7 +421,7 @@
         waitingApns.add(myApn1);
         waitingApns.add(myApn2);
 
-        RetryManager rm = new RetryManager(mPhone, "default");
+        RetryManager rm = new RetryManager(mPhone, "xyz");
         rm.setWaitingApns(waitingApns);
 
         ApnSetting nextApn = rm.getNextApnSetting();
@@ -468,8 +469,8 @@
     @SmallTest
     public void testRetryManagerApnPermanentFailedWithThreeApns() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "1000,4000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"default:2000:2000,3000:3000", "ims:1000,4000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         ApnSetting myApn1 = new ApnSetting(mApn1);
@@ -479,7 +480,7 @@
         waitingApns.add(myApn2);
         waitingApns.add(myApn3);
 
-        RetryManager rm = new RetryManager(mPhone, "default");
+        RetryManager rm = new RetryManager(mPhone, "ims");
         rm.setWaitingApns(waitingApns);
 
         ApnSetting nextApn = rm.getNextApnSetting();
@@ -527,8 +528,8 @@
     @SmallTest
     public void testRetryManagerApnPermanentFailedAll() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "1000,4000,7000,9000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"default:1000,4000,7000,9000", "mms:1234,4123"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         ApnSetting myApn1 = new ApnSetting(mApn1);
@@ -582,8 +583,8 @@
     @SmallTest
     public void testRetryManagerDelayWithRandomization() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "default_randomization=1000,3000:2000,6000:3000,10000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"default:default_randomization=1000,3000:2000,6000:3000,10000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         waitingApns.add(new ApnSetting(mApn1));
@@ -619,8 +620,8 @@
     @SmallTest
     public void testRetryManagerRetryForever() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "max_retries=infinite,1000,2000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"default:max_retries=infinite,1000,2000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         waitingApns.add(new ApnSetting(mApn1));
@@ -677,14 +678,14 @@
     @SmallTest
     public void testRetryManagerExplicitMaxRetry() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "max_retries=4,1000,2000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"hipri:  max_retries=4,1000,2000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         waitingApns.add(new ApnSetting(mApn1));
         waitingApns.add(new ApnSetting(mApn2));
 
-        RetryManager rm = new RetryManager(mPhone, "default");
+        RetryManager rm = new RetryManager(mPhone, "hipri");
         rm.setWaitingApns(waitingApns);
 
         ApnSetting nextApn = rm.getNextApnSetting();
@@ -745,8 +746,8 @@
     @SmallTest
     public void testRetryManagerFailFast() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "1000,5000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"default:1000,5000"});
 
         mBundle.putLong(CarrierConfigManager.KEY_CARRIER_DATA_CALL_APN_DELAY_FASTER_LONG, 2000);
 
@@ -795,8 +796,8 @@
     @SmallTest
     public void testRetryManagerApnPermanentFailedAllAndThenReset() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "1000,4000,7000,9000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"dun:1000,4000,7000,9000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         ApnSetting myApn1 = new ApnSetting(mApn1);
@@ -804,7 +805,7 @@
         waitingApns.add(myApn1);
         waitingApns.add(myApn2);
 
-        RetryManager rm = new RetryManager(mPhone, "default");
+        RetryManager rm = new RetryManager(mPhone, "dun");
         rm.setWaitingApns(waitingApns);
 
         ApnSetting nextApn = rm.getNextApnSetting();
@@ -848,8 +849,8 @@
         waitingApns.clear();
         waitingApns.add(myApn3);
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "3000,8000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"dun:3000,8000"});
 
         rm.setWaitingApns(waitingApns);
 
@@ -876,8 +877,8 @@
     @SmallTest
     public void testRetryManagerModemSuggestedRetryOnce() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "1000,4000,7000,9000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"others:1000,4000,7000,9000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         ApnSetting myApn1 = new ApnSetting(mApn1);
@@ -885,7 +886,7 @@
         waitingApns.add(myApn1);
         waitingApns.add(myApn2);
 
-        RetryManager rm = new RetryManager(mPhone, "default");
+        RetryManager rm = new RetryManager(mPhone, "mms");
         rm.setWaitingApns(waitingApns);
 
         ApnSetting nextApn = rm.getNextApnSetting();
@@ -932,8 +933,8 @@
     @SmallTest
     public void testRetryManagerModemSuggestedNoRetry() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "1000,4000,7000,9000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"default:1000,4000,7000,9000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         ApnSetting myApn1 = new ApnSetting(mApn1);
@@ -975,8 +976,8 @@
     @SmallTest
     public void testRetryManagerModemSuggestedRetryTooManyTimes() throws Exception {
 
-        mBundle.putString(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_DEFAULT_STRING,
-                "1000,4000,7000,9000");
+        mBundle.putStringArray(CarrierConfigManager.KEY_CARRIER_DATA_CALL_RETRY_CONFIG_STRINGS,
+                new String[]{"mms:2000,3000", "default:1000,4000,7000,9000"});
 
         ArrayList<ApnSetting> waitingApns = new ArrayList<ApnSetting>();
         ApnSetting myApn1 = new ApnSetting(mApn1);