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

Commit 8e0b0965 authored by Jack Yu's avatar Jack Yu Committed by Android (Google) Code Review
Browse files

Merge "Fixed out of sync suspended state" into sc-dev

parents 15845fa1 e11b6b6a
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());
    }