Add more data stall recovery info

- add recovered: Whether the data stall is recovered.
- add duration: The elapsed time between start of the
                data stall and result of current action.
Bug: 178670946
Test: atest FrameworksTelephonyTests
Change-Id: If5c7e8d21164c418da1130be4adc023b8946fe16
Merged-In: If5c7e8d21164c418da1130be4adc023b8946fe16
(cherry picked from commit 305b720191cf01c07b53e3e629e86fe45bb44964)
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 4d4ca81..d528ae0 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -4973,6 +4973,14 @@
         private long mTimeLastRecoveryStartMs;
         // Whether current network good or not
         private boolean mIsValidNetwork;
+        // Whether data stall happened or not.
+        private boolean mWasDataStall;
+        // Whether the result of last action(RADIO_RESTART) reported.
+        private boolean mLastActionReported;
+        // The real time for data stall start.
+        private long mDataStallStartMs;
+        // Last data stall action.
+        private @RecoveryAction int mLastAction;
 
         public DataStallRecoveryHandler() {
             reset();
@@ -4983,6 +4991,36 @@
             putRecoveryAction(RECOVERY_ACTION_GET_DATA_CALL_LIST);
         }
 
+        private void setNetworkValidationState(boolean isValid) {
+            // Validation status is true and was not data stall.
+            if (isValid && !mWasDataStall) {
+                return;
+            }
+
+            if (!mWasDataStall) {
+                mWasDataStall = true;
+                mDataStallStartMs = SystemClock.elapsedRealtime();
+                if (DBG) log("data stall: start time = " + mDataStallStartMs);
+                return;
+            }
+
+            if (!mLastActionReported) {
+                int timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs);
+                if (DBG) {
+                    log("data stall: lastaction = " + mLastAction + ", isRecovered = "
+                            + isValid + ", mTimeDuration = " + timeDuration);
+                }
+                DataStallRecoveryStats.onDataStallEvent(mLastAction, mPhone, isValid,
+                                                        timeDuration);
+                mLastActionReported = true;
+            }
+
+            if (isValid) {
+                mLastActionReported = false;
+                mWasDataStall = false;
+            }
+        }
+
         public boolean isAggressiveRecovery() {
             @RecoveryAction int action = getRecoveryAction();
 
@@ -5059,7 +5097,8 @@
                         mPhone.getPhoneId(), signalStrength);
                 TelephonyMetrics.getInstance().writeDataStallEvent(
                         mPhone.getPhoneId(), recoveryAction);
-                DataStallRecoveryStats.onDataStallEvent(recoveryAction, mPhone);
+                mLastAction = recoveryAction;
+                mLastActionReported = false;
                 broadcastDataStallDetected(recoveryAction);
 
                 switch (recoveryAction) {
@@ -5103,6 +5142,7 @@
         }
 
         public void processNetworkStatusChanged(boolean isValid) {
+            setNetworkValidationState(isValid);
             if (isValid) {
                 mIsValidNetwork = true;
                 reset();
diff --git a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
index 9074a7b..410afcf 100644
--- a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
+++ b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
@@ -36,7 +36,7 @@
      * @param phone
      */
     public static void onDataStallEvent(@DcTracker.RecoveryAction int recoveryAction,
-            Phone phone) {
+            Phone phone, boolean isRecovered, int durationMillis) {
         if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
             phone = phone.getDefaultPhone();
         }
@@ -50,7 +50,8 @@
         boolean isMultiSim = SimSlotState.getCurrentState().numActiveSims > 1;
 
         TelephonyStatsLog.write(TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED, carrierId, rat,
-                signalStrength, recoveryAction, isOpportunistic, isMultiSim, band);
+                signalStrength, recoveryAction, isOpportunistic, isMultiSim, band, isRecovered,
+                durationMillis);
     }
 
     /** Returns the RAT used for data (including IWLAN). */