Add the recovered reason into metrics

- Add the RecoveredReason enum
- Add the new function for new data stack in Android T.

Bug: 213394622
Test: build and statsd_testdrive
      atest DataStallRecoveryManagerTest
Merged-In: I71ce81b3ad754325a6183c8c3f1dd4255cda65fc
Change-Id: I71ce81b3ad754325a6183c8c3f1dd4255cda65fc
diff --git a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
index ca00044..ca2f15b 100644
--- a/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
+++ b/src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java
@@ -74,23 +74,45 @@
      * etc) using RIL_REQUEST_GET_DATA_CALL_LIST.  This will help in cases where the data stall
      * occurred because of a link property changed but not notified to connectivity service.
      */
-    private static final int RECOVERY_ACTION_GET_DATA_CALL_LIST = 0;
+    public static final int RECOVERY_ACTION_GET_DATA_CALL_LIST = 0;
 
     /* DataStallRecoveryManager will request DataNetworkController to reestablish internet using
      * RIL_REQUEST_DEACTIVATE_DATA_CALL and sets up the data call back using SETUP_DATA_CALL.
      * It will help to reestablish the channel between RIL and modem.
      */
-    private static final int RECOVERY_ACTION_CLEANUP = 1;
+    public static final int RECOVERY_ACTION_CLEANUP = 1;
 
+    // TODO: b/214662910: Align the recovery action between DataStallRecoveryManager and Westworld.
     /* DataStallRecoveryManager will request ServiceStateTracker to send RIL_REQUEST_RADIO_POWER
      * to restart radio. It will restart the radio and re-attch to the network.
      */
-    private static final int RECOVERY_ACTION_RADIO_RESTART = 2;
+    public static final int RECOVERY_ACTION_RADIO_RESTART = 2;
 
     /* DataStallRecoveryManager will request to reboot modem using NV_RESET_CONFIG. It will recover
      * if there is a problem in modem side.
      */
-    private static final int RECOVERY_ACTION_RESET_MODEM = 3;
+    public static final int RECOVERY_ACTION_RESET_MODEM = 3;
+
+    /** Recovered reason taken in case of data stall recovered */
+    @IntDef(
+            value = {
+                RECOVERED_REASON_NONE,
+                RECOVERED_REASON_DSRM,
+                RECOVERED_REASON_MODEM,
+                RECOVERED_REASON_USER
+            })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface RecoveredReason {};
+
+    /** The reason when data stall recovered. */
+    /** The data stall not recovered yet. */
+    private static final int RECOVERED_REASON_NONE = 0;
+    /** The data stall recovered by our DataStallRecoveryManager. */
+    private static final int RECOVERED_REASON_DSRM = 1;
+    /** The data stall recovered by modem(Radio Power off/on). */
+    private static final int RECOVERED_REASON_MODEM = 2;
+    /** The data stall recovered by user (Mobile Data Power off/on). */
+    private static final int RECOVERED_REASON_USER = 3;
 
     /** Event for data config updated. */
     private static final int EVENT_DATA_CONFIG_UPDATED = 1;
@@ -518,15 +540,19 @@
         }
 
         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);
+            DataStallRecoveryStats.onDataStallEvent(
+                    mLastAction, mPhone, isValid, timeDuration, reason);
             mLastActionReported = true;
         }
 
@@ -536,6 +562,23 @@
         }
     }
 
+    /**
+     * Get the data stall recovered reason.
+     *
+     * @param isValid true for validation passed & false for validation failed
+     */
+    private int getRecoveredReason(boolean isValid) {
+        if (!isValid) return RECOVERED_REASON_NONE;
+
+        if (mRadioStateChangedDuringDataStall) {
+            return RECOVERED_REASON_MODEM;
+        } else if (mMobileDataChangedToEnabledDuringDataStall) {
+            return RECOVERED_REASON_USER;
+        } else {
+            return RECOVERED_REASON_DSRM;
+        }
+    }
+
     /** Perform a series of data stall recovery actions. */
     private void doRecovery() {
         @RecoveryAction final int recoveryAction = getRecoveryAction();
@@ -579,6 +622,27 @@
     }
 
     /**
+     * Convert @RecoveredReason to string
+     *
+     * @param reason The recovered reason.
+     * @return The recovered reason in string format.
+     */
+    private static @NonNull String recoveredReasonToString(@RecoveredReason int reason) {
+        switch (reason) {
+            case RECOVERED_REASON_NONE:
+                return "RECOVERED_REASON_NONE";
+            case RECOVERED_REASON_DSRM:
+                return "RECOVERED_REASON_DSRM";
+            case RECOVERED_REASON_MODEM:
+                return "RECOVERED_REASON_MODEM";
+            case RECOVERED_REASON_USER:
+                return "RECOVERED_REASON_USER";
+            default:
+                return "Unknown(" + reason + ")";
+        }
+    }
+
+    /**
      * Convert RadioPowerState to string
      *
      * @param state The radio power state
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
index 0fb718a..6c1ae5e 100755
--- a/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcTracker.java
@@ -357,9 +357,6 @@
     // it effect the PhysicalLinkStatusChanged
     private boolean mLteEndcUsingUserDataForRrcDetection = false;
 
-    // stats per data call recovery event
-    private DataStallRecoveryStats mDataStallRecoveryStats;
-
     /* List of SubscriptionPlans, updated when initialized and when plans are changed. */
     private List<SubscriptionPlan> mSubscriptionPlans = null;
     /* List of network types an unmetered override applies to, set by onSubscriptionOverride