aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Yu <jackyu@google.com>2019-08-06 08:33:51 -0700
committerJack Yu <jackyu@google.com>2019-08-06 18:01:27 -0700
commit42e63db5bf11391a04cb5dec4bc99726887b7fa8 (patch)
treebaec74993159304e21fccdd2eb7867037fdf194d
parentd40b0ab7415befcf83f4595fc5ee72e385e4b54d (diff)
downloadtelephony-42e63db5bf11391a04cb5dec4bc99726887b7fa8.tar.gz
Fixed dangling network agent issue
In some IWLAN handover failure cases, the associated network agent might became dangling and causes out-of-sync between connectivity service and telephony. Connectivity service incorrectly thought the data connection was already there so reaped the newly created one. Bug: 138287040 Test: Manual Change-Id: Idb1aa53d31f7b730946485b17fa088b97f3f9300
-rw-r--r--src/java/com/android/internal/telephony/dataconnection/DataConnection.java54
-rw-r--r--src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java7
2 files changed, 58 insertions, 3 deletions
diff --git a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
index d1b13232bc..0cd80b3177 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DataConnection.java
@@ -59,6 +59,7 @@ import android.telephony.data.DataProfile;
import android.telephony.data.DataService;
import android.telephony.data.DataServiceCallback;
import android.text.TextUtils;
+import android.util.LocalLog;
import android.util.Pair;
import android.util.StatsLog;
import android.util.TimeUtils;
@@ -178,6 +179,8 @@ public class DataConnection extends StateMachine {
private final String mTagSuffix;
+ private final LocalLog mHandoverLocalLog = new LocalLog(100);
+
/**
* Used internally for saving connecting parameters.
*/
@@ -684,6 +687,7 @@ public class DataConnection extends StateMachine {
linkProperties = dc.getLinkProperties();
// Preserve the potential network agent from the source data connection. The ownership
// is not transferred at this moment.
+ mHandoverLocalLog.log("Handover started. Preserved the agent.");
mHandoverSourceNetworkAgent = dc.getNetworkAgent();
log("Get the handover source network agent: " + mHandoverSourceNetworkAgent);
dc.setHandoverState(HANDOVER_STATE_BEING_TRANSFERRED);
@@ -1685,6 +1689,31 @@ public class DataConnection extends StateMachine {
mHandoverState = HANDOVER_STATE_COMPLETED;
}
+ // Check for dangling agent. Ideally the handover source agent should be null if
+ // handover process is smooth. When it's not null, that means handover failed. The
+ // agent was not successfully transferred to the new data connection. We should
+ // gracefully notify connectivity service the network was disconnected.
+ if (mHandoverSourceNetworkAgent != null) {
+ DataConnection sourceDc = mHandoverSourceNetworkAgent.getDataConnection();
+ if (sourceDc != null) {
+ // If the source data connection still owns this agent, then just reset the
+ // handover state back to idle because handover is already failed.
+ mHandoverLocalLog.log(
+ "Handover failed. Reset the source dc state to idle");
+ sourceDc.setHandoverState(HANDOVER_STATE_IDLE);
+ } else {
+ // The agent is now a dangling agent. No data connection owns this agent.
+ // Gracefully notify connectivity service disconnected.
+ mHandoverLocalLog.log(
+ "Handover failed and dangling agent found.");
+ mHandoverSourceNetworkAgent.acquireOwnership(
+ DataConnection.this, mTransportType);
+ mHandoverSourceNetworkAgent.sendNetworkInfo(mNetworkInfo, DataConnection.this);
+ mHandoverSourceNetworkAgent.releaseOwnership(DataConnection.this);
+ }
+ mHandoverSourceNetworkAgent = null;
+ }
+
if (mConnectionParams != null) {
if (DBG) {
log("DcInactiveState: enter notifyConnectCompleted +ALL failCause="
@@ -1966,7 +1995,9 @@ public class DataConnection extends StateMachine {
}
if (mHandoverSourceNetworkAgent != null) {
- log("Transfer network agent successfully.");
+ String logStr = "Transfer network agent successfully.";
+ log(logStr);
+ mHandoverLocalLog.log(logStr);
mNetworkAgent = mHandoverSourceNetworkAgent;
mNetworkAgent.acquireOwnership(DataConnection.this, mTransportType);
@@ -1980,7 +2011,9 @@ public class DataConnection extends StateMachine {
mNetworkAgent.sendLinkProperties(mLinkProperties, DataConnection.this);
mHandoverSourceNetworkAgent = null;
} else {
- loge("Failed to get network agent from original data connection");
+ String logStr = "Failed to get network agent from original data connection";
+ loge(logStr);
+ mHandoverLocalLog.log(logStr);
return;
}
} else {
@@ -2595,6 +2628,8 @@ public class DataConnection extends StateMachine {
}
void setHandoverState(@HandoverState int state) {
+ mHandoverLocalLog.log("State changed from " + handoverStateToString(mHandoverState)
+ + " to " + handoverStateToString(state));
mHandoverState = state;
}
@@ -2818,6 +2853,15 @@ public class DataConnection extends StateMachine {
return score;
}
+ private String handoverStateToString(@HandoverState int state) {
+ switch (state) {
+ case HANDOVER_STATE_IDLE: return "IDLE";
+ case HANDOVER_STATE_BEING_TRANSFERRED: return "BEING_TRANSFERRED";
+ case HANDOVER_STATE_COMPLETED: return "COMPLETED";
+ default: return "UNKNOWN";
+ }
+ }
+
/**
* Dump the current state.
*
@@ -2847,7 +2891,7 @@ public class DataConnection extends StateMachine {
pw.println("mLinkProperties=" + mLinkProperties);
pw.flush();
pw.println("mDataRegState=" + mDataRegState);
- pw.println("mHandoverState=" + mHandoverState);
+ pw.println("mHandoverState=" + handoverStateToString(mHandoverState));
pw.println("mRilRat=" + mRilRat);
pw.println("mNetworkCapabilities=" + getNetworkCapabilities());
pw.println("mCreateTime=" + TimeUtils.logTimeOfDay(mCreateTime));
@@ -2865,6 +2909,10 @@ public class DataConnection extends StateMachine {
if (mNetworkAgent != null) {
mNetworkAgent.dump(fd, pw, args);
}
+ pw.println("handover local log:");
+ pw.increaseIndent();
+ mHandoverLocalLog.dump(fd, pw, args);
+ pw.decreaseIndent();
pw.decreaseIndent();
pw.println();
pw.flush();
diff --git a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
index b36a490be5..d9edd288b2 100644
--- a/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
+++ b/src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java
@@ -132,6 +132,13 @@ public class DcNetworkAgent extends NetworkAgent {
mDataConnection = null;
}
+ /**
+ * @return The data connection that owns this agent
+ */
+ public synchronized DataConnection getDataConnection() {
+ return mDataConnection;
+ }
+
@Override
protected synchronized void unwanted() {
if (mDataConnection == null) {