13918e13b24d4e7ad410089eb615721ca026bec01Wink Saville/**
23918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * Copyright (C) 2009 The Android Open Source Project
33918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *
43918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
53918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * you may not use this file except in compliance with the License.
63918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * You may obtain a copy of the License at
73918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *
83918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
93918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *
103918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * Unless required by applicable law or agreed to in writing, software
113918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
123918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
133918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * See the License for the specific language governing permissions and
143918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * limitations under the License.
153918e13b24d4e7ad410089eb615721ca026bec01Wink Saville */
163918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
173918e13b24d4e7ad410089eb615721ca026bec01Wink Savillepackage com.android.internal.telephony;
183918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
193918e13b24d4e7ad410089eb615721ca026bec01Wink Savilleimport android.util.Log;
203918e13b24d4e7ad410089eb615721ca026bec01Wink Savilleimport android.util.Pair;
213918e13b24d4e7ad410089eb615721ca026bec01Wink Savilleimport android.text.TextUtils;
223918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
233918e13b24d4e7ad410089eb615721ca026bec01Wink Savilleimport java.util.Random;
243918e13b24d4e7ad410089eb615721ca026bec01Wink Savilleimport java.util.ArrayList;
253918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
263918e13b24d4e7ad410089eb615721ca026bec01Wink Saville/**
273918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * Retry manager allows a simple way to declare a series of
28390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby * retry timeouts. After creating a RetryManager the configure
293918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * method is used to define the sequence. A simple linear series
303918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * may be initialized using configure with three integer parameters
313918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * The other configure method allows a series to be declared using
323918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * a string.
333918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *<p>
343918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * The format of the configuration string is a series of parameters
353918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * separated by a comma. There are two name value pair parameters plus a series
363918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * of delay times. The units of of these delay times is unspecified.
373918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * The name value pairs which may be specified are:
383918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *<ul>
393918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *<li>max_retries=<value>
403918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *<li>default_randomizationTime=<value>
413918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *</ul>
423918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *<p>
433918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * max_retries is the number of times that incrementRetryCount
44a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville * maybe called before isRetryNeeded will return false. if value
45a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville * is infinite then isRetryNeeded will always return true.
463918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *
473918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * default_randomizationTime will be used as the randomizationTime
483918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * for delay times which have no supplied randomizationTime. If
493918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * default_randomizationTime is not defined it defaults to 0.
503918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *<p>
513918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * The other parameters define The series of delay times and each
523918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * may have an optional randomization value separated from the
533918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * delay time by a colon.
543918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *<p>
553918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * Examples:
563918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * <ul>
57390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby * <li>3 retries with no randomization value which means its 0:
583918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * <ul><li><code>"1000, 2000, 3000"</code></ul>
593918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *
60390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby * <li>10 retries with a 500 default randomization value for each and
613918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * the 4..10 retries all using 3000 as the delay:
623918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * <ul><li><code>"max_retries=10, default_randomization=500, 1000, 2000, 3000"</code></ul>
633918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *
64390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby * <li>4 retries with a 100 as the default randomization value for the first 2 values and
65a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville * the other two having specified values of 500:
663918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * <ul><li><code>"default_randomization=100, 1000, 2000, 4000:500, 5000:500"</code></ul>
67a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville *
68390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby * <li>Infinite number of retries with the first one at 1000, the second at 2000 all
69a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville * others will be at 3000.
70a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville * <ul><li><code>"max_retries=infinite,1000,2000,3000</code></ul>
713918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * </ul>
723918e13b24d4e7ad410089eb615721ca026bec01Wink Saville *
733918e13b24d4e7ad410089eb615721ca026bec01Wink Saville * {@hide}
743918e13b24d4e7ad410089eb615721ca026bec01Wink Saville */
753918e13b24d4e7ad410089eb615721ca026bec01Wink Savillepublic class RetryManager {
763918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    static public final String LOG_TAG = "RetryManager";
773918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    static public final boolean DBG = false;
783918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
793918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
803918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Retry record with times in milli-seconds
813918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
823918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private static class RetryRec {
833918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        RetryRec(int delayTime, int randomizationTime) {
843918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            mDelayTime = delayTime;
853918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            mRandomizationTime = randomizationTime;
863918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
873918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
883918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        int mDelayTime;
893918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        int mRandomizationTime;
903918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
913918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
923918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /** The array of retry records */
933918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private ArrayList<RetryRec> mRetryArray = new ArrayList<RetryRec>();
943918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
953918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /** When true isRetryNeeded() will always return true */
963918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private boolean mRetryForever;
973918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
983918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
993918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * The maximum number of retries to attempt before
1003918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * isRetryNeeded returns false
1013918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
1023918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private int mMaxRetryCount;
1033918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
104390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby    /** The current number of retries */
1053918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private int mRetryCount;
1063918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1073918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /** Random number generator */
1083918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private Random rng = new Random();
1093918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1103918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /** Constructor */
1113918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public RetryManager() {
1123918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("constructor");
1133918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
1143918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1153918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
1163918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Configure for a simple linear sequence of times plus
1173918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * a random value.
1183918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     *
1193918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @param maxRetryCount is the maximum number of retries
1203918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     *        before isRetryNeeded returns false.
1213918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @param retryTime is a time that will be returned by getRetryTime.
1223918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @param randomizationTime a random value between 0 and
1233918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     *        randomizationTime will be added to retryTime. this
1243918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     *        parameter may be 0.
125390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby     * @return true if successful
1263918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
1273918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public boolean configure(int maxRetryCount, int retryTime, int randomizationTime) {
1283918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        Pair<Boolean, Integer> value;
1293918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1303918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("configure: " + maxRetryCount + ", " + retryTime + "," + randomizationTime);
1313918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1323918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (!validateNonNegativeInt("maxRetryCount", maxRetryCount)) {
1333918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            return false;
1343918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
1353918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1363918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (!validateNonNegativeInt("retryTime", retryTime)) {
1373918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            return false;
1383918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
1393918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1403918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (!validateNonNegativeInt("randomizationTime", randomizationTime)) {
1413918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            return false;
1423918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
1433918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1443918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mMaxRetryCount = maxRetryCount;
1453918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        resetRetryCount();
1463918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mRetryArray.clear();
1473918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mRetryArray.add(new RetryRec(retryTime, randomizationTime));
1483918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1493918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        return true;
1503918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
1513918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1523918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
15301b6d244174b4fe5434593fc89189ba94bc76e7dWink Saville     * Configure for using string which allow arbitrary
1543918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * sequences of times. See class comments for the
1553918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * string format.
1563918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     *
15701b6d244174b4fe5434593fc89189ba94bc76e7dWink Saville     * @return true if successful
1583918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
1593918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public boolean configure(String configStr) {
16001b6d244174b4fe5434593fc89189ba94bc76e7dWink Saville        // Strip quotes if present.
16101b6d244174b4fe5434593fc89189ba94bc76e7dWink Saville        if ((configStr.startsWith("\"") && configStr.endsWith("\""))) {
16201b6d244174b4fe5434593fc89189ba94bc76e7dWink Saville            configStr = configStr.substring(1, configStr.length()-1);
16301b6d244174b4fe5434593fc89189ba94bc76e7dWink Saville        }
1643918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("configure: '" + configStr + "'");
1653918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1663918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (!TextUtils.isEmpty(configStr)) {
1673918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            int defaultRandomization = 0;
1683918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1693918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            if (DBG) log("configure: not empty");
1703918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1713918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            mMaxRetryCount = 0;
1723918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            resetRetryCount();
1733918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            mRetryArray.clear();
1743918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
1753918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            String strArray[] = configStr.split(",");
1763918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            for (int i = 0; i < strArray.length; i++) {
1773918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                if (DBG) log("configure: strArray[" + i + "]='" + strArray[i] + "'");
1783918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                Pair<Boolean, Integer> value;
1793918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                String splitStr[] = strArray[i].split("=", 2);
1803918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                splitStr[0] = splitStr[0].trim();
1813918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                if (DBG) log("configure: splitStr[0]='" + splitStr[0] + "'");
1823918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                if (splitStr.length > 1) {
1833918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    splitStr[1] = splitStr[1].trim();
1843918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    if (DBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
1853918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    if (TextUtils.equals(splitStr[0], "default_randomization")) {
1863918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        value = parseNonNegativeInt(splitStr[0], splitStr[1]);
1873918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        if (!value.first) return false;
1883918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        defaultRandomization = value.second;
1893918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    } else if (TextUtils.equals(splitStr[0], "max_retries")) {
190a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville                        if (TextUtils.equals("infinite",splitStr[1])) {
191a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville                            mRetryForever = true;
192a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville                        } else {
193a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville                            value = parseNonNegativeInt(splitStr[0], splitStr[1]);
194a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville                            if (!value.first) return false;
195a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville                            mMaxRetryCount = value.second;
196a03ab1a6a07614f3d588232e12d9c45d840bae82Wink Saville                        }
1973918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    } else {
1983918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        Log.e(LOG_TAG, "Unrecognized configuration name value pair: "
1993918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                                        + strArray[i]);
2003918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        return false;
2013918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    }
2023918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                } else {
2033918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    /**
2043918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                     * Assume a retry time with an optional randomization value
2053918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                     * following a ":"
2063918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                     */
2073918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    splitStr = strArray[i].split(":", 2);
2083918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    splitStr[0] = splitStr[0].trim();
2093918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    RetryRec rr = new RetryRec(0, 0);
2103918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    value = parseNonNegativeInt("delayTime", splitStr[0]);
2113918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    if (!value.first) return false;
2123918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    rr.mDelayTime = value.second;
2133918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
2143918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    // Check if optional randomization value present
2153918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    if (splitStr.length > 1) {
2163918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        splitStr[1] = splitStr[1].trim();
2173918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        if (DBG) log("configure: splitStr[1]='" + splitStr[1] + "'");
2183918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        value = parseNonNegativeInt("randomizationTime", splitStr[1]);
2193918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        if (!value.first) return false;
2203918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        rr.mRandomizationTime = value.second;
2213918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    } else {
2223918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                        rr.mRandomizationTime = defaultRandomization;
2233918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    }
2243918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    mRetryArray.add(rr);
2253918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                }
2263918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            }
2273918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            if (mRetryArray.size() > mMaxRetryCount) {
2283918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                mMaxRetryCount = mRetryArray.size();
2293918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                if (DBG) log("configure: setting mMaxRetryCount=" + mMaxRetryCount);
2303918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            }
2313918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            if (DBG) log("configure: true");
2323918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            return true;
2333918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        } else {
2343918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            if (DBG) log("configure: false it's empty");
2353918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            return false;
2363918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
2373918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
2383918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
2393918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
2403918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Report whether data reconnection should be retried
2413918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     *
242390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby     * @return {@code true} if the max retries has not been reached. {@code
2433918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     *         false} otherwise.
2443918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
2453918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public boolean isRetryNeeded() {
2463918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        boolean retVal = mRetryForever || (mRetryCount < mMaxRetryCount);
2473918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("isRetryNeeded: " + retVal);
2483918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        return retVal;
2493918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
2503918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
2513918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
2523918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Return the timer that should be used to trigger the data reconnection
2533918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
2543918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public int getRetryTimer() {
2553918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        int index;
2563918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (mRetryCount < mRetryArray.size()) {
2573918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            index = mRetryCount;
2583918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        } else {
2593918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            index = mRetryArray.size() - 1;
2603918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
2613918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
2623918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        int retVal;
2633918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if ((index >= 0) && (index < mRetryArray.size())) {
2643918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            retVal = mRetryArray.get(index).mDelayTime + nextRandomizationTime(index);
2653918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        } else {
2663918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            retVal = 0;
2673918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
2683918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
2693918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("getRetryTimer: " + retVal);
2703918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        return retVal;
2713918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
2723918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
2733918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
2743918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @return retry count
2753918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
2763918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public int getRetryCount() {
2773918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("getRetryCount: " + mRetryCount);
2783918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        return mRetryCount;
2793918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
2803918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
2813918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
2823918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Increase the retry counter, does not change retry forever.
2833918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
2843918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public void increaseRetryCount() {
2853918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mRetryCount++;
2863918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (mRetryCount > mMaxRetryCount) {
2873918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            mRetryCount = mMaxRetryCount;
2883918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
289390de220248d05ccb9dc10a197700ad3c1595937Jake Hamby        if (DBG) log("increaseRetryCount: " + mRetryCount);
2903918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
2913918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
2923918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
2933918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Set retry count to the specified value
2943918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * and turns off retrying forever.
2953918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
2963918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public void setRetryCount(int count) {
2973918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mRetryCount = count;
2983918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (mRetryCount > mMaxRetryCount) {
2993918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            mRetryCount = mMaxRetryCount;
3003918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
3013918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
3023918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (mRetryCount < 0) {
3033918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            mRetryCount = 0;
3043918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
3053918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
3063918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mRetryForever = false;
3073918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("setRetryCount: " + mRetryCount);
3083918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
3093918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
3103918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
3113918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Reset network re-registration indicator and clear the data-retry counter
3123918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * and turns off retrying forever.
3133918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
3143918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public void resetRetryCount() {
3153918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mRetryCount = 0;
3163918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mRetryForever = false;
3173918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("resetRetryCount: " + mRetryCount);
3183918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
3193918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
3203918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
3213918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Retry forever using last timeout time.
3223918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
3233918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public void retryForeverUsingLastTimeout() {
3243918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mRetryCount = mMaxRetryCount;
3253918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        mRetryForever = true;
3263918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("retryForeverUsingLastTimeout: " + mRetryForever + ", " + mRetryCount);
3273918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
3283918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
3293918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
3303918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @return true if retrying forever
3313918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
3323918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    public boolean isRetryForever() {
3333918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("isRetryForever: " + mRetryForever);
3343918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        return mRetryForever;
3353918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
3363918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
3373918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
3383918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Parse an integer validating the value is not negative.
3393918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     *
3403918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @param name
3413918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @param stringValue
3423918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @return Pair.first == true if stringValue an integer >= 0
3433918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
3443918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private Pair<Boolean, Integer> parseNonNegativeInt(String name, String stringValue) {
3453918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        int value;
3463918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        Pair<Boolean, Integer> retVal;
3473918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        try {
3483918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            value = Integer.parseInt(stringValue);
3493918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            retVal = new Pair<Boolean, Integer>(validateNonNegativeInt(name, value), value);
3503918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        } catch (NumberFormatException e) {
3513918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            Log.e(LOG_TAG, name + " bad value: " + stringValue, e);
3523918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            retVal = new Pair<Boolean, Integer>(false, 0);
3533918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
3543918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("parseNonNetativeInt: " + name + ", " + stringValue + ", "
3553918e13b24d4e7ad410089eb615721ca026bec01Wink Saville                    + retVal.first + ", " + retVal.second);
3563918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        return retVal;
3573918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
3583918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
3593918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
3603918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Validate an integer is >= 0 and logs an error if not
3613918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     *
3623918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @param name
3633918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @param value
3643918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * @return Pair.first
3653918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
3663918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private boolean validateNonNegativeInt(String name, int value) {
3673918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        boolean retVal;
3683918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (value < 0) {
3693918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            Log.e(LOG_TAG, name + " bad value: is < 0");
3703918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            retVal = false;
3713918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        } else {
3723918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            retVal = true;
3733918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
3743918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (DBG) log("validateNonNegative: " + name + ", " + value + ", " + retVal);
3753918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        return retVal;
3763918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
3773918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
3783918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    /**
3793918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     * Return next random number for the index
3803918e13b24d4e7ad410089eb615721ca026bec01Wink Saville     */
3813918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private int nextRandomizationTime(int index) {
3823918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        int randomTime = mRetryArray.get(index).mRandomizationTime;
3833918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        if (randomTime == 0) {
3843918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            return 0;
3853918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        } else {
3863918e13b24d4e7ad410089eb615721ca026bec01Wink Saville            return rng.nextInt(randomTime);
3873918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        }
3883918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
3893918e13b24d4e7ad410089eb615721ca026bec01Wink Saville
3903918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    private void log(String s) {
3913918e13b24d4e7ad410089eb615721ca026bec01Wink Saville        Log.d(LOG_TAG, s);
3923918e13b24d4e7ad410089eb615721ca026bec01Wink Saville    }
3933918e13b24d4e7ad410089eb615721ca026bec01Wink Saville}
394