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

Commit 68ca97e8 authored by Jack Yu's avatar Jack Yu
Browse files

Fixed unnecessary tear down

1. Register RAT/registration state changed event
   from service state tracker will not trigger
   sending changed event to all registrants anymore.
2. When building waiting APNs to reevalulate if tearing
   down is needed or not, will check if the APN setting
   from the current data connection is one of the APN
   setting in the new list. If yes, will not tear down
   the data connection.

Fix: 150818730
Test: Unit tests + telephony sanity tests
Merged-In: I7015ba147534fe0dd8feb3ac7a068f3138ece399
Change-Id: I7015ba147534fe0dd8feb3ac7a068f3138ece399
(cherry picked from commit 58e07dfb)
parent 7da5facc
Loading
Loading
Loading
Loading
+28 −12
Original line number Diff line number Diff line
@@ -859,27 +859,39 @@ public class ServiceStateTracker extends Handler {
    }

    /**
     * Notify all mDataConnectionRatChangeRegistrants using an
     * AsyncResult in msg.obj where AsyncResult#result contains the
     * new RAT as an Integer Object.
     * Get registration info
     *
     * @param transport The transport type
     * @return Pair of registration info including {@link ServiceState.RegState} and
     * {@link RilRadioTechnology}.
     *
     */
    protected void notifyDataRegStateRilRadioTechnologyChanged(int transport) {
    @Nullable
    private Pair<Integer, Integer> getRegistrationInfo(@TransportType int transport) {
        NetworkRegistrationInfo nrs = mSS.getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_PS, transport);
        if (nrs != null) {
            int rat = ServiceState.networkTypeToRilRadioTechnology(
                    nrs.getAccessNetworkTechnology());
            int drs = regCodeToServiceState(nrs.getRegistrationState());
            if (DBG) {
                log("notifyDataRegStateRilRadioTechnologyChanged: drs=" + drs + " rat=" + rat);
            return new Pair<>(drs, rat);
        }
        return null;
    }

    /**
     * Notify all mDataConnectionRatChangeRegistrants using an
     * AsyncResult in msg.obj where AsyncResult#result contains the
     * new RAT as an Integer Object.
     */
    protected void notifyDataRegStateRilRadioTechnologyChanged(@TransportType int transport) {
        RegistrantList registrantList = mDataRegStateOrRatChangedRegistrants.get(transport);
        if (registrantList != null) {
                registrantList.notifyResult(new Pair<>(drs, rat));
            Pair<Integer, Integer> registrationInfo = getRegistrationInfo(transport);
            if (registrationInfo != null) {
                registrantList.notifyResult(registrationInfo);
            }
        }
        setDataNetworkTypeForPhone(mSS.getRilDataRadioTechnology());
    }

    /**
@@ -3490,6 +3502,7 @@ public class ServiceStateTracker extends Handler {
                    // Update all transports if preference changed so that consumers can be notified
                    // that ServiceState#getRilDataRadioTechnology has changed.
                    || hasDataTransportPreferenceChanged) {
                setDataNetworkTypeForPhone(mSS.getRilDataRadioTechnology());
                notifyDataRegStateRilRadioTechnologyChanged(transport);
                mPhone.notifyAllActiveDataConnections();
            }
@@ -4485,7 +4498,10 @@ public class ServiceStateTracker extends Handler {
            mDataRegStateOrRatChangedRegistrants.put(transport, new RegistrantList());
        }
        mDataRegStateOrRatChangedRegistrants.get(transport).add(r);
        notifyDataRegStateRilRadioTechnologyChanged(transport);
        Pair<Integer, Integer> registrationInfo = getRegistrationInfo(transport);
        if (registrationInfo != null) {
            r.notifyResult(registrationInfo);
        }
    }

    /**
+18 −26
Original line number Diff line number Diff line
@@ -4480,8 +4480,7 @@ public class DcTracker extends Handler {
        }
    }

    private boolean containsAllApns(ArrayList<ApnSetting> oldApnList,
                                    ArrayList<ApnSetting> newApnList) {
    private boolean containsAllApns(List<ApnSetting> oldApnList, List<ApnSetting> newApnList) {
        for (ApnSetting newApnSetting : newApnList) {
            boolean canHandle = false;
            for (ApnSetting oldApnSetting : oldApnList) {
@@ -4509,39 +4508,32 @@ public class DcTracker extends Handler {
                return;
            }
            for (ApnContext apnContext : mApnContexts.values()) {
                boolean cleanupRequired = false;
                boolean cleanupRequired = true;
                if (!apnContext.isDisconnected()) {
                    ArrayList<ApnSetting> currentWaitingApns = apnContext.getWaitingApns();
                    ArrayList<ApnSetting> waitingApns = buildWaitingApns(
                            apnContext.getApnType(), getDataRat());
                    if (VDBG) log("new waitingApns:" + waitingApns);
                    if ((currentWaitingApns != null)
                            && ((waitingApns.size() != currentWaitingApns.size())
                            // Check if the existing waiting APN list can cover the newly built APN
                            // list. If yes, then we don't need to tear down the existing data call.
                            // TODO: We probably need to rebuild APN list when roaming status
                            //  changes.
                            || !containsAllApns(currentWaitingApns, waitingApns))) {
                        if (VDBG) log("new waiting apn is different for " + apnContext);
                    apnContext.setWaitingApns(waitingApns);
                        ApnSetting apnSetting = apnContext.getApnSetting();
                        if (apnContext.getApnType().equals(PhoneConstants.APN_TYPE_DEFAULT)) {
                            if ((getPreferredApn() == null)
                                    || !apnSetting.equals(getPreferredApn())) {
                                cleanupRequired = true;
                    for (ApnSetting apnSetting : waitingApns) {
                        if (apnSetting.equals(apnContext.getApnSetting(),
                                mPhone.getServiceState().getDataRoamingFromRegistration())) {
                            cleanupRequired = false;
                            break;
                        }
                        } else if (!waitingApns.contains(apnSetting)) {
                            cleanupRequired = true;
                    }

                    if (cleanupRequired) {
                            if (VDBG) log("cleanUpConnectionsOnUpdatedApns for " + apnContext);
                        if (DBG) {
                            log("cleanUpConnectionsOnUpdatedApns: APN type "
                                    + apnContext.getApnType() + " clean up is required. The new "
                                    + "waiting APN list " + waitingApns + " does not cover "
                                    + apnContext.getApnSetting());
                        }
                        apnContext.setReason(reason);
                        cleanUpConnectionInternal(true, RELEASE_TYPE_DETACH, apnContext);
                    }
                }
            }
        }
        }

        if (!isConnected()) {
            stopNetStatPoll();
+57 −0
Original line number Diff line number Diff line
@@ -2232,4 +2232,61 @@ public class DcTrackerTest extends TelephonyTest {

        //No need to clean up handler because that work is done in teardown.
    }*/

    @Test
    public void testRatChanged() throws Exception {
        mSimulatedCommands.setDataCallResult(true, createSetupDataCallResult());

        DataConnectionReasons dataConnectionReasons = new DataConnectionReasons();
        boolean allowed = isDataAllowed(dataConnectionReasons);
        assertFalse(dataConnectionReasons.toString(), allowed);

        logd("Sending EVENT_CARRIER_CONFIG_CHANGED");
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_CARRIER_CONFIG_CHANGED, 1, 0));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        logd("Sending EVENT_DATA_CONNECTION_ATTACHED");
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_CONNECTION_ATTACHED, null));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        logd("Sending EVENT_ENABLE_APN");
        // APN id 0 is APN_TYPE_DEFAULT
        mDct.enableApn(ApnSetting.TYPE_DEFAULT, DcTracker.REQUEST_TYPE_NORMAL, null);
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());

        waitForMs(200);

        dataConnectionReasons = new DataConnectionReasons();
        allowed = isDataAllowed(dataConnectionReasons);
        assertTrue(dataConnectionReasons.toString(), allowed);

        ArgumentCaptor<DataProfile> dpCaptor = ArgumentCaptor.forClass(DataProfile.class);
        // Verify if RIL command was sent properly.
        verify(mSimulatedCommandsVerifier, times(1)).setupDataCall(
                eq(AccessNetworkType.EUTRAN), dpCaptor.capture(),
                eq(false), eq(false), eq(DataService.REQUEST_REASON_NORMAL), any(),
                any(Message.class));
        verifyDataProfile(dpCaptor.getValue(), FAKE_APN1, 0, 21, 1, NETWORK_TYPE_LTE_BITMASK);

        verifyDataConnected(FAKE_APN1);

        doReturn(ServiceState.RIL_RADIO_TECHNOLOGY_UMTS).when(mServiceState)
                .getRilDataRadioTechnology();

        logd("Sending EVENT_DATA_RAT_CHANGED");
        mNetworkRegistrationInfo = new NetworkRegistrationInfo.Builder()
                .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_UMTS)
                .setRegistrationState(NetworkRegistrationInfo.REGISTRATION_STATE_HOME)
                .build();
        doReturn(mNetworkRegistrationInfo).when(mServiceState).getNetworkRegistrationInfo(
                anyInt(), anyInt());
        mDct.sendMessage(mDct.obtainMessage(DctConstants.EVENT_DATA_RAT_CHANGED, null));
        waitForLastHandlerAction(mDcTrackerTestHandler.getThreadHandler());
        waitForMs(200);

        // expected tear down all metered DataConnections
        verify(mSimulatedCommandsVerifier).deactivateDataCall(
                eq(DataService.REQUEST_REASON_NORMAL), anyInt(),
                any(Message.class));
    }
}