diff options
author | Jack Yu <jackyu@google.com> | 2019-08-06 08:33:51 -0700 |
---|---|---|
committer | Jack Yu <jackyu@google.com> | 2019-08-06 18:01:27 -0700 |
commit | 42e63db5bf11391a04cb5dec4bc99726887b7fa8 (patch) | |
tree | baec74993159304e21fccdd2eb7867037fdf194d | |
parent | d40b0ab7415befcf83f4595fc5ee72e385e4b54d (diff) | |
download | telephony-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.java | 54 | ||||
-rw-r--r-- | src/java/com/android/internal/telephony/dataconnection/DcNetworkAgent.java | 7 |
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) { |