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

Commit 99c3559a authored by Nathan Harold's avatar Nathan Harold
Browse files

Fix RatRatcheter skipping the first Ratchet

The code was skipping the first ratchet, which is the second
time that RatRatcheter#ratchet() was being called on the same
cell. This CL:
-fixes the bug that was causing the first ratchet to be skipped;
-simplifies the logic so that the ratcheter is only called
 when ratcheting should be performed, moving the check for
 whether or not to ratchet back into SST;
-ratchets if the registered cell is a voice or data registration
 which fixes a bug that CS-only registrations (such as on WCDMA)
 weren't being ratcheted.

Bug: 156676862
Test: atest RatRatcheterTest; atest ServiceStateTrackerTest
Change-Id: I710c338289d54d2029dc5aba572ba201d07872af
parent be2d2aeb
Loading
Loading
Loading
Loading
+23 −42
Original line number Diff line number Diff line
@@ -54,8 +54,6 @@ public class RatRatcheter {
    private final SparseArray<SparseIntArray> mRatFamilyMap = new SparseArray<>();

    private final Phone mPhone;
    private boolean mVoiceRatchetEnabled = true;
    private boolean mDataRatchetEnabled = true;

    /**
     * Updates the ServiceState with a new set of cell bandwidths IFF the new bandwidth list has a
@@ -119,52 +117,35 @@ public class RatRatcheter {
        }
    }

    /** Ratchets RATs and cell bandwidths if oldSS and newSS have the same RAT family. */
    public void ratchet(@NonNull ServiceState oldSS, @NonNull ServiceState newSS,
                        boolean locationChange) {
        // temporarily disable rat ratchet on location change.
        if (locationChange) {
            mVoiceRatchetEnabled = false;
            mDataRatchetEnabled = false;
            return;
        }

    /**
     * Ratchets RATs and cell bandwidths if oldSS and newSS have the same RAT family.
     *
     * Ensure that a device on the same cell reports the best-seen capability to the user.
     */
    public void ratchet(@NonNull ServiceState oldSS, @NonNull ServiceState newSS) {
        // Different rat family, don't need rat ratchet and update cell bandwidths.
        if (!isSameRatFamily(oldSS, newSS)) {
            Rlog.e(LOG_TAG, "Same cell cannot have different RAT Families. Likely bug.");
            return;
        }

        updateBandwidths(oldSS.getCellBandwidths(), newSS);
        final int[] domains = {
                NetworkRegistrationInfo.DOMAIN_CS, NetworkRegistrationInfo.DOMAIN_PS};
        for (int domain : domains) {
            NetworkRegistrationInfo oldNri = oldSS.getNetworkRegistrationInfo(
                    domain, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
            NetworkRegistrationInfo newNri = newSS.getNetworkRegistrationInfo(
                    domain, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);

        NetworkRegistrationInfo oldCsNri = oldSS.getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        NetworkRegistrationInfo newCsNri = newSS.getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_CS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        if (mVoiceRatchetEnabled) {
            int newPsNetworkType = ratchetRat(oldCsNri.getAccessNetworkTechnology(),
                    newCsNri.getAccessNetworkTechnology());
            newCsNri.setAccessNetworkTechnology(newPsNetworkType);
            newSS.addNetworkRegistrationInfo(newCsNri);
            if (oldCsNri.isUsingCarrierAggregation()) newCsNri.setIsUsingCarrierAggregation(true);
        } else if (oldCsNri.getAccessNetworkTechnology() != oldCsNri.getAccessNetworkTechnology()) {
            // resume rat ratchet on following rat change within the same location
            mVoiceRatchetEnabled = true;
        }

        NetworkRegistrationInfo oldPsNri = oldSS.getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        NetworkRegistrationInfo newPsNri = newSS.getNetworkRegistrationInfo(
                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        if (mDataRatchetEnabled) {
            int newPsNetworkType = ratchetRat(oldPsNri.getAccessNetworkTechnology(),
                    newPsNri.getAccessNetworkTechnology());
            newPsNri.setAccessNetworkTechnology(newPsNetworkType);
            newSS.addNetworkRegistrationInfo(newPsNri);
            if (oldPsNri.isUsingCarrierAggregation()) newPsNri.setIsUsingCarrierAggregation(true);
        } else if (oldPsNri.getAccessNetworkTechnology() != newPsNri.getAccessNetworkTechnology()) {
            // resume rat ratchet on following rat change within the same location
            mDataRatchetEnabled = true;
            int newNetworkType = ratchetRat(oldNri.getAccessNetworkTechnology(),
                    newNri.getAccessNetworkTechnology());
            newNri.setAccessNetworkTechnology(newNetworkType);
            if (oldNri.isUsingCarrierAggregation()) newNri.setIsUsingCarrierAggregation(true);
            newSS.addNetworkRegistrationInfo(newNri);
        }

        // Ratchet Cell Bandwidths
        updateBandwidths(oldSS.getCellBandwidths(), newSS);
    }

    private boolean isSameRatFamily(ServiceState ss1, ServiceState ss2) {
+9 −6
Original line number Diff line number Diff line
@@ -3285,12 +3285,15 @@ public class ServiceStateTracker extends Handler {
        boolean hasLocationChanged = mCellIdentity == null
                ? primaryCellIdentity != null : !mCellIdentity.isSameCell(primaryCellIdentity);

        // ratchet the new tech up through its rat family but don't drop back down
        // until cell change or device is OOS
        boolean isDataInService = mNewSS.getDataRegistrationState()
                == ServiceState.STATE_IN_SERVICE;
        if (isDataInService) {
            mRatRatcheter.ratchet(mSS, mNewSS, hasLocationChanged);
        boolean isRegisteredOnWwan = false;
        for (NetworkRegistrationInfo nri : mNewSS.getNetworkRegistrationInfoListForTransportType(
                AccessNetworkConstants.TRANSPORT_TYPE_WWAN)) {
            isRegisteredOnWwan |= nri.isRegistered();
        }

        // Ratchet if the device is in service on the same cell
        if (isRegisteredOnWwan && !hasLocationChanged) {
            mRatRatcheter.ratchet(mSS, mNewSS);
        }

        boolean hasRilVoiceRadioTechnologyChanged =
+2 −2
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ public class RatRatcheterTest extends TelephonyTest {
        setNetworkRegistrationInfo(newSS, TelephonyManager.NETWORK_TYPE_LTE);

        RatRatcheter ratRatcheter = new RatRatcheter(mPhone);
        ratRatcheter.ratchet(oldSS, newSS, false);
        ratRatcheter.ratchet(oldSS, newSS);

        assertTrue(newSS.isUsingCarrierAggregation());
    }
@@ -157,7 +157,7 @@ public class RatRatcheterTest extends TelephonyTest {
        setNetworkRegistrationInfo(newSS, TelephonyManager.NETWORK_TYPE_LTE);

        RatRatcheter ratRatcheter = new RatRatcheter(mPhone);
        ratRatcheter.ratchet(oldSS, newSS, false);
        ratRatcheter.ratchet(oldSS, newSS);

        assertFalse(newSS.isUsingCarrierAggregation());
    }
+0 −24
Original line number Diff line number Diff line
@@ -2024,30 +2024,6 @@ public class ServiceStateTrackerTest extends TelephonyTest {

    }

    // TODO(nharold): This actually seems like broken behavior; rather than preserve it, we should
    // probably remove it.
    // GSM, Edge, GPRS are grouped under the same family where Edge > GPRS > GSM.
    // Expect no rat update from E to G immediately following cell id change.
    // Expect ratratchet (from G to E) for the following rat update within the cell location.
    @Test
    public void testRatRatchetWithCellChangeBeforeRatChange() throws Exception {
        // cell ID update
        CellIdentityGsm cellIdentity =
                new CellIdentityGsm(0, 1, 900, 5, "001", "01", "test", "tst",
                        Collections.emptyList());
        changeRegState(1, cellIdentity, 16, 2);
        assertEquals(ServiceState.STATE_IN_SERVICE, sst.getCurrentDataConnectionState());
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilDataRadioTechnology());

        // RAT: EDGE -> GPRS, cell ID unchanged. Expect no rat ratchet following cell Id change.
        changeRegState(1, cellIdentity, 16, 1);
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilDataRadioTechnology());

        // RAT: GPRS -> EDGE should ratchet.
        changeRegState(1, cellIdentity, 16, 2);
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilDataRadioTechnology());
    }

    private void sendPhyChanConfigChange(int[] bandwidths) {
        ArrayList<PhysicalChannelConfig> pc = new ArrayList<>();
        int ssType = PhysicalChannelConfig.CONNECTION_PRIMARY_SERVING;