am d2246930: Merge "Preserve retryCount when retrying." into jb-dev

* commit 'd22469302707d87ee56d7a30dd8b38e671ee0179':
  Preserve retryCount when retrying.
diff --git a/telephony/java/com/android/internal/telephony/ApnContext.java b/telephony/java/com/android/internal/telephony/ApnContext.java
index 3a3044e..9746398 100644
--- a/telephony/java/com/android/internal/telephony/ApnContext.java
+++ b/telephony/java/com/android/internal/telephony/ApnContext.java
@@ -50,6 +50,8 @@
 
     String mReason;
 
+    int mRetryCount;
+
     /**
      * user/app requested connection on this APN
      */
@@ -64,6 +66,7 @@
         mApnType = apnType;
         mState = DataConnectionTracker.State.IDLE;
         setReason(Phone.REASON_DATA_ENABLED);
+        setRetryCount(0);
         mDataEnabled = new AtomicBoolean(false);
         mDependencyMet = new AtomicBoolean(true);
         mWaitingApnsPermanentFailureCountDown = new AtomicInteger(0);
@@ -182,6 +185,21 @@
         return mReason;
     }
 
+    public synchronized void setRetryCount(int retryCount) {
+        if (DBG) {
+            log("setRetryCount: " + retryCount);
+        }
+        mRetryCount = retryCount;
+        DataConnection dc = mDataConnection;
+        if (dc != null) {
+            dc.setRetryCount(retryCount);
+        }
+    }
+
+    public synchronized int getRetryCount() {
+        return mRetryCount;
+    }
+
     public boolean isReady() {
         return mDataEnabled.get() && mDependencyMet.get();
     }
@@ -214,8 +232,8 @@
         return "{mApnType=" + mApnType + " mState=" + getState() + " mWaitingApns=" + mWaitingApns +
                 " mWaitingApnsPermanentFailureCountDown=" + mWaitingApnsPermanentFailureCountDown +
                 " mApnSetting=" + mApnSetting + " mDataConnectionAc=" + mDataConnectionAc +
-                " mReason=" + mReason + " mDataEnabled=" + mDataEnabled +
-                " mDependencyMet=" + mDependencyMet + "}";
+                " mReason=" + mReason + " mRetryCount=" + mRetryCount +
+                " mDataEnabled=" + mDataEnabled + " mDependencyMet=" + mDependencyMet + "}";
     }
 
     protected void log(String s) {
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index a6bd85e..d8aba92 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -445,6 +445,14 @@
     }
 
     /**
+     * set retry manager retryCount
+     */
+    public void setRetryCount(int retryCount) {
+        if (DBG) log("setRetryCount: " + retryCount);
+        mRetryMgr.setRetryCount(retryCount);
+    }
+
+    /**
      * @return retry manager retryTimer
      */
     public int getRetryTimer() {
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 588515b..0dee7a1 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -303,7 +303,8 @@
                                     new HashMap<String, Integer>();
 
     /** Phone.APN_TYPE_* ===> ApnContext */
-    protected ConcurrentHashMap<String, ApnContext> mApnContexts;
+    protected ConcurrentHashMap<String, ApnContext> mApnContexts =
+                                    new ConcurrentHashMap<String, ApnContext>();
 
     /* Currently active APN */
     protected ApnSetting mActiveApn;
@@ -1203,6 +1204,9 @@
     }
 
     protected void resetAllRetryCounts() {
+        for (ApnContext ac : mApnContexts.values()) {
+            ac.setRetryCount(0);
+        }
         for (DataConnection dc : mDataConnections.values()) {
             dc.resetRetryCount();
         }
diff --git a/telephony/java/com/android/internal/telephony/RetryManager.java b/telephony/java/com/android/internal/telephony/RetryManager.java
index ae451b9..250d99e 100644
--- a/telephony/java/com/android/internal/telephony/RetryManager.java
+++ b/telephony/java/com/android/internal/telephony/RetryManager.java
@@ -73,7 +73,7 @@
  * {@hide}
  */
 public class RetryManager {
-    static public final String LOG_TAG = "RetryManager";
+    static public final String LOG_TAG = "GSM";
     static public final boolean DBG = true;
     static public final boolean VDBG = false;
 
@@ -304,7 +304,6 @@
 
     /**
      * Set retry count to the specified value
-     * and turns off retrying forever.
      */
     public void setRetryCount(int count) {
         mRetryCount = count;
@@ -316,11 +315,18 @@
             mRetryCount = 0;
         }
 
-        mRetryForever = false;
         if (DBG) log("setRetryCount: " + mRetryCount);
     }
 
     /**
+     * Set retry forever to the specified value
+     */
+    public void setRetryForever(boolean retryForever) {
+        mRetryForever = retryForever;
+        if (DBG) log("setRetryForever: " + mRetryForever);
+    }
+
+    /**
      * Clear the data-retry counter
      */
     public void resetRetryCount() {
@@ -399,6 +405,6 @@
     }
 
     private void log(String s) {
-        Log.d(LOG_TAG, s);
+        Log.d(LOG_TAG, "[RM] " + s);
     }
 }
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index ed67759..6b863a7 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -134,6 +134,8 @@
     private static final String INTENT_RECONNECT_ALARM =
         "com.android.internal.telephony.gprs-reconnect";
     private static final String INTENT_RECONNECT_ALARM_EXTRA_TYPE = "reconnect_alarm_extra_type";
+    private static final String INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT =
+        "reconnect_alaram_extra_retry_count";
 
     private static final String INTENT_DATA_STALL_ALARM =
         "com.android.internal.telephony.gprs-data-stall";
@@ -148,18 +150,23 @@
 
     @Override
     protected void onActionIntentReconnectAlarm(Intent intent) {
-        if (DBG) log("GPRS reconnect alarm. Previous state was " + mState);
-
         String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
         int connectionId = intent.getIntExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, -1);
+        int retryCount = intent.getIntExtra(INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT, 0);
 
         DataConnectionAc dcac= mDataConnectionAsyncChannels.get(connectionId);
 
+        if (DBG) {
+            log("onActionIntentReconnectAlarm: mState=" + mState + " reason=" + reason +
+                    " connectionId=" + connectionId + " retryCount=" + retryCount);
+        }
+
         if (dcac != null) {
             for (ApnContext apnContext : dcac.getApnListSync()) {
                 apnContext.setDataConnectionAc(null);
                 apnContext.setDataConnection(null);
                 apnContext.setReason(reason);
+                apnContext.setRetryCount(retryCount);
                 if (apnContext.getState() == State.FAILED) {
                     apnContext.setState(State.IDLE);
                 }
@@ -207,7 +214,6 @@
         p.getContext().getContentResolver().registerContentObserver(
                 Telephony.Carriers.CONTENT_URI, true, mApnObserver);
 
-        mApnContexts = new ConcurrentHashMap<String, ApnContext>();
         initApnContextsAndDataConnection();
         broadcastMessenger();
     }
@@ -674,10 +680,15 @@
                         break;
                     }
                 }
-                configureRetry(dcac.dataConnection, hasDefault);
+                configureRetry(dcac.dataConnection, hasDefault, 0);
             }
         }
 
+        // Be sure retry counts for Apncontexts and DC's are sync'd.
+        // When DCT/ApnContexts are refactored and we cleanup retrying
+        // this won't be needed.
+        resetAllRetryCounts();
+
         // Only check for default APN state
         for (ApnContext apnContext : mApnContexts.values()) {
             if (apnContext.getState() == State.FAILED) {
@@ -1078,7 +1089,8 @@
 
         // configure retry count if no other Apn is using the same connection.
         if (refCount == 0) {
-            configureRetry(dc, apn.canHandleType(Phone.APN_TYPE_DEFAULT));
+            configureRetry(dc, apn.canHandleType(Phone.APN_TYPE_DEFAULT),
+                    apnContext.getRetryCount());
         }
         apnContext.setDataConnectionAc(dcac);
         apnContext.setDataConnection(dc);
@@ -1330,7 +1342,7 @@
         startNetStatPoll();
         startDataStallAlarm(DATA_STALL_NOT_SUSPECTED);
         // reset reconnect timer
-        apnContext.getDataConnection().resetRetryCount();
+        apnContext.setRetryCount(0);
     }
 
     // TODO: For multiple Active APNs not exactly sure how to do this.
@@ -1601,6 +1613,10 @@
             loge("reconnectAfterFail: apnContext == null, impossible");
             return;
         }
+        if (DBG) {
+            log("reconnectAfterFail: lastFailCause=" + lastFailCauseCode +
+                    " retryOverride=" + retryOverride + " apnContext=" + apnContext);
+        }
         if ((apnContext.getState() == State.FAILED) &&
             (apnContext.getDataConnection() != null)) {
             if (!apnContext.getDataConnection().isRetryNeeded()) {
@@ -1616,7 +1632,7 @@
                     if (DBG) log("reconnectAfterFail: activate failed, Reregistering to network");
                     mReregisterOnReconnectFailure = true;
                     mPhone.getServiceStateTracker().reRegisterNetwork(null);
-                    apnContext.getDataConnection().resetRetryCount();
+                    apnContext.setRetryCount(0);
                     return;
                 }
             }
@@ -1627,6 +1643,11 @@
             if (nextReconnectDelay < 0) {
                 nextReconnectDelay = apnContext.getDataConnection().getRetryTimer();
                 apnContext.getDataConnection().increaseRetryCount();
+                if (DBG) {
+                    log("reconnectAfterFail: increaseRetryCount=" +
+                            apnContext.getDataConnection().getRetryCount() +
+                            " nextReconnectDelay=" + nextReconnectDelay);
+                }
             }
             startAlarmForReconnect(nextReconnectDelay, apnContext);
 
@@ -1643,16 +1664,11 @@
 
     private void startAlarmForReconnect(int delay, ApnContext apnContext) {
 
-        if (DBG) {
-            log("Schedule alarm for reconnect: activate failed. Scheduling next attempt for "
-                + (delay / 1000) + "s");
-        }
-
         DataConnectionAc dcac = apnContext.getDataConnectionAc();
 
         if ((dcac == null) || (dcac.dataConnection == null)) {
             // should not happen, but just in case.
-            loge("null dcac or dc.");
+            loge("startAlarmForReconnect: null dcac or dc.");
             return;
         }
 
@@ -1661,12 +1677,29 @@
 
         Intent intent = new Intent(INTENT_RECONNECT_ALARM + '.' +
                                    dcac.dataConnection.getDataConnectionId());
-        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, apnContext.getReason());
-        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE,
-                        dcac.dataConnection.getDataConnectionId());
+        String reason = apnContext.getReason();
+        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
+        int connectionId = dcac.dataConnection.getDataConnectionId();
+        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_TYPE, connectionId);
+
+        // TODO: Until a real fix is created, which probably entails pushing
+        // retires into the DC itself, this fix gets the retry count and
+        // puts it in the reconnect alarm. When the reconnect alarm fires
+        // onActionIntentReconnectAlarm is called which will use the value saved
+        // here and save it in the ApnContext and send the EVENT_CONNECT message
+        // which invokes setupData. Then setupData will use the value in the ApnContext
+        // and to tell the DC to set the retry count in the retry manager.
+        int retryCount = dcac.dataConnection.getRetryCount();
+        intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_RETRY_COUNT, retryCount);
+
+        if (DBG) {
+            log("startAlarmForReconnect: next attempt in " + (delay / 1000) + "s" +
+                    " reason='" + reason + "' connectionId=" + connectionId +
+                    " retryCount=" + retryCount);
+        }
 
         PendingIntent alarmIntent = PendingIntent.getBroadcast (mPhone.getContext(), 0,
-                                                                intent, 0);
+                                        intent, PendingIntent.FLAG_UPDATE_CURRENT);
         dcac.setReconnectIntentSync(alarmIntent);
         am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                 SystemClock.elapsedRealtime() + delay, alarmIntent);
@@ -1942,9 +1975,7 @@
         // Make sure our reconnect delay starts at the initial value
         // next time the radio comes on
 
-        for (DataConnection dc : mDataConnections.values()) {
-            dc.resetRetryCount();
-        }
+        resetAllRetryCounts();
         mReregisterOnReconnectFailure = false;
 
         if (mPhone.getSimulatedRadioControl() != null) {
@@ -2287,7 +2318,11 @@
         return conn;
     }
 
-    private void configureRetry(DataConnection dc, boolean forDefault) {
+    private void configureRetry(DataConnection dc, boolean forDefault, int retryCount) {
+        if (DBG) {
+            log("configureRetry: forDefault=" + forDefault + " retryCount=" + retryCount +
+                    " dc=" + dc);
+        }
         if (dc == null) return;
 
         if (!dc.configureRetry(getReryConfig(forDefault))) {
@@ -2307,6 +2342,7 @@
                 }
             }
         }
+        dc.setRetryCount(retryCount);
     }
 
     private void destroyDataConnections() {