diff options
Diffstat (limited to 'src')
3 files changed, 342 insertions, 456 deletions
diff --git a/src/java/com/android/internal/telephony/DataConnectionTracker.java b/src/java/com/android/internal/telephony/DataConnectionTracker.java index fdaf0a3..43058b6 100644 --- a/src/java/com/android/internal/telephony/DataConnectionTracker.java +++ b/src/java/com/android/internal/telephony/DataConnectionTracker.java @@ -16,6 +16,7 @@ package com.android.internal.telephony; +import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -42,6 +43,7 @@ import android.provider.Settings.SettingNotFoundException; import android.telephony.ServiceState; import android.telephony.TelephonyManager; import android.text.TextUtils; +import android.util.EventLog; import android.util.Log; import com.android.internal.R; @@ -66,6 +68,7 @@ import java.util.concurrent.atomic.AtomicReference; public abstract class DataConnectionTracker extends Handler { protected static final boolean DBG = true; protected static final boolean VDBG = false; + protected static final boolean RADIO_TESTS = false; /** * Constants for the data connection activity: @@ -144,6 +147,12 @@ public abstract class DataConnectionTracker extends Handler { // Tag for tracking stale alarms protected static final String DATA_STALL_ALARM_TAG_EXTRA = "data.stall.alram.tag"; + protected static final boolean DATA_STALL_SUSPECTED = true; + protected static final boolean DATA_STALL_NOT_SUSPECTED = false; + + protected String RADIO_RESET_PROPERTY = "gsm.radioreset"; + + // TODO: See if we can remove INTENT_RECONNECT_ALARM // having to have different values for GSM and // CDMA. If so we can then remove the need for @@ -240,6 +249,8 @@ public abstract class DataConnectionTracker extends Handler { /* Once disposed dont handle any messages */ protected boolean mIsDisposed = false; + protected ContentResolver mResolver; + protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver () { @Override @@ -287,6 +298,26 @@ public abstract class DataConnectionTracker extends Handler { }; private final DataRoamingSettingObserver mDataRoamingSettingObserver; + private Runnable mPollNetStat = new Runnable() + { + @Override + public void run() { + updateDataActivity(); + + if (mIsScreenOn) { + mNetStatPollPeriod = Settings.Secure.getInt(mResolver, + Settings.Secure.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS); + } else { + mNetStatPollPeriod = Settings.Secure.getInt(mResolver, + Settings.Secure.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS, + POLL_NETSTAT_SCREEN_OFF_MILLIS); + } + + if (mNetStatPollEnabled) { + mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod); + } + } + }; private class DataRoamingSettingObserver extends ContentObserver { public DataRoamingSettingObserver(Handler handler) { @@ -345,34 +376,8 @@ public abstract class DataConnectionTracker extends Handler { } public void updateTxRxSum() { - boolean txUpdated = false, rxUpdated = false; - long txSum = 0, rxSum = 0; - for (ApnContext apnContext : mApnContexts.values()) { - if (apnContext.getState() == DctConstants.State.CONNECTED) { - DataConnectionAc dcac = apnContext.getDataConnectionAc(); - if (dcac == null) continue; - - LinkProperties linkProp = dcac.getLinkPropertiesSync(); - if (linkProp == null) continue; - - String iface = linkProp.getInterfaceName(); - - if (iface != null) { - long stats = TrafficStats.getTxPackets(iface); - if (stats > 0) { - txUpdated = true; - txSum += stats; - } - stats = TrafficStats.getRxPackets(iface); - if (stats > 0) { - rxUpdated = true; - rxSum += stats; - } - } - } - } - if (txUpdated) this.txPkts = txSum; - if (rxUpdated) this.rxPkts = rxSum; + this.txPkts = TrafficStats.getMobileTxPackets(); + this.rxPkts = TrafficStats.getMobileRxPackets(); } } @@ -432,6 +437,7 @@ public abstract class DataConnectionTracker extends Handler { filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(INTENT_SET_FAIL_DATA_SETUP_COUNTER); + filter.addAction(getActionIntentDataStallAlarm()); mUserDataEnabled = Settings.Secure.getInt( mPhone.getContext().getContentResolver(), Settings.Secure.MOBILE_DATA, 1) == 1; @@ -455,6 +461,8 @@ public abstract class DataConnectionTracker extends Handler { // watch for changes to Settings.Secure.DATA_ROAMING mDataRoamingSettingObserver = new DataRoamingSettingObserver(mPhone); mDataRoamingSettingObserver.register(mPhone.getContext()); + + mResolver = mPhone.getContext().getContentResolver(); } public void dispose() { @@ -565,9 +573,6 @@ public abstract class DataConnectionTracker extends Handler { // abstract methods protected abstract String getActionIntentReconnectAlarm(); protected abstract String getActionIntentDataStallAlarm(); - protected abstract void startNetStatPoll(); - protected abstract void stopNetStatPoll(); - protected abstract void restartDataStallAlarm(); protected abstract void restartRadio(); protected abstract void log(String s); protected abstract void loge(String s); @@ -591,10 +596,6 @@ public abstract class DataConnectionTracker extends Handler { protected abstract boolean isDataPossible(String apnType); protected abstract void onUpdateIcc(); - protected void onDataStallAlarm(int tag) { - loge("onDataStallAlarm: not impleted tag=" + tag); - } - @Override public void handleMessage(Message msg) { switch (msg.what) { @@ -1144,8 +1145,294 @@ public abstract class DataConnectionTracker extends Handler { } } + protected void resetPollStats() { + mTxPkts = -1; + mRxPkts = -1; + mNetStatPollPeriod = POLL_NETSTAT_MILLIS; + } + + protected abstract DctConstants.State getOverallState(); + + protected void startNetStatPoll() { + if (getOverallState() == DctConstants.State.CONNECTED && mNetStatPollEnabled == false) { + if (DBG) log("startNetStatPoll"); + resetPollStats(); + mNetStatPollEnabled = true; + mPollNetStat.run(); + } + } + + protected void stopNetStatPoll() { + mNetStatPollEnabled = false; + removeCallbacks(mPollNetStat); + if (DBG) log("stopNetStatPoll"); + } + + public void updateDataActivity() { + long sent, received; + + DctConstants.Activity newActivity; + + TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts); + TxRxSum curTxRxSum = new TxRxSum(); + curTxRxSum.updateTxRxSum(); + mTxPkts = curTxRxSum.txPkts; + mRxPkts = curTxRxSum.rxPkts; + + if (VDBG) { + log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum); + } + + if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) { + sent = mTxPkts - preTxRxSum.txPkts; + received = mRxPkts - preTxRxSum.rxPkts; + + if (VDBG) + log("updateDataActivity: sent=" + sent + " received=" + received); + if (sent > 0 && received > 0) { + newActivity = DctConstants.Activity.DATAINANDOUT; + } else if (sent > 0 && received == 0) { + newActivity = DctConstants.Activity.DATAOUT; + } else if (sent == 0 && received > 0) { + newActivity = DctConstants.Activity.DATAIN; + } else { + newActivity = (mActivity == DctConstants.Activity.DORMANT) ? + mActivity : DctConstants.Activity.NONE; + } + + if (mActivity != newActivity && mIsScreenOn) { + if (VDBG) + log("updateDataActivity: newActivity=" + newActivity); + mActivity = newActivity; + mPhone.notifyDataActivity(); + } + } + } + + // Recovery action taken in case of data stall + protected static class RecoveryAction { + public static final int GET_DATA_CALL_LIST = 0; + public static final int CLEANUP = 1; + public static final int REREGISTER = 2; + public static final int RADIO_RESTART = 3; + public static final int RADIO_RESTART_WITH_PROP = 4; + + private static boolean isAggressiveRecovery(int value) { + return ((value == RecoveryAction.CLEANUP) || + (value == RecoveryAction.REREGISTER) || + (value == RecoveryAction.RADIO_RESTART) || + (value == RecoveryAction.RADIO_RESTART_WITH_PROP)); + } + } + + public int getRecoveryAction() { + int action = Settings.System.getInt(mPhone.getContext().getContentResolver(), + "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST); + if (VDBG) log("getRecoveryAction: " + action); + return action; + } + public void putRecoveryAction(int action) { + Settings.System.putInt(mPhone.getContext().getContentResolver(), + "radio.data.stall.recovery.action", action); + if (VDBG) log("putRecoveryAction: " + action); + } + + protected boolean isConnected() { + return false; + } + + protected void doRecovery() { + if (getOverallState() == DctConstants.State.CONNECTED) { + // Go through a series of recovery steps, each action transitions to the next action + int recoveryAction = getRecoveryAction(); + switch (recoveryAction) { + case RecoveryAction.GET_DATA_CALL_LIST: + EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST, + mSentSinceLastRecv); + if (DBG) log("doRecovery() get data call list"); + mPhone.mCM.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED)); + putRecoveryAction(RecoveryAction.CLEANUP); + break; + case RecoveryAction.CLEANUP: + EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv); + if (DBG) log("doRecovery() cleanup all connections"); + cleanUpAllConnections(Phone.REASON_PDP_RESET); + putRecoveryAction(RecoveryAction.REREGISTER); + break; + case RecoveryAction.REREGISTER: + EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER, + mSentSinceLastRecv); + if (DBG) log("doRecovery() re-register"); + mPhone.getServiceStateTracker().reRegisterNetwork(null); + putRecoveryAction(RecoveryAction.RADIO_RESTART); + break; + case RecoveryAction.RADIO_RESTART: + EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART, + mSentSinceLastRecv); + if (DBG) log("restarting radio"); + putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP); + restartRadio(); + break; + case RecoveryAction.RADIO_RESTART_WITH_PROP: + // This is in case radio restart has not recovered the data. + // It will set an additional "gsm.radioreset" property to tell + // RIL or system to take further action. + // The implementation of hard reset recovery action is up to OEM product. + // Once RADIO_RESET property is consumed, it is expected to set back + // to false by RIL. + EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1); + if (DBG) log("restarting radio with gsm.radioreset to true"); + SystemProperties.set(RADIO_RESET_PROPERTY, "true"); + // give 1 sec so property change can be notified. + try { + Thread.sleep(1000); + } catch (InterruptedException e) {} + restartRadio(); + putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST); + break; + default: + throw new RuntimeException("doRecovery: Invalid recoveryAction=" + + recoveryAction); + } + } + } + + private void updateDataStallInfo() { + long sent, received; + + TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum); + mDataStallTxRxSum.updateTxRxSum(); + + if (VDBG) { + log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum + + " preTxRxSum=" + preTxRxSum); + } + + sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts; + received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts; + + if (RADIO_TESTS) { + if (SystemProperties.getBoolean("radio.test.data.stall", false)) { + log("updateDataStallInfo: radio.test.data.stall true received = 0;"); + received = 0; + } + } + if ( sent > 0 && received > 0 ) { + if (VDBG) log("updateDataStallInfo: IN/OUT"); + mSentSinceLastRecv = 0; + putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST); + } else if (sent > 0 && received == 0) { + if (mPhone.getState() == PhoneConstants.State.IDLE) { + mSentSinceLastRecv += sent; + } else { + mSentSinceLastRecv = 0; + } + if (DBG) { + log("updateDataStallInfo: OUT sent=" + sent + + " mSentSinceLastRecv=" + mSentSinceLastRecv); + } + } else if (sent == 0 && received > 0) { + if (VDBG) log("updateDataStallInfo: IN"); + mSentSinceLastRecv = 0; + putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST); + } else { + if (VDBG) log("updateDataStallInfo: NONE"); + } + } + + protected void onDataStallAlarm(int tag) { + if (mDataStallAlarmTag != tag) { + if (DBG) { + log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag); + } + return; + } + updateDataStallInfo(); + + int hangWatchdogTrigger = Settings.Secure.getInt(mResolver, + Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT, + NUMBER_SENT_PACKETS_OF_HANG); + + boolean suspectedStall = DATA_STALL_NOT_SUSPECTED; + if (mSentSinceLastRecv >= hangWatchdogTrigger) { + if (DBG) { + log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction()); + } + suspectedStall = DATA_STALL_SUSPECTED; + sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY)); + } else { + if (VDBG) { + log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) + + " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger); + } + } + startDataStallAlarm(suspectedStall); + } + + protected void startDataStallAlarm(boolean suspectedStall) { + int nextAction = getRecoveryAction(); + int delayInMs; + + // If screen is on or data stall is currently suspected, set the alarm + // with an aggresive timeout. + if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) { + delayInMs = Settings.Secure.getInt(mResolver, + Settings.Secure.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS, + DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT); + } else { + delayInMs = Settings.Secure.getInt(mResolver, + Settings.Secure.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS, + DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT); + } + + mDataStallAlarmTag += 1; + if (VDBG) { + log("startDataStallAlarm: tag=" + mDataStallAlarmTag + + " delay=" + (delayInMs / 1000) + "s"); + } + AlarmManager am = + (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); + + Intent intent = new Intent(getActionIntentDataStallAlarm()); + intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag); + mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent, + PendingIntent.FLAG_UPDATE_CURRENT); + am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, + SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent); + } + + protected void stopDataStallAlarm() { + AlarmManager am = + (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); + + if (VDBG) { + log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag + + " mDataStallAlarmIntent=" + mDataStallAlarmIntent); + } + mDataStallAlarmTag += 1; + if (mDataStallAlarmIntent != null) { + am.cancel(mDataStallAlarmIntent); + mDataStallAlarmIntent = null; + } + } + + protected void restartDataStallAlarm() { + if (isConnected() == false) return; + // To be called on screen status change. + // Do not cancel the alarm if it is set with aggressive timeout. + int nextAction = getRecoveryAction(); + + if (RecoveryAction.isAggressiveRecovery(nextAction)) { + if (DBG) log("data stall recovery action is pending. not resetting the alarm."); + return; + } + stopDataStallAlarm(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); + } + public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("DataConnectionTracker:"); + pw.println(" RADIO_TESTS=" + RADIO_TESTS); pw.println(" mInternalDataEnabled=" + mInternalDataEnabled); pw.println(" mUserDataEnabled=" + mUserDataEnabled); pw.println(" sPolicyDataEnabed=" + sPolicyDataEnabled); @@ -1167,6 +1454,7 @@ public abstract class DataConnectionTracker extends Handler { pw.println(" mDataStallAlarmTag=" + mDataStallAlarmTag); pw.println(" mSentSinceLastRecv=" + mSentSinceLastRecv); pw.println(" mNoRecvPollCount=" + mNoRecvPollCount); + pw.println(" mResolver=" + mResolver); pw.println(" mIsWifiConnected=" + mIsWifiConnected); pw.println(" mReconnectIntent=" + mReconnectIntent); pw.println(" mCidActive=" + mCidActive); diff --git a/src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java index 51b4a4c..070f023 100644 --- a/src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java +++ b/src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java @@ -20,7 +20,6 @@ import android.app.AlarmManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.net.TrafficStats; import android.os.AsyncResult; import android.os.Message; import android.os.SystemClock; @@ -81,7 +80,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { private static final String INTENT_DATA_STALL_ALARM = "com.android.internal.telephony.cdma-data-stall"; - private static final String[] mSupportedApnTypes = { PhoneConstants.APN_TYPE_DEFAULT, PhoneConstants.APN_TYPE_MMS, @@ -196,6 +194,11 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } @Override + public DctConstants.State getOverallState() { + return mState; + } + + @Override protected boolean isApnTypeAvailable(String type) { for (String s : mSupportedApnTypes) { if (TextUtils.equals(type, s)) { @@ -299,6 +302,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { * * @param tearDown true if the underlying DataConnection should be disconnected. * @param reason for the clean up. + * @param doAll Set RefCount to 0 and tear down data call even if + * multiple APN types are associated with it. */ private void cleanUpConnection(boolean tearDown, String reason, boolean doAll) { if (DBG) log("cleanUpConnection: reason: " + reason); @@ -341,6 +346,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } stopNetStatPoll(); + stopDataStallAlarm(); if (!notificationDeferred) { if (DBG) log("cleanupConnection: !notificationDeferred"); @@ -396,34 +402,10 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { setState(DctConstants.State.CONNECTED); notifyDataConnection(reason); startNetStatPoll(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); mDataConnections.get(0).resetRetryCount(); } - private void resetPollStats() { - mTxPkts = -1; - mRxPkts = -1; - mSentSinceLastRecv = 0; - mNetStatPollPeriod = POLL_NETSTAT_MILLIS; - mNoRecvPollCount = 0; - } - - @Override - protected void startNetStatPoll() { - if (mState == DctConstants.State.CONNECTED && mNetStatPollEnabled == false) { - log("[DataConnection] Start poll NetStat"); - resetPollStats(); - mNetStatPollEnabled = true; - mPollNetStat.run(); - } - } - - @Override - protected void stopNetStatPoll() { - mNetStatPollEnabled = false; - removeCallbacks(mPollNetStat); - log("[DataConnection] Stop poll NetStat"); - } - @Override protected void restartRadio() { if (DBG) log("Cleanup connection and wait " + @@ -433,87 +415,6 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { mPendingRestartRadio = true; } - private Runnable mPollNetStat = new Runnable() { - - public void run() { - long sent, received; - long preTxPkts = -1, preRxPkts = -1; - - DctConstants.Activity newActivity; - - preTxPkts = mTxPkts; - preRxPkts = mRxPkts; - - mTxPkts = TrafficStats.getMobileTxPackets(); - mRxPkts = TrafficStats.getMobileRxPackets(); - - //log("rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts)); - - if (mNetStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) { - sent = mTxPkts - preTxPkts; - received = mRxPkts - preRxPkts; - - if ( sent > 0 && received > 0 ) { - mSentSinceLastRecv = 0; - newActivity = DctConstants.Activity.DATAINANDOUT; - } else if (sent > 0 && received == 0) { - if (mPhone.getState() ==PhoneConstants.State.IDLE) { - mSentSinceLastRecv += sent; - } else { - mSentSinceLastRecv = 0; - } - newActivity = DctConstants.Activity.DATAOUT; - } else if (sent == 0 && received > 0) { - mSentSinceLastRecv = 0; - newActivity = DctConstants.Activity.DATAIN; - } else if (sent == 0 && received == 0) { - newActivity = (mActivity == DctConstants.Activity.DORMANT) ? - mActivity : DctConstants.Activity.NONE; - } else { - mSentSinceLastRecv = 0; - newActivity = (mActivity == DctConstants.Activity.DORMANT) ? - mActivity : DctConstants.Activity.NONE; - } - - if (mActivity != newActivity && mIsScreenOn) { - mActivity = newActivity; - mPhone.notifyDataActivity(); - } - } - - if (mSentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) { - // Packets sent without ack exceeded threshold. - - if (mNoRecvPollCount == 0) { - EventLog.writeEvent( - EventLogTags.PDP_RADIO_RESET_COUNTDOWN_TRIGGERED, - mSentSinceLastRecv); - } - - if (mNoRecvPollCount < NO_RECV_POLL_LIMIT) { - mNoRecvPollCount++; - // Slow down the poll interval to let things happen - mNetStatPollPeriod = POLL_NETSTAT_SLOW_MILLIS; - } else { - if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) + - " pkts since last received"); - // We've exceeded the threshold. Restart the radio. - mNetStatPollEnabled = false; - stopNetStatPoll(); - restartRadio(); - EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, NO_RECV_POLL_LIMIT); - } - } else { - mNoRecvPollCount = 0; - mNetStatPollPeriod = POLL_NETSTAT_MILLIS; - } - - if (mNetStatPollEnabled) { - mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod); - } - } - }; - /** * Returns true if the last fail cause is something that * seems like it deserves an error notification. @@ -770,6 +671,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { if (mState == DctConstants.State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) { stopNetStatPoll(); + stopDataStallAlarm(); notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED); notifyOffApnsOfAvailability(Phone.REASON_VOICE_CALL_STARTED); } @@ -783,6 +685,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { if (mState == DctConstants.State.CONNECTED) { if (!mCdmaPhone.mSST.isConcurrentVoiceAndDataAllowed()) { startNetStatPoll(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED); } else { // clean slate after call end. @@ -848,6 +751,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { private void onCdmaDataDetached() { if (mState == DctConstants.State.CONNECTED) { startNetStatPoll(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED); } else { if (mState == DctConstants.State.FAILED) { @@ -940,6 +844,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { mActivity = DctConstants.Activity.NONE; mPhone.notifyDataActivity(); startNetStatPoll(); + startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); break; case DATA_CONNECTION_ACTIVE_PH_LINK_DOWN: @@ -947,6 +852,7 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { mActivity = DctConstants.Activity.DORMANT; mPhone.notifyDataActivity(); stopNetStatPoll(); + stopDataStallAlarm(); break; default: @@ -1043,6 +949,11 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker { } @Override + protected boolean isConnected() { + return (mState == DctConstants.State.CONNECTED); + } + + @Override protected void log(String s) { Log.d(LOG_TAG, "[CdmaDCT] " + s); } diff --git a/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java index a1812f1..c285393 100644 --- a/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java +++ b/src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java @@ -82,7 +82,6 @@ import java.util.concurrent.ConcurrentHashMap; */ public final class GsmDataConnectionTracker extends DataConnectionTracker { protected final String LOG_TAG = "GSM"; - private static final boolean RADIO_TESTS = false; /** * Handles changes to the APN db. @@ -101,35 +100,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { //***** Instance Variables private boolean mReregisterOnReconnectFailure = false; - private ContentResolver mResolver; - // Recovery action taken in case of data stall - private static class RecoveryAction { - public static final int GET_DATA_CALL_LIST = 0; - public static final int CLEANUP = 1; - public static final int REREGISTER = 2; - public static final int RADIO_RESTART = 3; - public static final int RADIO_RESTART_WITH_PROP = 4; - - private static boolean isAggressiveRecovery(int value) { - return ((value == RecoveryAction.CLEANUP) || - (value == RecoveryAction.REREGISTER) || - (value == RecoveryAction.RADIO_RESTART) || - (value == RecoveryAction.RADIO_RESTART_WITH_PROP)); - } - } - - public int getRecoveryAction() { - int action = Settings.System.getInt(mPhone.getContext().getContentResolver(), - "radio.data.stall.recovery.action", RecoveryAction.GET_DATA_CALL_LIST); - if (VDBG) log("getRecoveryAction: " + action); - return action; - } - public void putRecoveryAction(int action) { - Settings.System.putInt(mPhone.getContext().getContentResolver(), - "radio.data.stall.recovery.action", action); - if (VDBG) log("putRecoveryAction: " + action); - } //***** Constants @@ -210,13 +181,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { p.getServiceStateTracker().registerForPsRestrictedDisabled(this, DctConstants.EVENT_PS_RESTRICT_DISABLED, null); - // install reconnect intent filter for this data connection. - IntentFilter filter = new IntentFilter(); - filter.addAction(INTENT_DATA_STALL_ALARM); - p.getContext().registerReceiver(mIntentReceiver, filter, null, p); - mDataConnectionTracker = this; - mResolver = mPhone.getContext().getContentResolver(); mApnObserver = new ApnChangeObserver(); p.getContext().getContentResolver().registerContentObserver( @@ -1394,85 +1359,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { mActiveApn = null; } - private void resetPollStats() { - mTxPkts = -1; - mRxPkts = -1; - mNetStatPollPeriod = POLL_NETSTAT_MILLIS; - } - - private void doRecovery() { - if (getOverallState() == DctConstants.State.CONNECTED) { - // Go through a series of recovery steps, each action transitions to the next action - int recoveryAction = getRecoveryAction(); - switch (recoveryAction) { - case RecoveryAction.GET_DATA_CALL_LIST: - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_GET_DATA_CALL_LIST, - mSentSinceLastRecv); - if (DBG) log("doRecovery() get data call list"); - mPhone.mCM.getDataCallList(obtainMessage(DctConstants.EVENT_DATA_STATE_CHANGED)); - putRecoveryAction(RecoveryAction.CLEANUP); - break; - case RecoveryAction.CLEANUP: - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_CLEANUP, mSentSinceLastRecv); - if (DBG) log("doRecovery() cleanup all connections"); - cleanUpAllConnections(true, Phone.REASON_PDP_RESET); - putRecoveryAction(RecoveryAction.REREGISTER); - break; - case RecoveryAction.REREGISTER: - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_REREGISTER, - mSentSinceLastRecv); - if (DBG) log("doRecovery() re-register"); - mPhone.getServiceStateTracker().reRegisterNetwork(null); - putRecoveryAction(RecoveryAction.RADIO_RESTART); - break; - case RecoveryAction.RADIO_RESTART: - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART, - mSentSinceLastRecv); - if (DBG) log("restarting radio"); - putRecoveryAction(RecoveryAction.RADIO_RESTART_WITH_PROP); - restartRadio(); - break; - case RecoveryAction.RADIO_RESTART_WITH_PROP: - // This is in case radio restart has not recovered the data. - // It will set an additional "gsm.radioreset" property to tell - // RIL or system to take further action. - // The implementation of hard reset recovery action is up to OEM product. - // Once gsm.radioreset property is consumed, it is expected to set back - // to false by RIL. - EventLog.writeEvent(EventLogTags.DATA_STALL_RECOVERY_RADIO_RESTART_WITH_PROP, -1); - if (DBG) log("restarting radio with gsm.radioreset to true"); - SystemProperties.set("gsm.radioreset", "true"); - // give 1 sec so property change can be notified. - try { - Thread.sleep(1000); - } catch (InterruptedException e) {} - restartRadio(); - putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST); - break; - default: - throw new RuntimeException("doRecovery: Invalid recoveryAction=" + - recoveryAction); - } - } - } - - @Override - protected void startNetStatPoll() { - if (getOverallState() == DctConstants.State.CONNECTED && mNetStatPollEnabled == false) { - if (DBG) log("startNetStatPoll"); - resetPollStats(); - mNetStatPollEnabled = true; - mPollNetStat.run(); - } - } - - @Override - protected void stopNetStatPoll() { - mNetStatPollEnabled = false; - removeCallbacks(mPollNetStat); - if (DBG) log("stopNetStatPoll"); - } - @Override protected void restartRadio() { if (DBG) log("restartRadio: ************TURN OFF RADIO**************"); @@ -1490,141 +1376,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { SystemProperties.set("net.ppp.reset-by-timeout", String.valueOf(reset+1)); } - - private void updateDataStallInfo() { - long sent, received; - - TxRxSum preTxRxSum = new TxRxSum(mDataStallTxRxSum); - mDataStallTxRxSum.updateTxRxSum(); - - if (VDBG) { - log("updateDataStallInfo: mDataStallTxRxSum=" + mDataStallTxRxSum + - " preTxRxSum=" + preTxRxSum); - } - - sent = mDataStallTxRxSum.txPkts - preTxRxSum.txPkts; - received = mDataStallTxRxSum.rxPkts - preTxRxSum.rxPkts; - - if (RADIO_TESTS) { - if (SystemProperties.getBoolean("radio.test.data.stall", false)) { - log("updateDataStallInfo: radio.test.data.stall true received = 0;"); - received = 0; - } - } - if ( sent > 0 && received > 0 ) { - if (VDBG) log("updateDataStallInfo: IN/OUT"); - mSentSinceLastRecv = 0; - putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST); - } else if (sent > 0 && received == 0) { - if (mPhone.getState() == PhoneConstants.State.IDLE) { - mSentSinceLastRecv += sent; - } else { - mSentSinceLastRecv = 0; - } - if (DBG) { - log("updateDataStallInfo: OUT sent=" + sent + - " mSentSinceLastRecv=" + mSentSinceLastRecv); - } - } else if (sent == 0 && received > 0) { - if (VDBG) log("updateDataStallInfo: IN"); - mSentSinceLastRecv = 0; - putRecoveryAction(RecoveryAction.GET_DATA_CALL_LIST); - } else { - if (VDBG) log("updateDataStallInfo: NONE"); - } - } - - @Override - protected void onDataStallAlarm(int tag) { - if (mDataStallAlarmTag != tag) { - if (DBG) { - log("onDataStallAlarm: ignore, tag=" + tag + " expecting " + mDataStallAlarmTag); - } - return; - } - updateDataStallInfo(); - - int hangWatchdogTrigger = Settings.Secure.getInt(mResolver, - Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT, - NUMBER_SENT_PACKETS_OF_HANG); - - boolean suspectedStall = DATA_STALL_NOT_SUSPECTED; - if (mSentSinceLastRecv >= hangWatchdogTrigger) { - if (DBG) { - log("onDataStallAlarm: tag=" + tag + " do recovery action=" + getRecoveryAction()); - } - suspectedStall = DATA_STALL_SUSPECTED; - sendMessage(obtainMessage(DctConstants.EVENT_DO_RECOVERY)); - } else { - if (VDBG) { - log("onDataStallAlarm: tag=" + tag + " Sent " + String.valueOf(mSentSinceLastRecv) + - " pkts since last received, < watchdogTrigger=" + hangWatchdogTrigger); - } - } - startDataStallAlarm(suspectedStall); - } - - - private void updateDataActivity() { - long sent, received; - - DctConstants.Activity newActivity; - - TxRxSum preTxRxSum = new TxRxSum(mTxPkts, mRxPkts); - TxRxSum curTxRxSum = new TxRxSum(); - curTxRxSum.updateTxRxSum(); - mTxPkts = curTxRxSum.txPkts; - mRxPkts = curTxRxSum.rxPkts; - - if (VDBG) { - log("updateDataActivity: curTxRxSum=" + curTxRxSum + " preTxRxSum=" + preTxRxSum); - } - - if (mNetStatPollEnabled && (preTxRxSum.txPkts > 0 || preTxRxSum.rxPkts > 0)) { - sent = mTxPkts - preTxRxSum.txPkts; - received = mRxPkts - preTxRxSum.rxPkts; - - if (VDBG) log("updateDataActivity: sent=" + sent + " received=" + received); - if ( sent > 0 && received > 0 ) { - newActivity = DctConstants.Activity.DATAINANDOUT; - } else if (sent > 0 && received == 0) { - newActivity = DctConstants.Activity.DATAOUT; - } else if (sent == 0 && received > 0) { - newActivity = DctConstants.Activity.DATAIN; - } else { - newActivity = (mActivity == DctConstants.Activity.DORMANT) ? - mActivity : DctConstants.Activity.NONE; - } - - if (mActivity != newActivity && mIsScreenOn) { - if (VDBG) log("updateDataActivity: newActivity=" + newActivity); - mActivity = newActivity; - mPhone.notifyDataActivity(); - } - } - } - - private Runnable mPollNetStat = new Runnable() - { - @Override - public void run() { - updateDataActivity(); - - if (mIsScreenOn) { - mNetStatPollPeriod = Settings.Secure.getInt(mResolver, - Settings.Secure.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS); - } else { - mNetStatPollPeriod = Settings.Secure.getInt(mResolver, - Settings.Secure.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS, - POLL_NETSTAT_SCREEN_OFF_MILLIS); - } - - if (mNetStatPollEnabled) { - mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod); - } - } - }; - /** * Returns true if the last fail cause is something that * seems like it deserves an error notification. @@ -1749,68 +1500,6 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { } - private void startDataStallAlarm(boolean suspectedStall) { - int nextAction = getRecoveryAction(); - int delayInMs; - - // If screen is on or data stall is currently suspected, set the alarm - // with an aggresive timeout. - if (mIsScreenOn || suspectedStall || RecoveryAction.isAggressiveRecovery(nextAction)) { - delayInMs = Settings.Secure.getInt(mResolver, - Settings.Secure.DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS, - DATA_STALL_ALARM_AGGRESSIVE_DELAY_IN_MS_DEFAULT); - } else { - delayInMs = Settings.Secure.getInt(mResolver, - Settings.Secure.DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS, - DATA_STALL_ALARM_NON_AGGRESSIVE_DELAY_IN_MS_DEFAULT); - } - - mDataStallAlarmTag += 1; - if (VDBG) { - log("startDataStallAlarm: tag=" + mDataStallAlarmTag + - " delay=" + (delayInMs / 1000) + "s"); - } - AlarmManager am = - (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - - Intent intent = new Intent(INTENT_DATA_STALL_ALARM); - intent.putExtra(DATA_STALL_ALARM_TAG_EXTRA, mDataStallAlarmTag); - mDataStallAlarmIntent = PendingIntent.getBroadcast(mPhone.getContext(), 0, intent, - PendingIntent.FLAG_UPDATE_CURRENT); - am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, - SystemClock.elapsedRealtime() + delayInMs, mDataStallAlarmIntent); - } - - private void stopDataStallAlarm() { - AlarmManager am = - (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE); - - if (VDBG) { - log("stopDataStallAlarm: current tag=" + mDataStallAlarmTag + - " mDataStallAlarmIntent=" + mDataStallAlarmIntent); - } - mDataStallAlarmTag += 1; - if (mDataStallAlarmIntent != null) { - am.cancel(mDataStallAlarmIntent); - mDataStallAlarmIntent = null; - } - } - - @Override - protected void restartDataStallAlarm() { - if (isConnected() == false) return; - // To be called on screen status change. - // Do not cancel the alarm if it is set with aggressive timeout. - int nextAction = getRecoveryAction(); - - if (RecoveryAction.isAggressiveRecovery(nextAction)) { - if (DBG) log("data stall recovery action is pending. not resetting the alarm."); - return; - } - stopDataStallAlarm(); - startDataStallAlarm(DATA_STALL_NOT_SUSPECTED); - } - private void notifyNoData(GsmDataConnection.FailCause lastFailCauseCode, ApnContext apnContext) { if (DBG) log( "notifyNoData: type=" + apnContext.getApnType()); @@ -2696,9 +2385,7 @@ public final class GsmDataConnectionTracker extends DataConnectionTracker { public void dump(FileDescriptor fd, PrintWriter pw, String[] args) { pw.println("GsmDataConnectionTracker extends:"); super.dump(fd, pw, args); - pw.println(" RADIO_TESTS=" + RADIO_TESTS); pw.println(" mReregisterOnReconnectFailure=" + mReregisterOnReconnectFailure); - pw.println(" mResolver=" + mResolver); pw.println(" canSetPreferApn=" + canSetPreferApn); pw.println(" mApnObserver=" + mApnObserver); pw.println(" getOverallState=" + getOverallState()); |