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

Commit 66ecdf68 authored by Jack Yu's avatar Jack Yu Committed by Gerrit Code Review
Browse files

Merge "Added handover failure fallback support"

parents 09fc1ff7 73316fe8
Loading
Loading
Loading
Loading
+29 −14
Original line number Diff line number Diff line
@@ -69,6 +69,7 @@ import android.telephony.AccessNetworkConstants.TransportType;
import android.telephony.CarrierConfigManager;
import android.telephony.CellLocation;
import android.telephony.DataFailCause;
import android.telephony.DataFailCause.FailCause;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.PcoData;
import android.telephony.Rlog;
@@ -161,15 +162,15 @@ public class DcTracker extends Handler {
    public @interface RequestNetworkType {}

    /**
     * Normal request for {@link #requestNetwork(NetworkRequest, int, LocalLog)}. For request
     * Normal request for {@link #requestNetwork(NetworkRequest, int, Message)}. For request
     * network, this adds the request to the {@link ApnContext}. If there were no network request
     * attached to the {@link ApnContext} earlier, this request setups a data connection.
     */
    public static final int REQUEST_TYPE_NORMAL = 1;

    /**
     * Handover request for {@link #requestNetwork(NetworkRequest, int, LocalLog)} or
     * {@link #releaseNetwork(NetworkRequest, int, LocalLog)}. For request network, this
     * Handover request for {@link #requestNetwork(NetworkRequest, int, Message)} or
     * {@link #releaseNetwork(NetworkRequest, int)}. For request network, this
     * initiates the handover data setup process. The existing data connection will be seamlessly
     * handover to the new network. For release network, this performs a data connection softly
     * clean up at the underlying layer (versus normal data release).
@@ -192,7 +193,7 @@ public class DcTracker extends Handler {
    public static final int RELEASE_TYPE_NORMAL = 1;

    /**
     * Detach request for {@link #releaseNetwork(NetworkRequest, int, LocalLog)} only. This
     * Detach request for {@link #releaseNetwork(NetworkRequest, int)} only. This
     * forces the APN context detach from the data connection. If this {@link ApnContext} is the
     * last one attached to the data connection, the data connection will be torn down, otherwise
     * the data connection remains active.
@@ -200,7 +201,7 @@ public class DcTracker extends Handler {
    public static final int RELEASE_TYPE_DETACH = 2;

    /**
     * Handover request for {@link #releaseNetwork(NetworkRequest, int, LocalLog)}. For release
     * Handover request for {@link #releaseNetwork(NetworkRequest, int)}. For release
     * network, this performs a data connection softly clean up at the underlying layer (versus
     * normal data release).
     */
@@ -211,6 +212,12 @@ public class DcTracker extends Handler {
    static final String DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE = "extra_transport_type";
    static final String DATA_COMPLETE_MSG_EXTRA_REQUEST_TYPE = "extra_request_type";
    static final String DATA_COMPLETE_MSG_EXTRA_SUCCESS = "extra_success";
    /**
     * The flag indicates whether after handover failure, the data connection should remain on the
     * original transport.
     */
    static final String DATA_COMPLETE_MSG_EXTRA_HANDOVER_FAILURE_FALLBACK =
            "extra_handover_failure_fallback";

    private final String mLogTag;

@@ -1834,7 +1841,7 @@ public class DcTracker extends Handler {
        }
    }

    boolean isPermanentFailure(@DataFailCause.FailCause int dcFailCause) {
    boolean isPermanentFailure(@FailCause int dcFailCause) {
        return (DataFailCause.isPermanentFailure(mPhone.getContext(), dcFailCause,
                mPhone.getSubId())
                && (mAttached.get() == false || dcFailCause != DataFailCause.SIGNAL_LOST));
@@ -2188,7 +2195,7 @@ public class DcTracker extends Handler {
                SystemClock.elapsedRealtime() + delay, alarmIntent);
    }

    private void notifyNoData(@DataFailCause.FailCause int lastFailCauseCode,
    private void notifyNoData(@FailCause int lastFailCauseCode,
                              ApnContext apnContext) {
        if (DBG) log( "notifyNoData: type=" + apnContext.getApnType());
        if (isPermanentFailure(lastFailCauseCode)
@@ -2318,13 +2325,19 @@ public class DcTracker extends Handler {

    private void sendRequestNetworkCompleteMsg(Message message, boolean success,
                                               @TransportType int transport,
                                               @RequestNetworkType int requestType) {
                                               @RequestNetworkType int requestType,
                                               @FailCause int cause) {
        if (message == null) return;

        Bundle b = message.getData();
        b.putBoolean(DATA_COMPLETE_MSG_EXTRA_SUCCESS, success);
        b.putInt(DATA_COMPLETE_MSG_EXTRA_REQUEST_TYPE, requestType);
        b.putInt(DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE, transport);
        // TODO: For now this is the only fail cause that we know modem keeps data connection on
        // original transport. Might add more complicated logic or mapping in the future.
        b.putBoolean(DATA_COMPLETE_MSG_EXTRA_HANDOVER_FAILURE_FALLBACK,
                (requestType == REQUEST_TYPE_HANDOVER
                        && cause == DataFailCause.HANDOFF_PREFERENCE_CHANGED));
        message.sendToTarget();
    }

@@ -2339,7 +2352,8 @@ public class DcTracker extends Handler {
        ApnContext apnContext = mApnContextsByType.get(apnType);
        if (apnContext == null) {
            loge("onEnableApn(" + apnType + "): NO ApnContext");
            sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType);
            sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType,
                    DataFailCause.NONE);
            return;
        }

@@ -2354,7 +2368,8 @@ public class DcTracker extends Handler {
            str = "onEnableApn: dependency is not met.";
            if (DBG) log(str);
            apnContext.requestLog(str);
            sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType);
            sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType, requestType,
                    DataFailCause.NONE);
            return;
        }

@@ -2371,13 +2386,13 @@ public class DcTracker extends Handler {
                    apnContext.requestLog("onEnableApn state=CONNECTED, so return");

                    sendRequestNetworkCompleteMsg(onCompleteMsg, true, mTransportType,
                            requestType);
                            requestType, DataFailCause.NONE);
                    return;
                case DISCONNECTING:
                    if (DBG) log("onEnableApn: 'DISCONNECTING' so return");
                    apnContext.requestLog("onEnableApn state=DISCONNECTING, so return");
                    sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType,
                            requestType);
                            requestType, DataFailCause.NONE);
                    return;
                case IDLE:
                    // fall through: this is unexpected but if it happens cleanup and try setup
@@ -2404,7 +2419,7 @@ public class DcTracker extends Handler {
            addRequestNetworkCompleteMsg(onCompleteMsg, apnType);
        } else {
            sendRequestNetworkCompleteMsg(onCompleteMsg, false, mTransportType,
                    requestType);
                    requestType, DataFailCause.NONE);
        }
    }

@@ -2694,7 +2709,7 @@ public class DcTracker extends Handler {
        List<Message> messageList = mRequestNetworkCompletionMsgs.get(apnType);
        if (messageList != null) {
            for (Message msg : messageList) {
                sendRequestNetworkCompleteMsg(msg, success, mTransportType, requestType);
                sendRequestNetworkCompleteMsg(msg, success, mTransportType, requestType, cause);
            }
            messageList.clear();
        }
+28 −22
Original line number Diff line number Diff line
@@ -181,9 +181,12 @@ public class TelephonyNetworkFactory extends NetworkFactory {
                                DcTracker.DATA_COMPLETE_MSG_EXTRA_SUCCESS);
                        int transport = bundle.getInt(
                                DcTracker.DATA_COMPLETE_MSG_EXTRA_TRANSPORT_TYPE);
                        boolean fallback = bundle.getBoolean(
                                DcTracker.DATA_COMPLETE_MSG_EXTRA_HANDOVER_FAILURE_FALLBACK);
                        HandoverParams handoverParams = mPendingHandovers.remove(msg);
                        if (handoverParams != null) {
                            onDataHandoverSetupCompleted(nr, success, transport, handoverParams);
                            onDataHandoverSetupCompleted(nr, success, transport, fallback,
                                    handoverParams);
                        } else {
                            logl("Handover completed but cannot find handover entry!");
                        }
@@ -375,20 +378,22 @@ public class TelephonyNetworkFactory extends NetworkFactory {

        if (!handoverPending) {
            log("No handover request pending. Handover process is now completed");
            handoverParams.callback.onCompleted(true);
            handoverParams.callback.onCompleted(true, false);
        }
    }

    private void onDataHandoverSetupCompleted(NetworkRequest networkRequest, boolean success,
                                              int targetTransport, HandoverParams handoverParams) {
                                              int targetTransport, boolean fallback,
                                              HandoverParams handoverParams) {
        log("onDataHandoverSetupCompleted: " + networkRequest + ", success=" + success
                + ", targetTransport="
                + AccessNetworkConstants.transportTypeToString(targetTransport));

        // At this point, handover setup has been completed on the target transport. No matter
        // succeeded or not, remove the request from the source transport because even the setup
        // failed on target transport, we can retry again there.
                + AccessNetworkConstants.transportTypeToString(targetTransport)
                + ", fallback=" + fallback);

        // At this point, handover setup has been completed on the target transport.
        // If it succeeded, or it failed without falling back to the original transport,
        // we should release the request from the original transport.
        if (!fallback) {
            int originTransport = (targetTransport == AccessNetworkConstants.TRANSPORT_TYPE_WWAN)
                    ? AccessNetworkConstants.TRANSPORT_TYPE_WLAN
                    : AccessNetworkConstants.TRANSPORT_TYPE_WWAN;
@@ -401,8 +406,9 @@ public class TelephonyNetworkFactory extends NetworkFactory {
                    : DcTracker.RELEASE_TYPE_NORMAL;
            releaseNetworkInternal(networkRequest, releaseType, originTransport);
            mNetworkRequests.put(networkRequest, targetTransport);
        }

        handoverParams.callback.onCompleted(success);
        handoverParams.callback.onCompleted(success, fallback);
    }

    protected void log(String s) {
+30 −23
Original line number Diff line number Diff line
@@ -199,8 +199,10 @@ public class TransportManager extends Handler {
             * Called when handover is completed.
             *
             * @param success {@true} if handover succeeded, otherwise failed.
             * @param fallback {@true} if handover failed, the data connection fallback to the
             * original transport
             */
            void onCompleted(boolean success);
            void onCompleted(boolean success, boolean fallback);
        }

        public final @ApnType int apnType;
@@ -347,7 +349,8 @@ public class TransportManager extends Handler {
                            + AccessNetworkConstants.transportTypeToString(targetTransport));
                    mPendingHandoverApns.put(networks.apnType, targetTransport);
                    mHandoverNeededEventRegistrants.notifyResult(
                            new HandoverParams(networks.apnType, targetTransport, success -> {
                            new HandoverParams(networks.apnType, targetTransport,
                                    (success, fallback) -> {
                                        // The callback for handover completed.
                                        if (success) {
                                            logl("Handover succeeded.");
@@ -356,15 +359,19 @@ public class TransportManager extends Handler {
                                                    + ApnSetting.getApnTypeString(networks.apnType)
                                                    + " handover to "
                                                    + AccessNetworkConstants.transportTypeToString(
                                                    targetTransport) + " failed.");
                                                    targetTransport) + " failed."
                                                    + ", fallback=" + fallback);
                                        }
                                // No matter succeeded or not, we need to set the current transport
                                // to the new one. If failed, there will be retry afterwards anyway.
                                        if (success || !fallback) {
                                            // If handover succeeds or failed without falling back
                                            // to the original transport, we should move to the new
                                            // transport (even if it is failed).
                                            setCurrentTransport(networks.apnType, targetTransport);
                                        }
                                        mPendingHandoverApns.delete(networks.apnType);

                                // If there are still pending available network changes, we need to
                                // process the rest.
                                        // If there are still pending available network changes, we
                                        // need to process the rest.
                                        if (mAvailableNetworksList.size() > 0) {
                                            sendEmptyMessage(EVENT_UPDATE_AVAILABLE_NETWORKS);
                                        }
+3 −3
Original line number Diff line number Diff line
@@ -129,7 +129,7 @@ public class TransportManagerTest extends TelephonyTest {
        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN, params.targetTransport);

        // Notify handover succeeded.
        params.callback.onCompleted(true);
        params.callback.onCompleted(true, false);
        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));

@@ -158,7 +158,7 @@ public class TransportManagerTest extends TelephonyTest {
        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));
        // Notify handover succeeded.
        params.callback.onCompleted(true);
        params.callback.onCompleted(true, false);
        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WWAN,
                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));
    }
@@ -256,7 +256,7 @@ public class TransportManagerTest extends TelephonyTest {
        assertEquals(1, listQueue.size());

        // Notify handover succeeded.
        params.callback.onCompleted(true);
        params.callback.onCompleted(true, false);
        assertEquals(AccessNetworkConstants.TRANSPORT_TYPE_WLAN,
                mTransportManager.getCurrentTransport(ApnSetting.TYPE_IMS));
        waitForMs(100);