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

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

Added IMS graceful tear down support

If data networks have network requests from MmTel or RCS
packages, wait for MmTel or RCS de-registration signal
before tearing down the network.

Bug: 196597630
Test: Manual
Merged-In: Ie794c236b0a69ebc8f12e30d62560f79d9b21698
Change-Id: Ie794c236b0a69ebc8f12e30d62560f79d9b21698
parent ceca6040
Loading
Loading
Loading
Loading
+45 −2
Original line number Diff line number Diff line
@@ -92,6 +92,8 @@ import com.android.internal.telephony.cdma.EriInfo;
import com.android.internal.telephony.cdma.EriManager;
import com.android.internal.telephony.cdnr.CarrierDisplayNameData;
import com.android.internal.telephony.cdnr.CarrierDisplayNameResolver;
import com.android.internal.telephony.data.DataNetwork;
import com.android.internal.telephony.data.DataNetworkController;
import com.android.internal.telephony.dataconnection.DataConnection;
import com.android.internal.telephony.dataconnection.DcTracker;
import com.android.internal.telephony.dataconnection.TransportManager;
@@ -225,6 +227,12 @@ public class ServiceStateTracker extends Handler {
    /** Waiting period before recheck gprs and voice registration. */
    public static final int DEFAULT_GPRS_CHECK_PERIOD_MILLIS = 60 * 1000;

    /**
     * The timer value to wait for all data networks to be torn down.
     */
    private static final long POWER_OFF_ALL_DATA_NETWORKS_DISCONNECTED_TIMEOUT =
            TimeUnit.SECONDS.toMillis(10);

    /** GSM events */
    protected static final int EVENT_RADIO_STATE_CHANGED                    = 1;
    protected static final int EVENT_NETWORK_STATE_CHANGED                  = 2;
@@ -1166,6 +1174,12 @@ public class ServiceStateTracker extends Handler {
        switch (msg.what) {
            case EVENT_SET_RADIO_POWER_OFF:
                synchronized(this) {
                    if (mPhone.isUsingNewDataStack()) {
                        mPendingRadioPowerOffAfterDataOff = false;
                        log("Wait for all data networks torn down timed out. Power off now.");
                        hangupAndPowerOff();
                        return;
                    }
                    if (mPendingRadioPowerOffAfterDataOff &&
                            (msg.arg1 == mPendingRadioPowerOffAfterDataOffTag)) {
                        if (DBG) log("EVENT_SET_RADIO_OFF, turn radio off now.");
@@ -1443,6 +1457,15 @@ public class ServiceStateTracker extends Handler {
                break;

            case EVENT_ALL_DATA_DISCONNECTED:
                if (mPhone.isUsingNewDataStack()) {
                    if (mPendingRadioPowerOffAfterDataOff) {
                        mPendingRadioPowerOffAfterDataOff = false;
                        removeMessages(EVENT_SET_RADIO_POWER_OFF);
                        if (DBG) log("EVENT_ALL_DATA_DISCONNECTED, turn radio off now.");
                        hangupAndPowerOff();
                        return;
                    }
                }
                int dds = SubscriptionManager.getDefaultDataSubscriptionId();
                ProxyController.getInstance().unregisterForAllDataDisconnected(dds, this);
                synchronized(this) {
@@ -3045,13 +3068,14 @@ public class ServiceStateTracker extends Handler {
        } else if ((!mDesiredPowerState || mRadioDisabledByCarrier) && mCi.getRadioState()
                == TelephonyManager.RADIO_POWER_ON) {
            // If it's on and available and we want it off gracefully
            if (mImsRegistrationOnOff && getRadioPowerOffDelayTimeoutForImsRegistration() > 0) {
            if (!mPhone.isUsingNewDataStack() && mImsRegistrationOnOff
                    && getRadioPowerOffDelayTimeoutForImsRegistration() > 0) {
                if (DBG) log("setPowerStateToDesired: delaying power off until IMS dereg.");
                startDelayRadioOffWaitingForImsDeregTimeout();
                // Return early here as we do not want to hit the cancel timeout code below.
                return;
            } else {
                if (DBG) log("setPowerStateToDesired: powering off");
                if (DBG) log("setPowerStateToDesired: powerOffRadioSafely()");
                powerOffRadioSafely();
            }
        } else if (mDeviceShuttingDown
@@ -4883,6 +4907,24 @@ public class ServiceStateTracker extends Handler {
    public void powerOffRadioSafely() {
        synchronized (this) {
            if (!mPendingRadioPowerOffAfterDataOff) {
                if (mPhone.isUsingNewDataStack()) {
                    mPhone.getDataNetworkController().registerDataNetworkControllerCallback(
                            new DataNetworkController.DataNetworkControllerCallback() {
                                @Override
                                public void onAllDataNetworksDisconnected() {
                                    sendEmptyMessage(EVENT_ALL_DATA_DISCONNECTED);
                                }
                                // One time callback. If all data networks are already disconnected
                                // upon registration, the callback will be invoked immediately.
                            }, true);
                    log("powerOffRadioSafely: Tear down all data networks.");
                    mPhone.getDataNetworkController().tearDownAllDataNetworks(
                            DataNetwork.TEAR_DOWN_REASON_AIRPLANE_MODE_ON);
                    sendEmptyMessageDelayed(EVENT_SET_RADIO_POWER_OFF,
                            POWER_OFF_ALL_DATA_NETWORKS_DISCONNECTED_TIMEOUT);
                    mPendingRadioPowerOffAfterDataOff = true;
                    return;
                }
                int dds = SubscriptionManager.getDefaultDataSubscriptionId();
                // To minimize race conditions we call cleanUpAllConnections on
                // both if else paths instead of before this isDisconnected test.
@@ -4989,6 +5031,7 @@ public class ServiceStateTracker extends Handler {
     * Hang up all voice call and turn off radio. Implemented by derived class.
     */
    protected void hangupAndPowerOff() {
        if (mCi.getRadioState() == TelephonyManager.RADIO_POWER_OFF) return;
        // hang up all active voice calls
        if (!mPhone.isPhoneTypeGsm() || mPhone.isInCall()) {
            mPhone.mCT.mRingingCall.hangupIfAlive();
+9 −0
Original line number Diff line number Diff line
@@ -35,6 +35,7 @@ import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.IndentingPrintWriter;

import com.android.internal.R;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.data.DataRetryManager.DataRetryRule;
import com.android.telephony.Rlog;
@@ -229,6 +230,14 @@ public class DataConfigManager extends Handler {
        return null;
    }

    /**
     * @return The delay in millisecond for IMS graceful tear down. If IMS/RCS de-registration
     * does not complete within the window, the data network will be torn down after timeout.
     */
    public long getImsDeregistrationDelay() {
        return mResources.getInteger(R.integer.config_delay_for_ims_dereg_millis);
    }

    /**
     * Registration point for subscription info ready
     *
+37 −5
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;

/**
 * DataNetwork class represents a single PDN (Packet Data Network).
@@ -1303,14 +1304,45 @@ public class DataNetwork extends StateMachine {
    }

    private void onTearDown(@TearDownReason int reason) {
        log("onTearDown: reason=" + tearDownReasonToString(reason));
        if (shouldPerformGracefulTearDown()) {
            logd("Performing graceful tear down. Wait for IMS/RCS de-registered.");
            return;
        }
        logl("onTearDown: reason=" + tearDownReasonToString(reason));
        // TODO: Need to support DataService.REQUEST_REASON_SHUTDOWN
        mDataServiceManagers.get(mTransport).deactivateDataCall(mCid.get(mTransport),
                DataService.REQUEST_REASON_NORMAL, null);
        mInvokedDataDeactivation = true;
    }

    /**
     * Tear down the data network when condition is met or timed out. Data network will enter
     * {@link DisconnectingState} immediately and waiting for condition met. When condition is met,
     * {@link DataNetworkController} should invoke {@link Consumer#accept(Object)} so the actual
     * tear down work can be performed.
     *
     * This is primarily used for IMS graceful tear down. {@link DataNetworkController} inform
     * {@link DataNetwork} to enter {@link DisconnectingState}. IMS service can observe this
     * through {@link PreciseDataConnectionState#getState()} and then perform IMS de-registration
     * work. After IMS de-registered, {@link DataNetworkController} informs {@link DataNetwork}
     * that it's okay to tear down the network.
     *
     * @param reason The tear down reason.
     *
     * @param timeoutMillis Timeout in milliseconds. Within the time window, clients will have to
     * call {@link Consumer#accept(Object)}, otherwise, data network will be torn down when
     * timed out.
     *
     * @return The runnable for client to execute when condition is met. When executed, tear down
     * will be performed. {@code null} if the data network is already disconnected or being
     * disconnected.
     */
    public @Nullable Runnable tearDownWithCondition(@TearDownReason int reason,
            long timeoutMillis) {
        if (getCurrentState() == null || isDisconnected() || isDisconnecting()) {
            loge("tearDownGracefully: Not in the right state. State=" + getCurrentState());
            return null;
        }
        logl("tearDownWithCondition: reason=" + tearDownReasonToString(reason) + ", timeout="
                + timeoutMillis + "ms.");
        sendMessageDelayed(EVENT_TEAR_DOWN_NETWORK, timeoutMillis);
        return () -> this.tearDown(reason);
    }

    /**
+364 −1

File changed.

Preview size limit exceeded, changes collapsed.

+16 −0
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import android.telephony.Annotation.ValidationStatus;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
import android.telephony.data.ApnSetting.ApnType;
import android.telephony.ims.feature.ImsFeature;

import java.text.SimpleDateFormat;
import java.util.Arrays;
@@ -281,4 +282,19 @@ public class DataUtils {
    public static @NonNull String systemTimeToString(@CurrentTimeMillisLong long systemTime) {
        return (systemTime != 0) ? TIME_FORMAT.format(systemTime) : "never";
    }

    /**
     * Convert the IMS feature to string.
     *
     * @param imsFeature IMS feature.
     * @return IMS feature in string format.
     */
    public static @NonNull String imsFeatureToString(@ImsFeature.FeatureType int imsFeature) {
        switch (imsFeature) {
            case ImsFeature.FEATURE_MMTEL: return "MMTEL";
            case ImsFeature.FEATURE_RCS: return "RCS";
            default:
                return "Unknown(" + imsFeature + ")";
        }
    }
}
Loading