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

Commit 277c6456 authored by fionaxu's avatar fionaxu Committed by Chen Xu
Browse files

DO NOT MERGE fix ratratchet when CID change right before RAT change.

There is a timing gap of updating CID and DataRAT when moving between
cell from different RAT (e.g., move from EDGE to GPRS). In that case,
cell ID remains the same when handling rat change, thus ratratchet
will not report lower rate RAT for the purpose of battery-saving.

As its hard to gurantee synchronous cell location change and RAT change,
Frameworks will bypass ratratchet on the next RAT change event
following CID change. This will fix the timeline issue but with some
degree of performance regression when cell location change is not
followed with an immediate RAT change. In that case, we still report
lower rate RAT (only for the next RAT change) and update UI etc.

Bug: 65695609
Test: ServiceStateTrackerTest.java
Change-Id: Ia9cc52fa3c9cd3d6d1fc0ec08c929f52a5752755
parent bc0269bd
Loading
Loading
Loading
Loading
+28 −10
Original line number Diff line number Diff line
@@ -27,8 +27,6 @@ import android.telephony.Rlog;
import android.util.SparseArray;
import android.util.SparseIntArray;

import java.util.ArrayList;

/**
 * This class loads configuration from CarrierConfig and uses it to determine
 * what RATs are within a ratcheting family.  For example all the HSPA/HSDPA/HSUPA RATs.
@@ -49,6 +47,9 @@ public class RatRatcheter {

    private final Phone mPhone;

    private boolean mVoiceRatchetEnabled = true;
    private boolean mDataRatchetEnabled = true;

    /** Constructor */
    public RatRatcheter(Phone phone) {
        mPhone = phone;
@@ -75,16 +76,33 @@ public class RatRatcheter {
        }
    }

    public void ratchetRat(ServiceState oldSS, ServiceState newSS) {
    public void ratchetRat(ServiceState oldSS, ServiceState newSS, boolean locationChange) {
        // temporarily disable rat ratchet on location change.
        if (locationChange) {
            mVoiceRatchetEnabled = false;
            mDataRatchetEnabled = false;
            return;
        }
        if (mVoiceRatchetEnabled) {
            int newVoiceRat = ratchetRat(oldSS.getRilVoiceRadioTechnology(),
                    newSS.getRilVoiceRadioTechnology());
            newSS.setRilVoiceRadioTechnology(newVoiceRat);
        } else if (oldSS.getRilVoiceRadioTechnology() != newSS.getRilVoiceRadioTechnology()) {
            // resume rat ratchet on following rat change within the same location
            mVoiceRatchetEnabled = true;
        }

        if (mDataRatchetEnabled) {
            int newDataRat = ratchetRat(oldSS.getRilDataRadioTechnology(),
                    newSS.getRilDataRadioTechnology());
            newSS.setRilDataRadioTechnology(newDataRat);
        } else if (oldSS.getRilVoiceRadioTechnology() != newSS.getRilVoiceRadioTechnology()) {
            // resume rat ratchet on following rat change within the same location
            mVoiceRatchetEnabled = true;
        }

        boolean newUsingCA = oldSS.isUsingCarrierAggregation() ||
                newSS.isUsingCarrierAggregation();

        newSS.setRilVoiceRadioTechnology(newVoiceRat);
        newSS.setRilDataRadioTechnology(newDataRat);
        newSS.setIsUsingCarrierAggregation(newUsingCA);
    }

+4 −3
Original line number Diff line number Diff line
@@ -139,7 +139,8 @@ public class ServiceStateTracker extends Handler {
     * and ignore stale responses.  The value is a count-down of
     * expected responses in this pollingContext.
     */
    private int[] mPollingContext;
    @VisibleForTesting
    public int[] mPollingContext;
    private boolean mDesiredPowerState;

    /**
@@ -2631,8 +2632,8 @@ public class ServiceStateTracker extends Handler {
        // ratchet the new tech up through it's rat family but don't drop back down
        // until cell change or device is OOS
        boolean isDataInService = mNewSS.getDataRegState() == ServiceState.STATE_IN_SERVICE;
        if (!hasLocationChanged && isDataInService) {
            mRatRatcheter.ratchetRat(mSS, mNewSS);
        if (isDataInService) {
            mRatRatcheter.ratchetRat(mSS, mNewSS, hasLocationChanged);
        }

        boolean hasRilVoiceRadioTechnologyChanged =
+130 −0
Original line number Diff line number Diff line
@@ -158,6 +158,10 @@ public class ServiceStateTrackerTest extends TelephonyTest {
        mBundle.putStringArray(
                CarrierConfigManager.KEY_NON_ROAMING_OPERATOR_STRING_ARRAY, new String[]{"123456"});

        mBundle.putStringArray(CarrierConfigManager.KEY_RATCHET_RAT_FAMILIES,
                // UMTS < GPRS < EDGE
                new String[]{"3,1,2"});

        mSimulatedCommands.setVoiceRegState(NetworkRegistrationState.REG_STATE_HOME);
        mSimulatedCommands.setVoiceRadioTech(ServiceState.RIL_RADIO_TECHNOLOGY_HSPA);
        mSimulatedCommands.setDataRegState(NetworkRegistrationState.REG_STATE_HOME);
@@ -1330,4 +1334,130 @@ public class ServiceStateTrackerTest extends TelephonyTest {
            assertTrue(actualNitzSignal.mElapsedRealtime <= SystemClock.elapsedRealtime());
        }
    }

    // Edge and GPRS are grouped under the same family and Edge has higher rate than GPRS.
    // Expect no rat update when move from E to G.
    @Test
    public void testRatRatchet() throws Exception {
        CellIdentityGsm cellIdentity = new CellIdentityGsm(-1, -1, -1, -1, -1, -1);
        NetworkRegistrationState dataResult = new NetworkRegistrationState(
                0, 0, 1, 2, 0, false, null, cellIdentity, 1);
        sst.mPollingContext[0] = 2;
        // update data reg state to be in service
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
                new AsyncResult(sst.mPollingContext, dataResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());

        NetworkRegistrationState voiceResult = new NetworkRegistrationState(
                0, 0, 1, 2, 0, false, null, cellIdentity, false, 0, 0, 0);
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
                new AsyncResult(sst.mPollingContext, voiceResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilVoiceRadioTechnology());

        // EDGE -> GPRS
        voiceResult = new NetworkRegistrationState(
                0, 0, 1, 1, 0, false, null,
                cellIdentity, false, 0, 0, 0);
        sst.mPollingContext[0] = 2;
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
                new AsyncResult(sst.mPollingContext, dataResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());

        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
                new AsyncResult(sst.mPollingContext, voiceResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilVoiceRadioTechnology());
    }

    // Edge and GPRS are grouped under the same family and Edge has higher rate than GPRS.
    // Bypass rat rachet when cell id changed. Expect rat update from E to G
    @Test
    public void testRatRatchetWithCellChange() throws Exception {
        CellIdentityGsm cellIdentity = new CellIdentityGsm(-1, -1, -1, -1, -1, -1);
        NetworkRegistrationState dataResult = new NetworkRegistrationState(
                0, 0, 1, 2, 0, false, null, cellIdentity, 1);
        sst.mPollingContext[0] = 2;
        // update data reg state to be in service
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
                new AsyncResult(sst.mPollingContext, dataResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());

        NetworkRegistrationState voiceResult = new NetworkRegistrationState(
                0, 0, 1, 2, 0, false, null, cellIdentity, false, 0, 0, 0);
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
                new AsyncResult(sst.mPollingContext, voiceResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilVoiceRadioTechnology());

        // RAT: EDGE -> GPRS cell ID: -1 -> 5
        cellIdentity = new CellIdentityGsm(-1, -1, -1, 5, -1, -1);
        voiceResult = new NetworkRegistrationState(
                0, 0, 1, 1, 0, false, null, cellIdentity, false, 0, 0, 0);
        sst.mPollingContext[0] = 2;
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
                new AsyncResult(sst.mPollingContext, dataResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());

        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
                new AsyncResult(sst.mPollingContext, voiceResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilVoiceRadioTechnology());
    }

    // Edge, GPRS and UMTS are grouped under the same family where Edge > GPRS > UMTS  .
    // Expect no rat update from E to G immediately following cell id change.
    // Expect ratratchet (from G to UMTS) for the following rat update within the cell location.
    @Test
    public void testRatRatchetWithCellChangeBeforeRatChange() throws Exception {
        // cell ID update
        CellIdentityGsm cellIdentity = new CellIdentityGsm(-1, -1, -1, 5, -1, -1);
        NetworkRegistrationState dataResult = new NetworkRegistrationState(
                0, 0, 1, 2, 0, false, null, cellIdentity, 1);
        sst.mPollingContext[0] = 2;
        // update data reg state to be in service
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
                new AsyncResult(sst.mPollingContext, dataResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());

        NetworkRegistrationState voiceResult = new NetworkRegistrationState(
                0, 0, 1, 2, 0, false, null, cellIdentity, false, 0, 0, 0);
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
                new AsyncResult(sst.mPollingContext, voiceResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_EDGE, sst.mSS.getRilVoiceRadioTechnology());

        // RAT: EDGE -> GPRS, cell ID unchanged. Expect no rat ratchet following cell Id change.
        voiceResult = new NetworkRegistrationState(
                0, 0, 1, 1, 0, false, null, cellIdentity, false, 0, 0, 0);
        sst.mPollingContext[0] = 2;
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
                new AsyncResult(sst.mPollingContext, dataResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());

        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
                new AsyncResult(sst.mPollingContext, voiceResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilVoiceRadioTechnology());

        // RAT: GPRS -> UMTS
        voiceResult = new NetworkRegistrationState(
                0, 0, 1, 3, 0, false, null, cellIdentity, false, 0, 0, 0);
        sst.mPollingContext[0] = 2;
        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_GPRS,
                new AsyncResult(sst.mPollingContext, dataResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.STATE_IN_SERVICE, mSST.getCurrentDataConnectionState());

        sst.sendMessage(sst.obtainMessage(ServiceStateTracker.EVENT_POLL_STATE_REGISTRATION,
                new AsyncResult(sst.mPollingContext, voiceResult, null)));
        waitForMs(200);
        assertEquals(ServiceState.RIL_RADIO_TECHNOLOGY_GPRS, sst.mSS.getRilVoiceRadioTechnology());
    }
}