Loading src/java/com/android/internal/telephony/data/DataConfigManager.java +20 −0 Original line number Diff line number Diff line Loading @@ -793,6 +793,26 @@ public class DataConfigManager extends Handler { } } /** * @return Get recovery action delay in milliseconds between recovery actions. * * @see CarrierConfigManager#KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY */ public @NonNull long[] getDataStallRecoveryDelayMillis() { return mCarrierConfig.getLongArray( CarrierConfigManager.KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY); } /** * @return Get the data stall recovery should skip boolean array. * * @see CarrierConfigManager#KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY */ public @NonNull boolean[] getDataStallRecoveryShouldSkipArray() { return mCarrierConfig.getBooleanArray( CarrierConfigManager.KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY); } /** * Registration point for subscription info ready * Loading src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +149 −44 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback; import com.android.internal.telephony.metrics.DataStallRecoveryStats; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.telephony.Rlog; Loading @@ -46,6 +47,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.concurrent.Executor; /** Loading Loading @@ -91,15 +93,11 @@ public class DataStallRecoveryManager extends Handler { /** Event for data config updated. */ private static final int EVENT_DATA_CONFIG_UPDATED = 1; /** Event for triggering recovery action. */ private static final int EVENT_DO_RECOVERY = 2; /** Event for mobile data setting changed. */ private static final int EVENT_MOBILE_DATA_SETTINGS_CHANGED = 3; /** Event for radio state changed. */ private static final int EVENT_RADIO_STATE_CHANGED = 4; private static final int EVENT_RADIO_STATE_CHANGED = 3; private final @NonNull Phone mPhone; private final @NonNull String mLogTag; Loading Loading @@ -132,8 +130,17 @@ public class DataStallRecoveryManager extends Handler { private @RadioPowerState int mRadioPowerState; /** Whether the NetworkCheckTimer start. */ private boolean mNetworkCheckTimerStarted = false; /** Whether radio state changed during data stall. */ private boolean mRadioStateChangedDuringDataStall; /** Whether mobile data change to Enabled during data stall. */ private boolean mMobileDataChangedToEnabledDuringDataStall; /** The array for the timers between recovery actions. */ private @NonNull long[] mDataStallRecoveryDelayMillisArray; /** The boolean array for the flags. They are used to skip the recovery actions if needed. */ private @NonNull boolean[] mSkipRecoveryActionArray; private @NonNull DataStallRecoveryManagerCallback mDataStallRecoveryManagerCallback; private DataStallRecoveryManagerCallback mDataStallRecoveryManagerCallback; /** * The data stall recovery manager callback. Note this is only used for passing information Loading Loading @@ -175,11 +182,24 @@ public class DataStallRecoveryManager extends Handler { super(looper); mPhone = phone; mLogTag = "DSRM-" + mPhone.getPhoneId(); log("DataStallRecoveryManager created."); mDataNetworkController = dataNetworkController; mWwanDataServiceManager = dataServiceManager; mDataConfigManager = mDataNetworkController.getDataConfigManager(); mDataNetworkController .getDataSettingsManager() .registerCallback( new DataSettingsManagerCallback(this::post) { @Override public void onDataEnabledChanged( boolean enabled, @TelephonyManager.DataEnabledChangedReason int reason) { onMobileDataEnabledChanged(enabled); } }); mDataStallRecoveryManagerCallback = callback; mRadioPowerState = mPhone.getRadioPowerState(); updateDataStallRecoveryConfigs(); registerAllEvents(); } Loading @@ -197,12 +217,12 @@ public class DataStallRecoveryManager extends Handler { @Override public void onInternetDataNetworkConnected() { // onInternetDataNetworkConnected(); // onInternetNetworkConnected(); } @Override public void onInternetDataNetworkDisconnected() { // onInternetDataNetworkDisconnected(); // onInternetNetworkDisconnected(); } }); mPhone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); Loading @@ -218,11 +238,12 @@ public class DataStallRecoveryManager extends Handler { case EVENT_DO_RECOVERY: doRecovery(); break; case EVENT_MOBILE_DATA_SETTINGS_CHANGED: onMobileDataSettingsChanged(); break; case EVENT_RADIO_STATE_CHANGED: mRadioPowerState = mPhone.getRadioPowerState(); if (mDataStalled) { // Store the radio state changed flag only when data stall occurred. mRadioStateChangedDuringDataStall = true; } break; default: loge("Unexpected message = " + msg); Loading @@ -230,9 +251,49 @@ public class DataStallRecoveryManager extends Handler { } } /** Update the data stall recovery configs from DataConfigManager. */ private void updateDataStallRecoveryConfigs() { mDataStallRecoveryDelayMillisArray = mDataConfigManager.getDataStallRecoveryDelayMillis(); mSkipRecoveryActionArray = mDataConfigManager.getDataStallRecoveryShouldSkipArray(); } /** * Get the duration for specific data stall recovery action. * * @param recoveryAction The recovery action to query. * @return the delay in milliseconds for the specific recovery action. */ private long getDataStallRecoveryDelayMillis(@RecoveryAction int recoveryAction) { return mDataStallRecoveryDelayMillisArray[recoveryAction]; } /** * Check if the recovery action needs to be skipped. * * @param recoveryAction The recovery action. * @return {@code true} if the action needs to be skipped. */ private boolean shouldSkipRecoveryAction(@RecoveryAction int recoveryAction) { return mSkipRecoveryActionArray[recoveryAction]; } /** Called when data config was updated. */ private void onDataConfigUpdated() { // TODO: (b/178670629): Get the new config from DataConfigManager. updateDataStallRecoveryConfigs(); } /** * Called when mobile data setting changed. * * @param enabled true for mobile data settings enabled & false for disabled. */ private void onMobileDataEnabledChanged(boolean enabled) { logl("onMobileDataEnabledChanged: DataEnabled:" + enabled + ",DataStalled:" + mDataStalled); // Store the mobile data changed flag (from disabled to enabled) as TRUE // during data stalled. if (mDataStalled && enabled) { mMobileDataChangedToEnabledDuringDataStall = true; } } /** Loading Loading @@ -260,15 +321,11 @@ public class DataStallRecoveryManager extends Handler { } } /** Called when mobile data setiings changed. */ private void onMobileDataSettingsChanged() { logv("onMobileDataSettingsChanged"); // TODO: (b/178670629): Get mobile data settings from DataSettingsManager. } /** Reset the action to initial step. */ private void resetAction() { mTimeLastRecoveryStartMs = 0; mMobileDataChangedToEnabledDuringDataStall = false; mRadioStateChangedDuringDataStall = false; setRecoveryAction(RECOVERY_ACTION_GET_DATA_CALL_LIST); } Loading @@ -292,6 +349,38 @@ public class DataStallRecoveryManager extends Handler { @VisibleForTesting public void setRecoveryAction(@RecoveryAction int action) { mRecovryAction = action; // Check if the mobile data enabled is TRUE, it means that the mobile data setting changed // from DISABLED to ENABLED, we will set the next recovery action to // RECOVERY_ACTION_RADIO_RESTART due to already did the RECOVERY_ACTION_CLEANUP. if (mMobileDataChangedToEnabledDuringDataStall && mRecovryAction < RECOVERY_ACTION_RADIO_RESTART) { mRecovryAction = RECOVERY_ACTION_RADIO_RESTART; } // Check if the radio state changed from off to on, it means that the modem already // did the radio restart, we will set the next action to RECOVERY_ACTION_RESET_MODEM. if (mRadioStateChangedDuringDataStall && mRadioPowerState == TelephonyManager.RADIO_POWER_ON) { mRecovryAction = RECOVERY_ACTION_RESET_MODEM; } // To check the flag from DataConfigManager if we need to skip the step. if (shouldSkipRecoveryAction(mRecovryAction)) { switch (mRecovryAction) { case RECOVERY_ACTION_GET_DATA_CALL_LIST: setRecoveryAction(RECOVERY_ACTION_CLEANUP); break; case RECOVERY_ACTION_CLEANUP: setRecoveryAction(RECOVERY_ACTION_RADIO_RESTART); break; case RECOVERY_ACTION_RADIO_RESTART: setRecoveryAction(RECOVERY_ACTION_RESET_MODEM); break; case RECOVERY_ACTION_RESET_MODEM: resetAction(); break; } } log("setRecoveryAction: " + recoveryActionToString(mRecovryAction)); } Loading @@ -313,16 +402,6 @@ public class DataStallRecoveryManager extends Handler { return (SystemClock.elapsedRealtime() - mTimeLastRecoveryStartMs); } /** * Get duration between recovery from DataStallRecoveryConfig. * * @return the time in milliseconds between recovery action. */ private long getMinDurationBetweenRecovery() { // TODO: (b/178670629): Get the duration from DataConfigManager return 3 * 60 * 1000; } /** * Broadcast intent when data stall occurred. * Loading Loading @@ -361,12 +440,19 @@ public class DataStallRecoveryManager extends Handler { mPhone.rebootModem(null); } /** Initialize the network check timer. */ private void startNetworkCheckTimer() { log("startNetworkCheckTimer()"); /** * Initialize the network check timer. * * @param action The recovery action to start the network check timer. */ private void startNetworkCheckTimer(@RecoveryAction int action) { // Ignore send message delayed due to reached the last action. if (action == RECOVERY_ACTION_RESET_MODEM) return; log("startNetworkCheckTimer(): " + getDataStallRecoveryDelayMillis(action) + "ms"); if (!mNetworkCheckTimerStarted) { mNetworkCheckTimerStarted = true; sendMessageDelayed(obtainMessage(EVENT_DO_RECOVERY), getMinDurationBetweenRecovery()); sendMessageDelayed( obtainMessage(EVENT_DO_RECOVERY), getDataStallRecoveryDelayMillis(action)); } } Loading @@ -388,7 +474,7 @@ public class DataStallRecoveryManager extends Handler { private boolean isRecoveryNeeded() { logv("enter: isRecoveryNeeded()"); // To avoid back to back recovery, wait for a grace period if (getElapsedTimeSinceRecoveryMs() < getMinDurationBetweenRecovery()) { if (getElapsedTimeSinceRecoveryMs() < getDataStallRecoveryDelayMillis(mLastAction)) { log("skip back to back data stall recovery"); return false; } Loading @@ -407,8 +493,6 @@ public class DataStallRecoveryManager extends Handler { return false; } // TODO: (b/178670629): check the customized carrier config to skip the recovery action return true; } Loading Loading @@ -488,7 +572,26 @@ public class DataStallRecoveryManager extends Handler { + recoveryActionToString(recoveryAction)); } startNetworkCheckTimer(); startNetworkCheckTimer(mLastAction); } /** * Convert RadioPowerState to string * * @param state The radio power state * @return The radio power state in string format. */ private static @NonNull String radioPowerStateToString(@RadioPowerState int state) { switch (state) { case TelephonyManager.RADIO_POWER_OFF: return "RADIO_POWER_OFF"; case TelephonyManager.RADIO_POWER_ON: return "RADIO_POWER_ON"; case TelephonyManager.RADIO_POWER_UNAVAILABLE: return "RADIO_POWER_UNAVAILABLE"; default: return "Unknown(" + state + ")"; } } /** Loading @@ -512,13 +615,6 @@ public class DataStallRecoveryManager extends Handler { } } /** The data stall recovery config. */ public static final class DataStallRecoveryConfig { DataStallRecoveryConfig(String stringConfig) { // TODO: (b/178670629): Parsing the config string. } } /** * Log debug messages. * Loading Loading @@ -572,10 +668,19 @@ public class DataStallRecoveryManager extends Handler { pw.println("mIsValidNetwork=" + mIsValidNetwork); pw.println("mDataStalled=" + mDataStalled); pw.println("mDataStallStartMs=" + mDataStallStartMs); pw.println("mRadioPowerState=" + mRadioPowerState); pw.println("mRadioPowerState=" + radioPowerStateToString(mRadioPowerState)); pw.println("mLastActionReported=" + mLastActionReported); pw.println("mTimeLastRecoveryStartMs=" + mTimeLastRecoveryStartMs); pw.println("getRecoveryAction()=" + recoveryActionToString(getRecoveryAction())); pw.println("mRadioStateChangedDuringDataStall=" + mRadioStateChangedDuringDataStall); pw.println( "mMobileDataChangedToEnabledDuringDataStall=" + mMobileDataChangedToEnabledDuringDataStall); pw.println( "DataStallRecoveryDelayMillisArray=" + Arrays.toString(mDataStallRecoveryDelayMillisArray)); pw.println("SkipRecoveryActionArray=" + Arrays.toString(mSkipRecoveryActionArray)); pw.decreaseIndent(); pw.println(""); pw.println("Local logs:"); Loading tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -591,6 +591,7 @@ public abstract class TelephonyTest { doReturn(mAccessNetworksManager).when(mPhone).getAccessNetworksManager(); doReturn(mDataEnabledSettings).when(mPhone).getDataEnabledSettings(); doReturn(mDcTracker).when(mPhone).getDcTracker(anyInt()); doReturn(mDataSettingsManager).when(mDataNetworkController).getDataSettingsManager(); doReturn(mDataNetworkController).when(mPhone).getDataNetworkController(); doReturn(mDataSettingsManager).when(mPhone).getDataSettingsManager(); doReturn(mCarrierPrivilegesTracker).when(mPhone).getCarrierPrivilegesTracker(); Loading tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +13 −1 Original line number Diff line number Diff line Loading @@ -16,17 +16,19 @@ package com.android.internal.telephony.data; import static com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.net.NetworkAgent; import android.telephony.CarrierConfigManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading @@ -53,6 +55,15 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { logd("DataStallRecoveryManagerTest +Setup!"); super.setUp(getClass().getSimpleName()); doReturn(true).when(mPhone).isUsingNewDataStack(); mCarrierConfigManager = mPhone.getContext().getSystemService(CarrierConfigManager.class); long[] dataStallRecoveryTimersArray = new long[] {1, 1, 1}; boolean[] dataStallRecoveryStepsArray = new boolean[] {false, false, false, false}; doReturn(dataStallRecoveryTimersArray) .when(mDataConfigManager) .getDataStallRecoveryDelayMillis(); doReturn(dataStallRecoveryStepsArray) .when(mDataConfigManager) .getDataStallRecoveryShouldSkipArray(); doReturn(mSST).when(mPhone).getServiceStateTracker(); doAnswer( invocation -> { Loading @@ -61,6 +72,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { }) .when(mDataStallRecoveryManagerCallback) .invokeFromExecutor(any(Runnable.class)); doReturn("").when(mSubscriptionController).getDataEnabledOverrideRules(anyInt()); mDataStallRecoveryManager = new DataStallRecoveryManager( Loading Loading
src/java/com/android/internal/telephony/data/DataConfigManager.java +20 −0 Original line number Diff line number Diff line Loading @@ -793,6 +793,26 @@ public class DataConfigManager extends Handler { } } /** * @return Get recovery action delay in milliseconds between recovery actions. * * @see CarrierConfigManager#KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY */ public @NonNull long[] getDataStallRecoveryDelayMillis() { return mCarrierConfig.getLongArray( CarrierConfigManager.KEY_DATA_STALL_RECOVERY_TIMERS_LONG_ARRAY); } /** * @return Get the data stall recovery should skip boolean array. * * @see CarrierConfigManager#KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY */ public @NonNull boolean[] getDataStallRecoveryShouldSkipArray() { return mCarrierConfig.getBooleanArray( CarrierConfigManager.KEY_DATA_STALL_RECOVERY_SHOULD_SKIP_BOOL_ARRAY); } /** * Registration point for subscription info ready * Loading
src/java/com/android/internal/telephony/data/DataStallRecoveryManager.java +149 −44 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.Phone; import com.android.internal.telephony.PhoneConstants; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback; import com.android.internal.telephony.metrics.DataStallRecoveryStats; import com.android.internal.telephony.metrics.TelephonyMetrics; import com.android.telephony.Rlog; Loading @@ -46,6 +47,7 @@ import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Arrays; import java.util.concurrent.Executor; /** Loading Loading @@ -91,15 +93,11 @@ public class DataStallRecoveryManager extends Handler { /** Event for data config updated. */ private static final int EVENT_DATA_CONFIG_UPDATED = 1; /** Event for triggering recovery action. */ private static final int EVENT_DO_RECOVERY = 2; /** Event for mobile data setting changed. */ private static final int EVENT_MOBILE_DATA_SETTINGS_CHANGED = 3; /** Event for radio state changed. */ private static final int EVENT_RADIO_STATE_CHANGED = 4; private static final int EVENT_RADIO_STATE_CHANGED = 3; private final @NonNull Phone mPhone; private final @NonNull String mLogTag; Loading Loading @@ -132,8 +130,17 @@ public class DataStallRecoveryManager extends Handler { private @RadioPowerState int mRadioPowerState; /** Whether the NetworkCheckTimer start. */ private boolean mNetworkCheckTimerStarted = false; /** Whether radio state changed during data stall. */ private boolean mRadioStateChangedDuringDataStall; /** Whether mobile data change to Enabled during data stall. */ private boolean mMobileDataChangedToEnabledDuringDataStall; /** The array for the timers between recovery actions. */ private @NonNull long[] mDataStallRecoveryDelayMillisArray; /** The boolean array for the flags. They are used to skip the recovery actions if needed. */ private @NonNull boolean[] mSkipRecoveryActionArray; private @NonNull DataStallRecoveryManagerCallback mDataStallRecoveryManagerCallback; private DataStallRecoveryManagerCallback mDataStallRecoveryManagerCallback; /** * The data stall recovery manager callback. Note this is only used for passing information Loading Loading @@ -175,11 +182,24 @@ public class DataStallRecoveryManager extends Handler { super(looper); mPhone = phone; mLogTag = "DSRM-" + mPhone.getPhoneId(); log("DataStallRecoveryManager created."); mDataNetworkController = dataNetworkController; mWwanDataServiceManager = dataServiceManager; mDataConfigManager = mDataNetworkController.getDataConfigManager(); mDataNetworkController .getDataSettingsManager() .registerCallback( new DataSettingsManagerCallback(this::post) { @Override public void onDataEnabledChanged( boolean enabled, @TelephonyManager.DataEnabledChangedReason int reason) { onMobileDataEnabledChanged(enabled); } }); mDataStallRecoveryManagerCallback = callback; mRadioPowerState = mPhone.getRadioPowerState(); updateDataStallRecoveryConfigs(); registerAllEvents(); } Loading @@ -197,12 +217,12 @@ public class DataStallRecoveryManager extends Handler { @Override public void onInternetDataNetworkConnected() { // onInternetDataNetworkConnected(); // onInternetNetworkConnected(); } @Override public void onInternetDataNetworkDisconnected() { // onInternetDataNetworkDisconnected(); // onInternetNetworkDisconnected(); } }); mPhone.mCi.registerForRadioStateChanged(this, EVENT_RADIO_STATE_CHANGED, null); Loading @@ -218,11 +238,12 @@ public class DataStallRecoveryManager extends Handler { case EVENT_DO_RECOVERY: doRecovery(); break; case EVENT_MOBILE_DATA_SETTINGS_CHANGED: onMobileDataSettingsChanged(); break; case EVENT_RADIO_STATE_CHANGED: mRadioPowerState = mPhone.getRadioPowerState(); if (mDataStalled) { // Store the radio state changed flag only when data stall occurred. mRadioStateChangedDuringDataStall = true; } break; default: loge("Unexpected message = " + msg); Loading @@ -230,9 +251,49 @@ public class DataStallRecoveryManager extends Handler { } } /** Update the data stall recovery configs from DataConfigManager. */ private void updateDataStallRecoveryConfigs() { mDataStallRecoveryDelayMillisArray = mDataConfigManager.getDataStallRecoveryDelayMillis(); mSkipRecoveryActionArray = mDataConfigManager.getDataStallRecoveryShouldSkipArray(); } /** * Get the duration for specific data stall recovery action. * * @param recoveryAction The recovery action to query. * @return the delay in milliseconds for the specific recovery action. */ private long getDataStallRecoveryDelayMillis(@RecoveryAction int recoveryAction) { return mDataStallRecoveryDelayMillisArray[recoveryAction]; } /** * Check if the recovery action needs to be skipped. * * @param recoveryAction The recovery action. * @return {@code true} if the action needs to be skipped. */ private boolean shouldSkipRecoveryAction(@RecoveryAction int recoveryAction) { return mSkipRecoveryActionArray[recoveryAction]; } /** Called when data config was updated. */ private void onDataConfigUpdated() { // TODO: (b/178670629): Get the new config from DataConfigManager. updateDataStallRecoveryConfigs(); } /** * Called when mobile data setting changed. * * @param enabled true for mobile data settings enabled & false for disabled. */ private void onMobileDataEnabledChanged(boolean enabled) { logl("onMobileDataEnabledChanged: DataEnabled:" + enabled + ",DataStalled:" + mDataStalled); // Store the mobile data changed flag (from disabled to enabled) as TRUE // during data stalled. if (mDataStalled && enabled) { mMobileDataChangedToEnabledDuringDataStall = true; } } /** Loading Loading @@ -260,15 +321,11 @@ public class DataStallRecoveryManager extends Handler { } } /** Called when mobile data setiings changed. */ private void onMobileDataSettingsChanged() { logv("onMobileDataSettingsChanged"); // TODO: (b/178670629): Get mobile data settings from DataSettingsManager. } /** Reset the action to initial step. */ private void resetAction() { mTimeLastRecoveryStartMs = 0; mMobileDataChangedToEnabledDuringDataStall = false; mRadioStateChangedDuringDataStall = false; setRecoveryAction(RECOVERY_ACTION_GET_DATA_CALL_LIST); } Loading @@ -292,6 +349,38 @@ public class DataStallRecoveryManager extends Handler { @VisibleForTesting public void setRecoveryAction(@RecoveryAction int action) { mRecovryAction = action; // Check if the mobile data enabled is TRUE, it means that the mobile data setting changed // from DISABLED to ENABLED, we will set the next recovery action to // RECOVERY_ACTION_RADIO_RESTART due to already did the RECOVERY_ACTION_CLEANUP. if (mMobileDataChangedToEnabledDuringDataStall && mRecovryAction < RECOVERY_ACTION_RADIO_RESTART) { mRecovryAction = RECOVERY_ACTION_RADIO_RESTART; } // Check if the radio state changed from off to on, it means that the modem already // did the radio restart, we will set the next action to RECOVERY_ACTION_RESET_MODEM. if (mRadioStateChangedDuringDataStall && mRadioPowerState == TelephonyManager.RADIO_POWER_ON) { mRecovryAction = RECOVERY_ACTION_RESET_MODEM; } // To check the flag from DataConfigManager if we need to skip the step. if (shouldSkipRecoveryAction(mRecovryAction)) { switch (mRecovryAction) { case RECOVERY_ACTION_GET_DATA_CALL_LIST: setRecoveryAction(RECOVERY_ACTION_CLEANUP); break; case RECOVERY_ACTION_CLEANUP: setRecoveryAction(RECOVERY_ACTION_RADIO_RESTART); break; case RECOVERY_ACTION_RADIO_RESTART: setRecoveryAction(RECOVERY_ACTION_RESET_MODEM); break; case RECOVERY_ACTION_RESET_MODEM: resetAction(); break; } } log("setRecoveryAction: " + recoveryActionToString(mRecovryAction)); } Loading @@ -313,16 +402,6 @@ public class DataStallRecoveryManager extends Handler { return (SystemClock.elapsedRealtime() - mTimeLastRecoveryStartMs); } /** * Get duration between recovery from DataStallRecoveryConfig. * * @return the time in milliseconds between recovery action. */ private long getMinDurationBetweenRecovery() { // TODO: (b/178670629): Get the duration from DataConfigManager return 3 * 60 * 1000; } /** * Broadcast intent when data stall occurred. * Loading Loading @@ -361,12 +440,19 @@ public class DataStallRecoveryManager extends Handler { mPhone.rebootModem(null); } /** Initialize the network check timer. */ private void startNetworkCheckTimer() { log("startNetworkCheckTimer()"); /** * Initialize the network check timer. * * @param action The recovery action to start the network check timer. */ private void startNetworkCheckTimer(@RecoveryAction int action) { // Ignore send message delayed due to reached the last action. if (action == RECOVERY_ACTION_RESET_MODEM) return; log("startNetworkCheckTimer(): " + getDataStallRecoveryDelayMillis(action) + "ms"); if (!mNetworkCheckTimerStarted) { mNetworkCheckTimerStarted = true; sendMessageDelayed(obtainMessage(EVENT_DO_RECOVERY), getMinDurationBetweenRecovery()); sendMessageDelayed( obtainMessage(EVENT_DO_RECOVERY), getDataStallRecoveryDelayMillis(action)); } } Loading @@ -388,7 +474,7 @@ public class DataStallRecoveryManager extends Handler { private boolean isRecoveryNeeded() { logv("enter: isRecoveryNeeded()"); // To avoid back to back recovery, wait for a grace period if (getElapsedTimeSinceRecoveryMs() < getMinDurationBetweenRecovery()) { if (getElapsedTimeSinceRecoveryMs() < getDataStallRecoveryDelayMillis(mLastAction)) { log("skip back to back data stall recovery"); return false; } Loading @@ -407,8 +493,6 @@ public class DataStallRecoveryManager extends Handler { return false; } // TODO: (b/178670629): check the customized carrier config to skip the recovery action return true; } Loading Loading @@ -488,7 +572,26 @@ public class DataStallRecoveryManager extends Handler { + recoveryActionToString(recoveryAction)); } startNetworkCheckTimer(); startNetworkCheckTimer(mLastAction); } /** * Convert RadioPowerState to string * * @param state The radio power state * @return The radio power state in string format. */ private static @NonNull String radioPowerStateToString(@RadioPowerState int state) { switch (state) { case TelephonyManager.RADIO_POWER_OFF: return "RADIO_POWER_OFF"; case TelephonyManager.RADIO_POWER_ON: return "RADIO_POWER_ON"; case TelephonyManager.RADIO_POWER_UNAVAILABLE: return "RADIO_POWER_UNAVAILABLE"; default: return "Unknown(" + state + ")"; } } /** Loading @@ -512,13 +615,6 @@ public class DataStallRecoveryManager extends Handler { } } /** The data stall recovery config. */ public static final class DataStallRecoveryConfig { DataStallRecoveryConfig(String stringConfig) { // TODO: (b/178670629): Parsing the config string. } } /** * Log debug messages. * Loading Loading @@ -572,10 +668,19 @@ public class DataStallRecoveryManager extends Handler { pw.println("mIsValidNetwork=" + mIsValidNetwork); pw.println("mDataStalled=" + mDataStalled); pw.println("mDataStallStartMs=" + mDataStallStartMs); pw.println("mRadioPowerState=" + mRadioPowerState); pw.println("mRadioPowerState=" + radioPowerStateToString(mRadioPowerState)); pw.println("mLastActionReported=" + mLastActionReported); pw.println("mTimeLastRecoveryStartMs=" + mTimeLastRecoveryStartMs); pw.println("getRecoveryAction()=" + recoveryActionToString(getRecoveryAction())); pw.println("mRadioStateChangedDuringDataStall=" + mRadioStateChangedDuringDataStall); pw.println( "mMobileDataChangedToEnabledDuringDataStall=" + mMobileDataChangedToEnabledDuringDataStall); pw.println( "DataStallRecoveryDelayMillisArray=" + Arrays.toString(mDataStallRecoveryDelayMillisArray)); pw.println("SkipRecoveryActionArray=" + Arrays.toString(mSkipRecoveryActionArray)); pw.decreaseIndent(); pw.println(""); pw.println("Local logs:"); Loading
tests/telephonytests/src/com/android/internal/telephony/TelephonyTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -591,6 +591,7 @@ public abstract class TelephonyTest { doReturn(mAccessNetworksManager).when(mPhone).getAccessNetworksManager(); doReturn(mDataEnabledSettings).when(mPhone).getDataEnabledSettings(); doReturn(mDcTracker).when(mPhone).getDcTracker(anyInt()); doReturn(mDataSettingsManager).when(mDataNetworkController).getDataSettingsManager(); doReturn(mDataNetworkController).when(mPhone).getDataNetworkController(); doReturn(mDataSettingsManager).when(mPhone).getDataSettingsManager(); doReturn(mCarrierPrivilegesTracker).when(mPhone).getCarrierPrivilegesTracker(); Loading
tests/telephonytests/src/com/android/internal/telephony/data/DataStallRecoveryManagerTest.java +13 −1 Original line number Diff line number Diff line Loading @@ -16,17 +16,19 @@ package com.android.internal.telephony.data; import static com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import com.android.internal.telephony.data.DataNetworkController.DataNetworkControllerCallback; import static com.google.common.truth.Truth.assertThat; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.doReturn; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import android.net.NetworkAgent; import android.telephony.CarrierConfigManager; import android.testing.AndroidTestingRunner; import android.testing.TestableLooper; Loading @@ -53,6 +55,15 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { logd("DataStallRecoveryManagerTest +Setup!"); super.setUp(getClass().getSimpleName()); doReturn(true).when(mPhone).isUsingNewDataStack(); mCarrierConfigManager = mPhone.getContext().getSystemService(CarrierConfigManager.class); long[] dataStallRecoveryTimersArray = new long[] {1, 1, 1}; boolean[] dataStallRecoveryStepsArray = new boolean[] {false, false, false, false}; doReturn(dataStallRecoveryTimersArray) .when(mDataConfigManager) .getDataStallRecoveryDelayMillis(); doReturn(dataStallRecoveryStepsArray) .when(mDataConfigManager) .getDataStallRecoveryShouldSkipArray(); doReturn(mSST).when(mPhone).getServiceStateTracker(); doAnswer( invocation -> { Loading @@ -61,6 +72,7 @@ public class DataStallRecoveryManagerTest extends TelephonyTest { }) .when(mDataStallRecoveryManagerCallback) .invokeFromExecutor(any(Runnable.class)); doReturn("").when(mSubscriptionController).getDataEnabledOverrideRules(anyInt()); mDataStallRecoveryManager = new DataStallRecoveryManager( Loading