summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/java/com/android/internal/telephony/DataConnectionTracker.java358
-rw-r--r--src/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java127
-rw-r--r--src/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java313
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());