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

Commit f1bbadd1 authored by Jack Yu's avatar Jack Yu Committed by Automerger Merge Worker
Browse files

Merge "Fixed out of sync suspended state" into sc-dev am: 8e0b0965

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/opt/telephony/+/15133908

Change-Id: I8b02e2b7dd0974c51833343e54018fb29d961216
parents c9c7afb9 8e0b0965
Loading
Loading
Loading
Loading
+32 −29
Original line number Diff line number Diff line
@@ -314,6 +314,10 @@ public class DataConnection extends StateMachine {
    private boolean mUnmeteredOverride;
    private int mRilRat = ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN;
    private int mDataRegState = Integer.MAX_VALUE;
    // Indicating data connection is suspended due to temporary reasons, for example, out of
    // service, concurrency voice/data not supported, etc.. Note this flag is only meaningful when
    // data is in active state. When data is in inactive, connecting, or disconnecting, this flag
    // is unmeaningful.
    private boolean mIsSuspended;
    private int mDownlinkBandwidth = 14;
    private int mUplinkBandwidth = 14;
@@ -487,28 +491,6 @@ public class DataConnection extends StateMachine {
        return new LinkProperties(mLinkProperties);
    }

    boolean isSuspended() {
        // Data can only be (temporarily) suspended while data is in active state
        if (getCurrentState() != mActiveState) return false;

        // never set suspend for emergency apn
        if (mApnSetting != null && mApnSetting.isEmergencyApn()) {
            return false;
        }

        // if we are not in-service change to SUSPENDED
        if (mDataRegState != ServiceState.STATE_IN_SERVICE) {
            return true;
        }

        // check for voice call and concurrency issues
        if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
            return mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE;
        }

        return false;
    }

    boolean isDisconnecting() {
        return getCurrentState() == mDisconnectingState
                || getCurrentState() == mDisconnectingErrorCreatingConnection;
@@ -2339,8 +2321,8 @@ public class DataConnection extends StateMachine {
                    mRilRat = drsRatPair.second;
                    if (DBG) {
                        log("DcDefaultState: EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED"
                                + " drs=" + mDataRegState
                                + " mRilRat=" + mRilRat);
                                + " regState=" + ServiceState.rilServiceStateToString(mDataRegState)
                                + " RAT=" + ServiceState.rilRadioTechnologyToString(mRilRat));
                    }
                    mDataCallSessionStats.onDrsOrRatChanged(mRilRat);
                    break;
@@ -2423,12 +2405,28 @@ public class DataConnection extends StateMachine {
            Rlog.d(getName(), "Setting suspend state without a NetworkAgent");
        }

        boolean suspended = isSuspended();
        if (mIsSuspended != suspended) {
            mIsSuspended = suspended;
        boolean newSuspendedState = false;
        // Data can only be (temporarily) suspended while data is in active state
        if (getCurrentState() == mActiveState) {
            // Never set suspended for emergency apn. Emergency data connection
            // can work while device is not in service.
            if (mApnSetting != null && mApnSetting.isEmergencyApn()) {
                newSuspendedState = false;
            // If we are not in service, change to suspended.
            } else if (mDataRegState != ServiceState.STATE_IN_SERVICE) {
                newSuspendedState = true;
            // Check voice/data concurrency.
            } else if (!mPhone.getServiceStateTracker().isConcurrentVoiceAndDataAllowed()) {
                newSuspendedState = mPhone.getCallTracker().getState() != PhoneConstants.State.IDLE;
            }
        }

        // Only notify when there is a change.
        if (mIsSuspended != newSuspendedState) {
            mIsSuspended = newSuspendedState;

            // If data connection is active, we need to notify the new data connection state
            // changed event.
            // changed event reflecting the latest suspended state.
            if (isActive()) {
                notifyDataConnectionState();
            }
@@ -2921,6 +2919,11 @@ public class DataConnection extends StateMachine {

                mDisabledApnTypeBitMask |= getDisallowedApnTypes();
                updateLinkPropertiesHttpProxy();
                // The suspended state is only meaningful when data is in active state. We need to
                // make sure the suspended state is correct as soon as we enter active state.
                // After this, the network agent will be created with the correct suspended state
                // (i.e. NOT_SUSPENDED capability).
                updateSuspendState();
                mNetworkAgent = new DcNetworkAgent(DataConnection.this, mPhone, mScore,
                        configBuilder.build(), provider, mTransportType);

@@ -3941,7 +3944,7 @@ public class DataConnection extends StateMachine {
            return TelephonyManager.DATA_CONNECTING;
        } else if (isActive()) {
            // The data connection can only be suspended when it's in active state.
            if (isSuspended()) {
            if (mIsSuspended) {
                return TelephonyManager.DATA_SUSPENDED;
            }
            return TelephonyManager.DATA_CONNECTED;
+24 −6
Original line number Diff line number Diff line
@@ -55,6 +55,8 @@ import android.telephony.AccessNetworkConstants;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.ServiceState;
import android.telephony.ServiceState.RegState;
import android.telephony.ServiceState.RilRadioTechnology;
import android.telephony.data.ApnSetting;
import android.telephony.data.DataCallResponse;
import android.telephony.data.DataProfile;
@@ -63,6 +65,7 @@ import android.telephony.data.DataServiceCallback;
import android.telephony.data.TrafficDescriptor;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Pair;

import com.android.internal.R;
import com.android.internal.telephony.PhoneConstants;
@@ -429,9 +432,9 @@ public class DataConnectionTest extends TelephonyTest {
    }

    private boolean isSuspended() throws Exception {
        Method method = DataConnection.class.getDeclaredMethod("isSuspended");
        method.setAccessible(true);
        return (boolean) method.invoke(mDc);
        Field field = DataConnection.class.getDeclaredField("mIsSuspended");
        field.setAccessible(true);
        return field.getBoolean(mDc);
    }

    private SetupResult setLinkProperties(DataCallResponse response, LinkProperties linkProperties)
@@ -926,6 +929,12 @@ public class DataConnectionTest extends TelephonyTest {
        assertTrue(mDc.isInactive());
    }

    private void serviceStateChangedEvent(@RegState int dataRegState, @RilRadioTechnology int rat) {
        mDc.obtainMessage(DataConnection.EVENT_DATA_CONNECTION_DRS_OR_RAT_CHANGED,
                new AsyncResult(null, new Pair<>(dataRegState, rat), null)).sendToTarget();
        waitForMs(100);
    }

    @Test
    @SmallTest
    public void testIsIpAddress() {
@@ -1281,24 +1290,33 @@ public class DataConnectionTest extends TelephonyTest {
        assertTrue(mDc.isInactive());
        doReturn(mApn1).when(mApnContext).getApnSetting();
        doReturn(ApnSetting.TYPE_DEFAULT).when(mApnContext).getApnTypeBitmask();
        doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
        connectEvent(true);

        // Before getting any service state event, the connection should not be suspended.
        assertFalse(isSuspended());

        // Return true if combined reg state is not in service
        doReturn(ServiceState.STATE_OUT_OF_SERVICE).when(mServiceState).getDataRegistrationState();
        serviceStateChangedEvent(ServiceState.STATE_OUT_OF_SERVICE,
                ServiceState.RIL_RADIO_TECHNOLOGY_UNKNOWN);
        assertTrue(isSuspended());

        // Return false if in service and concurrent voice and data is allowed
        doReturn(ServiceState.STATE_IN_SERVICE).when(mServiceState).getDataRegistrationState();
        doReturn(true).when(mSST).isConcurrentVoiceAndDataAllowed();
        serviceStateChangedEvent(ServiceState.STATE_IN_SERVICE,
                ServiceState.RIL_RADIO_TECHNOLOGY_LTE);
        assertFalse(isSuspended());

        // Return false if in service and concurrent voice/data not allowed but call state is idle
        doReturn(false).when(mSST).isConcurrentVoiceAndDataAllowed();
        doReturn(PhoneConstants.State.IDLE).when(mCT).getState();
        mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED);
        waitForMs(100);
        assertFalse(isSuspended());

        // Return true if in service, concurrent voice/data not allowed, and call state not idle
        doReturn(PhoneConstants.State.RINGING).when(mCT).getState();
        mDc.sendMessage(DataConnection.EVENT_DATA_CONNECTION_VOICE_CALL_STARTED);
        waitForMs(100);
        assertTrue(isSuspended());
    }