Loading src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +37 −18 Original line number Diff line number Diff line Loading @@ -156,7 +156,8 @@ public class DataStallRecoveryManager extends Handler { /** Whether the result of last action(RADIO_RESTART) reported. */ private boolean mLastActionReported; /** The real time for data stall start. */ private @ElapsedRealtimeLong long mDataStallStartMs; @VisibleForTesting public @ElapsedRealtimeLong long mDataStallStartMs; /** Last data stall recovery action. */ private @RecoveryAction int mLastAction; /** Last radio power state. */ Loading Loading @@ -587,38 +588,56 @@ public class DataStallRecoveryManager extends Handler { * @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; isFirstDataStall = true; mDataStallStartMs = SystemClock.elapsedRealtime(); logl("data stall: start time = " + DataUtils.elapsedTimeToString(mDataStallStartMs)); return; } else if (!mLastActionReported) { // When the first validation status appears, enter this block. isLogNeeded = true; timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); mLastActionReported = true; isFirstValidationAfterDoRecovery = true; } if (!mLastActionReported) { @RecoveredReason int reason = getRecoveredReason(isValid); int timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); 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: lastaction = " "data stall: " + (isFirstDataStall == true ? "start" : isValid == false ? "in process" : "end") + ", lastaction=" + recoveryActionToString(mLastAction) + ", isRecovered=" + isValid + ", reason=" + recoveredReasonToString(reason) + ", isFirstValidationAfterDoRecovery=" + isFirstValidationAfterDoRecovery + ", TimeDuration=" + timeDuration); DataStallRecoveryStats.onDataStallEvent( mLastAction, mPhone, isValid, timeDuration, reason); mLastActionReported = true; } if (isValid) { mLastActionReported = false; mDataStalled = false; } } Loading src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java +45 −4 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package com.android.internal.telephony.metrics; import android.telephony.AccessNetworkConstants; import android.telephony.Annotation.NetworkType; import android.telephony.CellSignalStrength; import android.telephony.NetworkRegistrationInfo; import android.telephony.ServiceState; import android.telephony.TelephonyManager; Loading Loading @@ -61,8 +64,15 @@ public class DataStallRecoveryStats { boolean isOpportunistic = getIsOpportunistic(phone); boolean isMultiSim = SimSlotState.getCurrentState().numActiveSims > 1; // Not use this field in Android S, so we send RECOVERED_REASON_NONE for default value. // Not use these fields in Android S, so we set below parameter for default value. int recoveryReason = 0; int otherSignalStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; int otherNetworkRegState = NetworkRegistrationInfo .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING; int phoneNetworkRegState = NetworkRegistrationInfo .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING; boolean isFirstValidation = false; int phoneId = 0; TelephonyStatsLog.write( TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED, carrierId, Loading @@ -74,7 +84,12 @@ public class DataStallRecoveryStats { band, isRecovered, durationMillis, recoveryReason); recoveryReason, otherSignalStrength, otherNetworkRegState, phoneNetworkRegState, isFirstValidation, phoneId); } /** Loading @@ -85,13 +100,15 @@ public class DataStallRecoveryStats { * @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(); } Loading @@ -111,6 +128,25 @@ public class DataStallRecoveryStats { recoveryAction = RECOVERY_ACTION_RESET_MODEM_MAPPING; } // collect info of the other device in case of DSDS int otherSignalStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; // the number returned here matches the NetworkRegistrationState enum we have int otherNetworkRegState = NetworkRegistrationInfo .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING; // 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(); } // reserve 0 for default value int phoneId = phone.getPhoneId() + 1; TelephonyStatsLog.write( TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED, carrierId, Loading @@ -122,7 +158,12 @@ public class DataStallRecoveryStats { band, isRecovered, durationMillis, reason); reason, otherSignalStrength, otherNetworkRegState, phoneNetworkRegState, isFirstValidation, phoneId); } /** Returns the RAT used for data (including IWLAN). */ Loading tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +19 −0 Original line number Diff line number Diff line Loading @@ -350,4 +350,23 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0); } } @Test public void testStartTimeNotZero() throws Exception { sendOnInternetDataNetworkCallback(false); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllFutureMessages(); for (int i = 0; i < 2; i++) { sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); logd("Sending validation failed callback"); processAllMessages(); moveTimeForward(101); } assertThat(mDataStallRecoveryManager.mDataStallStartMs != 0).isTrue(); } } Loading
src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +37 −18 Original line number Diff line number Diff line Loading @@ -156,7 +156,8 @@ public class DataStallRecoveryManager extends Handler { /** Whether the result of last action(RADIO_RESTART) reported. */ private boolean mLastActionReported; /** The real time for data stall start. */ private @ElapsedRealtimeLong long mDataStallStartMs; @VisibleForTesting public @ElapsedRealtimeLong long mDataStallStartMs; /** Last data stall recovery action. */ private @RecoveryAction int mLastAction; /** Last radio power state. */ Loading Loading @@ -587,38 +588,56 @@ public class DataStallRecoveryManager extends Handler { * @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; isFirstDataStall = true; mDataStallStartMs = SystemClock.elapsedRealtime(); logl("data stall: start time = " + DataUtils.elapsedTimeToString(mDataStallStartMs)); return; } else if (!mLastActionReported) { // When the first validation status appears, enter this block. isLogNeeded = true; timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); mLastActionReported = true; isFirstValidationAfterDoRecovery = true; } if (!mLastActionReported) { @RecoveredReason int reason = getRecoveredReason(isValid); int timeDuration = (int) (SystemClock.elapsedRealtime() - mDataStallStartMs); 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: lastaction = " "data stall: " + (isFirstDataStall == true ? "start" : isValid == false ? "in process" : "end") + ", lastaction=" + recoveryActionToString(mLastAction) + ", isRecovered=" + isValid + ", reason=" + recoveredReasonToString(reason) + ", isFirstValidationAfterDoRecovery=" + isFirstValidationAfterDoRecovery + ", TimeDuration=" + timeDuration); DataStallRecoveryStats.onDataStallEvent( mLastAction, mPhone, isValid, timeDuration, reason); mLastActionReported = true; } if (isValid) { mLastActionReported = false; mDataStalled = false; } } Loading
src/java/com/android/internal/telephony/metrics/DataStallRecoveryStats.java +45 −4 Original line number Diff line number Diff line Loading @@ -16,7 +16,10 @@ package com.android.internal.telephony.metrics; import android.telephony.AccessNetworkConstants; import android.telephony.Annotation.NetworkType; import android.telephony.CellSignalStrength; import android.telephony.NetworkRegistrationInfo; import android.telephony.ServiceState; import android.telephony.TelephonyManager; Loading Loading @@ -61,8 +64,15 @@ public class DataStallRecoveryStats { boolean isOpportunistic = getIsOpportunistic(phone); boolean isMultiSim = SimSlotState.getCurrentState().numActiveSims > 1; // Not use this field in Android S, so we send RECOVERED_REASON_NONE for default value. // Not use these fields in Android S, so we set below parameter for default value. int recoveryReason = 0; int otherSignalStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; int otherNetworkRegState = NetworkRegistrationInfo .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING; int phoneNetworkRegState = NetworkRegistrationInfo .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING; boolean isFirstValidation = false; int phoneId = 0; TelephonyStatsLog.write( TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED, carrierId, Loading @@ -74,7 +84,12 @@ public class DataStallRecoveryStats { band, isRecovered, durationMillis, recoveryReason); recoveryReason, otherSignalStrength, otherNetworkRegState, phoneNetworkRegState, isFirstValidation, phoneId); } /** Loading @@ -85,13 +100,15 @@ public class DataStallRecoveryStats { * @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(); } Loading @@ -111,6 +128,25 @@ public class DataStallRecoveryStats { recoveryAction = RECOVERY_ACTION_RESET_MODEM_MAPPING; } // collect info of the other device in case of DSDS int otherSignalStrength = CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; // the number returned here matches the NetworkRegistrationState enum we have int otherNetworkRegState = NetworkRegistrationInfo .REGISTRATION_STATE_NOT_REGISTERED_OR_SEARCHING; // 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(); } // reserve 0 for default value int phoneId = phone.getPhoneId() + 1; TelephonyStatsLog.write( TelephonyStatsLog.DATA_STALL_RECOVERY_REPORTED, carrierId, Loading @@ -122,7 +158,12 @@ public class DataStallRecoveryStats { band, isRecovered, durationMillis, reason); reason, otherSignalStrength, otherNetworkRegState, phoneNetworkRegState, isFirstValidation, phoneId); } /** Returns the RAT used for data (including IWLAN). */ Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +19 −0 Original line number Diff line number Diff line Loading @@ -350,4 +350,23 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { assertThat(mDataStallRecoveryManager.getRecoveryAction()).isEqualTo(0); } } @Test public void testStartTimeNotZero() throws Exception { sendOnInternetDataNetworkCallback(false); doReturn(mSignalStrength).when(mPhone).getSignalStrength(); doReturn(PhoneConstants.State.IDLE).when(mPhone).getState(); logd("Sending validation failed callback"); sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); processAllFutureMessages(); for (int i = 0; i < 2; i++) { sendValidationStatusCallback(NetworkAgent.VALIDATION_STATUS_NOT_VALID); logd("Sending validation failed callback"); processAllMessages(); moveTimeForward(101); } assertThat(mDataStallRecoveryManager.mDataStallStartMs != 0).isTrue(); } }