Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a5cfcb34 authored by Jack Yu's avatar Jack Yu
Browse files

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
Merged-In: Idb1aa53d31f7b730946485b17fa088b97f3f9300
Change-Id: Idb1aa53d31f7b730946485b17fa088b97f3f9300
(cherry picked from commit 42e63db5)
parent 003196a8
Loading
Loading
Loading
Loading
+51 −3
Original line number Diff line number Diff line
@@ -55,6 +55,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;
@@ -174,6 +175,8 @@ public class DataConnection extends StateMachine {

    private final String mTagSuffix;

    private final LocalLog mHandoverLocalLog = new LocalLog(100);

    /**
     * Used internally for saving connecting parameters.
     */
@@ -680,6 +683,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);
@@ -1681,6 +1685,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="
@@ -1955,7 +1984,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);
                    mNetworkAgent.sendNetworkCapabilities(getNetworkCapabilities(),
@@ -1963,7 +1994,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 {
@@ -2576,6 +2609,8 @@ public class DataConnection extends StateMachine {
    }

    void setHandoverState(@HandoverState int state) {
        mHandoverLocalLog.log("State changed from " + handoverStateToString(mHandoverState)
                + " to " + handoverStateToString(state));
        mHandoverState = state;
    }

@@ -2772,6 +2807,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.
     *
@@ -2801,7 +2845,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));
@@ -2817,6 +2861,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();
+7 −0
Original line number Diff line number Diff line
@@ -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) {