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

Commit 229cbaf2 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I026a4d71,I88e2284a into tm-dev

* changes:
  Fixed delay data switching issue
  Fixed network request not detached from data network
parents 19191387 8d249387
Loading
Loading
Loading
Loading
+56 −8
Original line number Diff line number Diff line
@@ -59,6 +59,7 @@ import android.telephony.NetworkRegistrationInfo;
import android.telephony.PcoData;
import android.telephony.PreciseDataConnectionState;
import android.telephony.ServiceState;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionPlan;
import android.telephony.TelephonyDisplayInfo;
import android.telephony.TelephonyManager;
@@ -280,6 +281,7 @@ public class DataNetwork extends StateMachine {
                    TEAR_DOWN_REASON_NOT_ALLOWED_BY_POLICY,
                    TEAR_DOWN_REASON_ILLEGAL_STATE,
                    TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK,
                    TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED,
            })
    public @interface TearDownReason {}

@@ -369,6 +371,9 @@ public class DataNetwork extends StateMachine {
    /** Data network tear down due to only allowed single network. */
    public static final int TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK = 29;

    /** Data network tear down due to preferred data switched to another phone. */
    public static final int TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED = 30;

    @IntDef(prefix = {"BANDWIDTH_SOURCE_"},
            value = {
                    BANDWIDTH_SOURCE_UNKNOWN,
@@ -467,6 +472,9 @@ public class DataNetwork extends StateMachine {
     */
    private final int mSubId;

    /** The network score of this network. */
    private int mNetworkScore;

    /**
     * Indicates that
     * {@link DataService.DataServiceProvider#deactivateDataCall(int, int, DataServiceCallback)}
@@ -955,8 +963,10 @@ public class DataNetwork extends StateMachine {
                mPhone.getPhoneId());
        final NetworkProvider provider = (null == factory) ? null : factory.getProvider();

        mNetworkScore = getNetworkScore();
        return new TelephonyNetworkAgent(mPhone, getHandler().getLooper(), this,
                getNetworkScore(), configBuilder.build(), provider,
                new NetworkScore.Builder().setLegacyInt(mNetworkScore).build(),
                configBuilder.build(), provider,
                new TelephonyNetworkAgentCallback(getHandler()::post) {
                    @Override
                    public void onValidationStatus(@ValidationStatus int status,
@@ -1047,13 +1057,12 @@ public class DataNetwork extends StateMachine {
                }
                case EVENT_ATTACH_NETWORK_REQUEST: {
                    onAttachNetworkRequests((NetworkRequestList) msg.obj);
                    updateNetworkScore();
                    break;
                }
                case EVENT_DETACH_NETWORK_REQUEST: {
                    TelephonyNetworkRequest networkRequest = (TelephonyNetworkRequest) msg.obj;
                    mAttachedNetworkRequestList.remove(networkRequest);
                    networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED);
                    networkRequest.setAttachedNetwork(null);
                    onDetachNetworkRequest((TelephonyNetworkRequest) msg.obj);
                    updateNetworkScore();
                    break;
                }
                case EVENT_DETACH_ALL_NETWORK_REQUESTS: {
@@ -1618,6 +1627,31 @@ public class DataNetwork extends StateMachine {
        }
    }

    /**
     * Called when detaching the network request from this data network.
     *
     * @param networkRequest Network request to detach.
     */
    private void onDetachNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
        mAttachedNetworkRequestList.remove(networkRequest);
        networkRequest.setState(TelephonyNetworkRequest.REQUEST_STATE_UNSATISFIED);
        networkRequest.setAttachedNetwork(null);

        if (mAttachedNetworkRequestList.isEmpty()) {
            log("All network requests are detached.");

            // If there is no network request attached, and we are not preferred data phone, then
            // this detach is likely due to temp DDS switch. We should tear down the network when
            // all requests are detached so the other network on preferred data sub can be
            // established properly.
            int preferredDataPhoneId = PhoneSwitcher.getInstance().getPreferredDataPhoneId();
            if (preferredDataPhoneId != SubscriptionManager.INVALID_PHONE_INDEX
                    && preferredDataPhoneId != mPhone.getPhoneId()) {
                tearDown(TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED);
            }
        }
    }

    /**
     * Detach the network request from this data network. Note that this will not tear down the
     * network.
@@ -2758,17 +2792,28 @@ public class DataNetwork extends StateMachine {
        return mLinkStatus;
    }

    /**
     * Update the network score and report to connectivity service if necessary.
     */
    private void updateNetworkScore() {
        int networkScore = getNetworkScore();
        if (networkScore != mNetworkScore) {
            logl("Updating score from " + mNetworkScore + " to " + networkScore);
            mNetworkScore = networkScore;
            mNetworkAgent.sendNetworkScore(mNetworkScore);
        }
    }

    /**
     * @return The network score. The higher score of the network has higher chance to be
     * selected by the connectivity service as active network.
     */
    private @NonNull NetworkScore getNetworkScore() {
    private int getNetworkScore() {
        // If it's serving a network request that asks NET_CAPABILITY_INTERNET and doesn't have
        // specify a sub id, this data network is considered to be default internet data
        // connection. In this case we assign a slightly higher score of 50. The intention is
        // it will not be replaced by other data networks accidentally in DSDS use case.
        int score = OTHER_NETWORK_SCORE;
        // TODO: Should update the score when attached list changed.
        for (TelephonyNetworkRequest networkRequest : mAttachedNetworkRequestList) {
            if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
                    && networkRequest.getNetworkSpecifier() == null) {
@@ -2776,7 +2821,7 @@ public class DataNetwork extends StateMachine {
            }
        }

        return new NetworkScore.Builder().setLegacyInt(score).build();
        return score;
    }

    /**
@@ -3207,6 +3252,8 @@ public class DataNetwork extends StateMachine {
                return "TEAR_DOWN_REASON_ILLEGAL_STATE";
            case TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK:
                return "TEAR_DOWN_REASON_ONLY_ALLOWED_SINGLE_NETWORK";
            case TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED:
                return "TEAR_DOWN_REASON_PREFERRED_DATA_SWITCHED";
            default:
                return "UNKNOWN(" + reason + ")";
        }
@@ -3351,6 +3398,7 @@ public class DataNetwork extends StateMachine {
        pw.println("mTransport=" + AccessNetworkConstants.transportTypeToString(mTransport));
        pw.println("WWAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WWAN));
        pw.println("WLAN cid=" + mCid.get(AccessNetworkConstants.TRANSPORT_TYPE_WLAN));
        pw.println("mNetworkScore=" + mNetworkScore);
        pw.println("mDataAllowedReason=" + mDataAllowedReason);
        pw.println("mPduSessionId=" + mPduSessionId);
        pw.println("mDataProfile=" + mDataProfile);
+13 −5
Original line number Diff line number Diff line
@@ -1989,16 +1989,24 @@ public class DataNetworkController extends Handler {
        sendMessage(obtainMessage(EVENT_REMOVE_NETWORK_REQUEST, networkRequest));
    }

    private void onRemoveNetworkRequest(@NonNull TelephonyNetworkRequest networkRequest) {
    private void onRemoveNetworkRequest(@NonNull TelephonyNetworkRequest request) {
        // The request generated from telephony network factory does not contain the information
        // the original request has, for example, attached data network. We need to find the
        // original one.
        TelephonyNetworkRequest networkRequest = mAllNetworkRequestList.stream()
                .filter(r -> r.equals(request))
                .findFirst()
                .orElse(null);
        if (networkRequest == null || !mAllNetworkRequestList.remove(networkRequest)) {
            loge("onRemoveNetworkRequest: Network request does not exist. " + networkRequest);
            return;
        }

        if (networkRequest.hasCapability(NetworkCapabilities.NET_CAPABILITY_IMS)) {
            mImsThrottleCounter.addOccurrence();
            mLastReleasedImsRequestCapabilities = networkRequest.getCapabilities();
            mLastImsOperationIsRelease = true;
        }
        if (!mAllNetworkRequestList.remove(networkRequest)) {
            loge("onRemoveNetworkRequest: Network request does not exist. " + networkRequest);
            return;
        }

        if (networkRequest.getAttachedNetwork() != null) {
            networkRequest.getAttachedNetwork().detachNetworkRequest(networkRequest);
+44 −0
Original line number Diff line number Diff line
@@ -2957,4 +2957,48 @@ public class DataNetworkControllerTest extends TelephonyTest {
        verifyConnectedNetworkHasCapabilities(NetworkCapabilities.NET_CAPABILITY_IMS,
                NetworkCapabilities.NET_CAPABILITY_MMTEL);
    }

    @Test
    public void testRemoveNetworkRequest() throws Exception {
        NetworkCapabilities netCaps = new NetworkCapabilities();
        netCaps.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);

        NetworkRequest nativeNetworkRequest = new NetworkRequest(netCaps,
                ConnectivityManager.TYPE_MOBILE, 0, NetworkRequest.Type.REQUEST);

        mDataNetworkControllerUT.addNetworkRequest(new TelephonyNetworkRequest(
                nativeNetworkRequest, mPhone));
        processAllMessages();

        // Intentionally create a new telephony request with the original native network request.
        TelephonyNetworkRequest request = new TelephonyNetworkRequest(nativeNetworkRequest, mPhone);

        mDataNetworkControllerUT.removeNetworkRequest(request);
        processAllFutureMessages();

        List<DataNetwork> dataNetworkList = getDataNetworks();
        // The data network should not be torn down after network request removal.
        assertThat(dataNetworkList).hasSize(1);
        // But should be detached from the data network.
        assertThat(dataNetworkList.get(0).getAttachedNetworkRequestList()).isEmpty();
        assertThat(dataNetworkList.get(0).isConnected()).isTrue();
    }

    @Test
    public void testTempDdsSwitchTearDown() throws Exception {
        TelephonyNetworkRequest request = createNetworkRequest(
                NetworkCapabilities.NET_CAPABILITY_INTERNET);
        mDataNetworkControllerUT.addNetworkRequest(request);
        processAllMessages();

        // Now DDS temporarily switched to phone 1
        doReturn(1).when(mMockedPhoneSwitcher).getPreferredDataPhoneId();

        // Simulate telephony network factory remove request due to switch.
        mDataNetworkControllerUT.removeNetworkRequest(request);
        processAllMessages();

        // Data should be torn down on this non-preferred sub.
        verifyAllDataDisconnected();
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -181,6 +181,7 @@ public class DataNetworkTest extends TelephonyTest {
    // Mocked classes
    private DataNetworkCallback mDataNetworkCallback;
    private DataCallSessionStats mDataCallSessionStats;
    private PhoneSwitcher mMockedPhoneSwitcher;

    private final NetworkRegistrationInfo mIwlanNetworkRegistrationInfo =
            new NetworkRegistrationInfo.Builder()
@@ -300,6 +301,8 @@ public class DataNetworkTest extends TelephonyTest {

        mDataNetworkCallback = Mockito.mock(DataNetworkCallback.class);
        mDataCallSessionStats = Mockito.mock(DataCallSessionStats.class);
        mMockedPhoneSwitcher = Mockito.mock(PhoneSwitcher.class);
        replaceInstance(PhoneSwitcher.class, "sPhoneSwitcher", null, mMockedPhoneSwitcher);
        doAnswer(invocation -> {
            ((Runnable) invocation.getArguments()[0]).run();
            return null;