Add metrics for data stall recovery enhancement

MDR: https://eldar.corp.google.com/assessments/296451350/drafts/988759905?jsmode=o

Bug: 262382363
Test: atest DataStallRecoveryManagerTest passed
Change-Id: I173e936315c9976a4dcbc592273e74388233f90b
Merged-In: I173e936315c9976a4dcbc592273e74388233f90b
diff --git a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
index e467815..753abd8 100644
--- a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
@@ -587,39 +587,55 @@
      * @param isValid true for validation passed & false for validation failed
      */
     private void setNetworkValidationState(boolean isValid) {
+        boolean isLogNeeded = false;
+        int timeDuration = 0;
+        boolean isFirstDataStall = false;
+        boolean isFirstValidationAfterDoRecovery = false;
+        @RecoveredReason int reason = getRecoveredReason(isValid);
         // Validation status is true and was not data stall.
         if (isValid && !mDataStalled) {
             return;
         }
 
         if (!mDataStalled) {
+            // First data stall
+            isLogNeeded = true;
             mDataStalled = true;
-            mDataStallStartMs = SystemClock.elapsedRealtime();
-            logl("data stall: start time = " + DataUtils.elapsedTimeToString(mDataStallStartMs));
-            return;
-        }
-
-        if (!mLastActionReported) {
-            @RecoveredReason int reason = getRecoveredReason(isValid);
-            int timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs);
-            logl(
-                    "data stall: lastaction = "
-                            + recoveryActionToString(mLastAction)
-                            + ", isRecovered = "
-                            + isValid
-                            + ", reason = "
-                            + recoveredReasonToString(reason)
-                            + ", TimeDuration = "
-                            + timeDuration);
-            DataStallRecoveryStats.onDataStallEvent(
-                    mLastAction, mPhone, isValid, timeDuration, reason);
+            isFirstDataStall = true;
+        } else if (!mLastActionReported) {
+            // When the first validation status appears, enter this block.
+            isLogNeeded = true;
+            timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs);
             mLastActionReported = true;
+            isFirstValidationAfterDoRecovery = true;
         }
 
         if (isValid) {
+            // When the validation passed(mobile data resume), enter this block.
+            isLogNeeded = true;
+            timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs);
             mLastActionReported = false;
             mDataStalled = false;
         }
+
+        if (isLogNeeded) {
+            DataStallRecoveryStats.onDataStallEvent(
+                    mLastAction, mPhone, isValid, timeDuration, reason,
+                    isFirstValidationAfterDoRecovery);
+            logl(
+                    "data stall: "
+                    + (isFirstDataStall == true ? "start" : isValid == false ? "in process" : "end")
+                    + ", lastaction="
+                    + recoveryActionToString(mLastAction)
+                    + ", isRecovered="
+                    + isValid
+                    + ", reason="
+                    + recoveredReasonToString(reason)
+                    + ", isFirstValidationAfterDoRecovery="
+                    + isFirstValidationAfterDoRecovery
+                    + ", TimeDuration="
+                    + timeDuration);
+        }
     }
 
     /**
diff --git a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
index ee4e842..6637cb5 100644
--- a/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
+++ b/src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java
@@ -52,13 +52,15 @@
      * @param isRecovered The data stall symptom recovered or not.
      * @param durationMillis The duration from data stall symptom occurred.
      * @param reason The recovered(data resume) reason.
+     * @param isFirstValidation The validation status if it's the first come after recovery.
      */
     public static void onDataStallEvent(
             @DataStallRecoveryManager.RecoveryAction int recoveryAction,
             Phone phone,
             boolean isRecovered,
             int durationMillis,
-            @DataStallRecoveryManager.RecoveredReason int reason) {
+            @DataStallRecoveryManager.RecoveredReason int reason,
+            boolean isFirstValidation) {
         if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_IMS) {
             phone = phone.getDefaultPhone();
         }
@@ -97,6 +99,19 @@
             }
         }
 
+        // the number returned here matches the NetworkRegistrationState enum we have
+        int phoneNetworkRegState = NetworkRegistrationInfo
+                .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING;
+
+        NetworkRegistrationInfo phoneRegInfo = phone.getServiceState()
+                        .getNetworkRegistrationInfo(NetworkRegistrationInfo.DOMAIN_PS,
+                                AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
+        if (phoneRegInfo != null) {
+            phoneNetworkRegState = phoneRegInfo.getRegistrationState();
+        }
+
+        int phoneId = phone.getPhoneId();
+
         TelephonyStatsLog.write(
                 TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED,
                 carrierId,
@@ -110,7 +125,10 @@
                 durationMillis,
                 reason,
                 otherSignalStrength,
-                otherNetworkRegState);
+                otherNetworkRegState,
+                phoneNetworkRegState,
+                isFirstValidation,
+                phoneId);
     }
 
     /** Returns the RAT used for data (including IWLAN). */