10825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 20825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Copyright (C) 2009 The Android Open Source Project 30825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 40825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Licensed under the Apache License, Version 2.0 (the "License"); 50825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * you may not use this file except in compliance with the License. 60825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * You may obtain a copy of the License at 70825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 80825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * http://www.apache.org/licenses/LICENSE-2.0 90825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Unless required by applicable law or agreed to in writing, software 110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * distributed under the License is distributed on an "AS IS" BASIS, 120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * See the License for the specific language governing permissions and 140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * limitations under the License. 150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 170825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepackage com.android.internal.telephony; 180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 190825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Log; 200825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.util.Pair; 210825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport android.text.TextUtils; 220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 230825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.Random; 240825495a331bb44df395a0cdb79fab85e68db5d5Wink Savilleimport java.util.ArrayList; 250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville/** 270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Retry manager allows a simple way to declare a series of 280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * retry timeouts. After creating a RetryManager the configure 290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * method is used to define the sequence. A simple linear series 300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * may be initialized using configure with three integer parameters 310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The other configure method allows a series to be declared using 320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * a string. 330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *<p> 340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The format of the configuration string is a series of parameters 350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * separated by a comma. There are two name value pair parameters plus a series 360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * of delay times. The units of of these delay times is unspecified. 370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The name value pairs which may be specified are: 380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *<ul> 390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *<li>max_retries=<value> 400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *<li>default_randomizationTime=<value> 410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *</ul> 420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *<p> 430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * max_retries is the number of times that incrementRetryCount 440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * maybe called before isRetryNeeded will return false. if value 450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * is infinite then isRetryNeeded will always return true. 460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * default_randomizationTime will be used as the randomizationTime 480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * for delay times which have no supplied randomizationTime. If 490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * default_randomizationTime is not defined it defaults to 0. 500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *<p> 510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The other parameters define The series of delay times and each 520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * may have an optional randomization value separated from the 530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * delay time by a colon. 540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville *<p> 550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Examples: 560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <ul> 570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <li>3 retries with no randomization value which means its 0: 580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <ul><li><code>"1000, 2000, 3000"</code></ul> 590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <li>10 retries with a 500 default randomization value for each and 610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the 4..10 retries all using 3000 as the delay: 620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <ul><li><code>"max_retries=10, default_randomization=500, 1000, 2000, 3000"</code></ul> 630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <li>4 retries with a 100 as the default randomization value for the first 2 values and 650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * the other two having specified values of 500: 660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <ul><li><code>"default_randomization=100, 1000, 2000, 4000:500, 5000:500"</code></ul> 670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <li>Infinite number of retries with the first one at 1000, the second at 2000 all 690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * others will be at 3000. 700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * <ul><li><code>"max_retries=infinite,1000,2000,3000</code></ul> 710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * </ul> 720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * {@hide} 740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 750825495a331bb44df395a0cdb79fab85e68db5d5Wink Savillepublic class RetryManager { 760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static public final String LOG_TAG = "GSM"; 770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static public final boolean DBG = true; 780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville static public final boolean VDBG = false; 790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Retry record with times in milli-seconds 820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private static class RetryRec { 840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville RetryRec(int delayTime, int randomizationTime) { 850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mDelayTime = delayTime; 860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRandomizationTime = randomizationTime; 870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int mDelayTime; 900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int mRandomizationTime; 910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** The array of retry records */ 940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private ArrayList<RetryRec> mRetryArray = new ArrayList<RetryRec>(); 950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** When true isRetryNeeded() will always return true */ 970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean mRetryForever; 980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * The maximum number of retries to attempt before 1010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * isRetryNeeded returns false 1020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int mMaxRetryCount; 1040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** The current number of retries */ 1060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int mRetryCount; 1070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Random number generator */ 1090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Random rng = new Random(); 1100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private String mConfig; 1120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** Constructor */ 1140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public RetryManager() { 1150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("constructor"); 1160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public String toString() { 1190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String ret = "RetryManager: forever=" + mRetryForever + ", maxRetry=" + mMaxRetryCount + 1200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ", retry=" + mRetryCount + ",\n " + mConfig; 1210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (RetryRec r : mRetryArray) { 1220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville ret += "\n " + r.mDelayTime + ":" + r.mRandomizationTime; 1230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return ret; 1250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Configure for a simple linear sequence of times plus 1290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * a random value. 1300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param maxRetryCount is the maximum number of retries 1320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * before isRetryNeeded returns false. 1330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param retryTime is a time that will be returned by getRetryTime. 1340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param randomizationTime a random value between 0 and 1350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * randomizationTime will be added to retryTime. this 1360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * parameter may be 0. 1370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if successful 1380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean configure(int maxRetryCount, int retryTime, int randomizationTime) { 1400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Pair<Boolean, Integer> value; 1410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: " + maxRetryCount + ", " + retryTime + "," + randomizationTime); 1430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!validateNonNegativeInt("maxRetryCount", maxRetryCount)) { 1450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 1460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!validateNonNegativeInt("retryTime", retryTime)) { 1490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 1500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!validateNonNegativeInt("randomizationTime", randomizationTime)) { 1530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 1540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMaxRetryCount = maxRetryCount; 1570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resetRetryCount(); 1580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryArray.clear(); 1590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryArray.add(new RetryRec(retryTime, randomizationTime)); 1600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 1620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 1650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Configure for using string which allow arbitrary 1660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * sequences of times. See class comments for the 1670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * string format. 1680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 1690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if successful 1700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 1710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean configure(String configStr) { 1720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Strip quotes if present. 1730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((configStr.startsWith("\"") && configStr.endsWith("\""))) { 1740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville configStr = configStr.substring(1, configStr.length()-1); 1750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 1760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: '" + configStr + "'"); 1770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mConfig = configStr; 1780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!TextUtils.isEmpty(configStr)) { 1800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int defaultRandomization = 0; 1810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: not empty"); 1830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMaxRetryCount = 0; 1850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville resetRetryCount(); 1860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryArray.clear(); 1870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 1880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String strArray[] = configStr.split(","); 1890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville for (int i = 0; i < strArray.length; i++) { 1900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: strArray[" + i + "]='" + strArray[i] + "'"); 1910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Pair<Boolean, Integer> value; 1920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville String splitStr[] = strArray[i].split("=", 2); 1930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville splitStr[0] = splitStr[0].trim(); 1940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: splitStr[0]='" + splitStr[0] + "'"); 1950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (splitStr.length > 1) { 1960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville splitStr[1] = splitStr[1].trim(); 1970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'"); 1980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (TextUtils.equals(splitStr[0], "default_randomization")) { 1990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville value = parseNonNegativeInt(splitStr[0], splitStr[1]); 2000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!value.first) return false; 2010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville defaultRandomization = value.second; 2020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else if (TextUtils.equals(splitStr[0], "max_retries")) { 2030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (TextUtils.equals("infinite",splitStr[1])) { 2040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryForever = true; 2050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville value = parseNonNegativeInt(splitStr[0], splitStr[1]); 2070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!value.first) return false; 2080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMaxRetryCount = value.second; 2090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, "Unrecognized configuration name value pair: " 2120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + strArray[i]); 2130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 2140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Assume a retry time with an optional randomization value 2180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * following a ":" 2190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville splitStr = strArray[i].split(":", 2); 2210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville splitStr[0] = splitStr[0].trim(); 2220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville RetryRec rr = new RetryRec(0, 0); 2230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville value = parseNonNegativeInt("delayTime", splitStr[0]); 2240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!value.first) return false; 2250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville rr.mDelayTime = value.second; 2260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville // Check if optional randomization value present 2280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (splitStr.length > 1) { 2290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville splitStr[1] = splitStr[1].trim(); 2300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: splitStr[1]='" + splitStr[1] + "'"); 2310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville value = parseNonNegativeInt("randomizationTime", splitStr[1]); 2320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (!value.first) return false; 2330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville rr.mRandomizationTime = value.second; 2340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville rr.mRandomizationTime = defaultRandomization; 2360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryArray.add(rr); 2380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mRetryArray.size() > mMaxRetryCount) { 2410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mMaxRetryCount = mRetryArray.size(); 2420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: setting mMaxRetryCount=" + mMaxRetryCount); 2430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: true"); 2450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return true; 2460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("configure: false it's empty"); 2480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return false; 2490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Report whether data reconnection should be retried 2540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 2550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return {@code true} if the max retries has not been reached. {@code 2560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * false} otherwise. 2570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isRetryNeeded() { 2590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean retVal = mRetryForever || (mRetryCount < mMaxRetryCount); 2600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("isRetryNeeded: " + retVal); 2610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return retVal; 2620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return the timer that should be used to trigger the data reconnection 2660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int getRetryTimer() { 2680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int index; 2690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mRetryCount < mRetryArray.size()) { 2700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville index = mRetryCount; 2710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville index = mRetryArray.size() - 1; 2730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int retVal; 2760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if ((index >= 0) && (index < mRetryArray.size())) { 2770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville retVal = mRetryArray.get(index).mDelayTime + nextRandomizationTime(index); 2780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 2790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville retVal = 0; 2800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("getRetryTimer: " + retVal); 2830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return retVal; 2840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return retry count 2880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public int getRetryCount() { 2900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("getRetryCount: " + mRetryCount); 2910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mRetryCount; 2920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 2930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 2940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 2950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Increase the retry counter, does not change retry forever. 2960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 2970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void increaseRetryCount() { 2980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryCount++; 2990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mRetryCount > mMaxRetryCount) { 3000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryCount = mMaxRetryCount; 3010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("increaseRetryCount: " + mRetryCount); 3030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Set retry count to the specified value 3070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void setRetryCount(int count) { 3090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryCount = count; 3100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mRetryCount > mMaxRetryCount) { 3110825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryCount = mMaxRetryCount; 3120825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3130825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3140825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (mRetryCount < 0) { 3150825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryCount = 0; 3160825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3170825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3180825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("setRetryCount: " + mRetryCount); 3190825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3200825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3210825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3220825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Set retry forever to the specified value 3230825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3240825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void setRetryForever(boolean retryForever) { 3250825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryForever = retryForever; 3260825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("setRetryForever: " + mRetryForever); 3270825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3280825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3290825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3300825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Clear the data-retry counter 3310825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3320825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void resetRetryCount() { 3330825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryCount = 0; 3340825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("resetRetryCount: " + mRetryCount); 3350825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3360825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3370825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3380825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Retry forever using last timeout time. 3390825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3400825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public void retryForeverUsingLastTimeout() { 3410825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryCount = mMaxRetryCount; 3420825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville mRetryForever = true; 3430825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("retryForeverUsingLastTimeout: " + mRetryForever + ", " + mRetryCount); 3440825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3450825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3460825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3470825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return true if retrying forever 3480825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3490825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville public boolean isRetryForever() { 3500825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (DBG) log("isRetryForever: " + mRetryForever); 3510825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return mRetryForever; 3520825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3530825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3540825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3550825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Parse an integer validating the value is not negative. 3560825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3570825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param name 3580825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param stringValue 3590825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return Pair.first == true if stringValue an integer >= 0 3600825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3610825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private Pair<Boolean, Integer> parseNonNegativeInt(String name, String stringValue) { 3620825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int value; 3630825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Pair<Boolean, Integer> retVal; 3640825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville try { 3650825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville value = Integer.parseInt(stringValue); 3660825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville retVal = new Pair<Boolean, Integer>(validateNonNegativeInt(name, value), value); 3670825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } catch (NumberFormatException e) { 3680825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, name + " bad value: " + stringValue, e); 3690825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville retVal = new Pair<Boolean, Integer>(false, 0); 3700825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3710825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("parseNonNetativeInt: " + name + ", " + stringValue + ", " 3720825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville + retVal.first + ", " + retVal.second); 3730825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return retVal; 3740825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3750825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3760825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3770825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Validate an integer is >= 0 and logs an error if not 3780825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * 3790825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param name 3800825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @param value 3810825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * @return Pair.first 3820825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3830825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private boolean validateNonNegativeInt(String name, int value) { 3840825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville boolean retVal; 3850825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (value < 0) { 3860825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.e(LOG_TAG, name + " bad value: is < 0"); 3870825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville retVal = false; 3880825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 3890825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville retVal = true; 3900825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3910825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (VDBG) log("validateNonNegative: " + name + ", " + value + ", " + retVal); 3920825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return retVal; 3930825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 3940825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 3950825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville /** 3960825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville * Return next random number for the index 3970825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville */ 3980825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private int nextRandomizationTime(int index) { 3990825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville int randomTime = mRetryArray.get(index).mRandomizationTime; 4000825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville if (randomTime == 0) { 4010825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return 0; 4020825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } else { 4030825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville return rng.nextInt(randomTime); 4040825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4050825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4060825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville 4070825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville private void log(String s) { 4080825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville Log.d(LOG_TAG, "[RM] " + s); 4090825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville } 4100825495a331bb44df395a0cdb79fab85e68db5d5Wink Saville} 411