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

Commit 42c8dceb authored by Amit Mahajan's avatar Amit Mahajan Committed by Rambo Wang
Browse files

Add configurable RSRP boost for 5G NR SA.

Test: atest CellSignalStrengthNrTest
Bug: 187679048
Merged-In: Ie894b063db5881736bd55d4703fde742d2325c77
Change-Id: Ie894b063db5881736bd55d4703fde742d2325c77
(cherry picked from commit 61fd42fa)
parent 9a11271e
Loading
Loading
Loading
Loading
+72 −42
Original line number Diff line number Diff line
@@ -642,11 +642,17 @@ public class ServiceStateTracker extends Handler {
     * Reference: 3GPP TS 36.104 5.4.3)
     * inclusive ranges for which the lte rsrp boost is applied */
    private ArrayList<Pair<Integer, Integer>> mEarfcnPairListForRsrpBoost = null;

    private int mLteRsrpBoost = 0; // offset which is reduced from the rsrp threshold
                                   // while calculating signal strength level.
    private final Object mLteRsrpBoostLock = new Object();
    private static final int INVALID_LTE_EARFCN = -1;

    /* Ranges of NR ARFCNs (5G Absolute Radio Frequency Channel Number,
     * Reference: 3GPP TS 38.104)
     * inclusive ranges for which the corresponding nr rsrp boost is applied */
    private ArrayList<Pair<Integer, Integer>> mNrarfcnRangeListForRsrpBoost = null;
    private int[] mNrRsrpBoost;

    private final Object mRsrpBoostLock = new Object();
    private static final int INVALID_ARFCN = -1;

    private final List<SignalRequestRecord> mSignalRequestRecords = new ArrayList<>();

@@ -1199,23 +1205,6 @@ public class ServiceStateTracker extends Handler {
        }
    }

    private int getLteEarfcn(CellIdentity cellIdentity) {
        int lteEarfcn = INVALID_LTE_EARFCN;
        if (cellIdentity != null) {
            switch (cellIdentity.getType()) {
                case CellInfoType.LTE: {
                    lteEarfcn = ((CellIdentityLte) cellIdentity).getEarfcn();
                    break;
                }
                default: {
                    break;
                }
            }
        }

        return lteEarfcn;
    }

    @Override
    public void handleMessage(Message msg) {
        AsyncResult ar;
@@ -2440,8 +2429,7 @@ public class ServiceStateTracker extends Handler {
                    mNewSS.setDataRoamingFromRegistration(isDataRoaming);
                }

                updateServiceStateLteEarfcnBoost(mNewSS,
                        getLteEarfcn(networkRegState.getCellIdentity()));
                updateServiceStateArfcnRsrpBoost(mNewSS, networkRegState.getCellIdentity());
                break;
            }

@@ -5072,19 +5060,21 @@ public class ServiceStateTracker extends Handler {
    /**
     * Checks if the provided earfcn falls withing the range of earfcns.
     *
     * return true if earfcn falls within the provided range; false otherwise.
     * return int index in earfcnPairList if earfcn falls within the provided range; -1 otherwise.
     */
    private boolean containsEarfcnInEarfcnRange(ArrayList<Pair<Integer, Integer>> earfcnPairList,
    private int containsEarfcnInEarfcnRange(ArrayList<Pair<Integer, Integer>> earfcnPairList,
            int earfcn) {
        int index = 0;
        if (earfcnPairList != null) {
            for (Pair<Integer, Integer> earfcnPair : earfcnPairList) {
                if ((earfcn >= earfcnPair.first) && (earfcn <= earfcnPair.second)) {
                    return true;
                    return index;
                }
                index++;
            }
        }

        return false;
        return -1;
    }

    /**
@@ -5145,7 +5135,7 @@ public class ServiceStateTracker extends Handler {
        mEriManager.loadEriFile();
        mCdnr.updateEfForEri(getOperatorNameFromEri());

        updateLteEarfcnLists(config);
        updateArfcnLists(config);
        updateReportingCriteria(config);
        updateOperatorNamePattern(config);
        mCdnr.updateEfFromCarrierConfig(config);
@@ -5156,13 +5146,29 @@ public class ServiceStateTracker extends Handler {
        pollStateInternal(false);
    }

    private void updateLteEarfcnLists(PersistableBundle config) {
        synchronized (mLteRsrpBoostLock) {
    private void updateArfcnLists(PersistableBundle config) {
        synchronized (mRsrpBoostLock) {
            mLteRsrpBoost = config.getInt(CarrierConfigManager.KEY_LTE_EARFCNS_RSRP_BOOST_INT, 0);
            String[] earfcnsStringArrayForRsrpBoost = config.getStringArray(
                    CarrierConfigManager.KEY_BOOSTED_LTE_EARFCNS_STRING_ARRAY);
            mEarfcnPairListForRsrpBoost = convertEarfcnStringArrayToPairList(
                    earfcnsStringArrayForRsrpBoost);

            mNrRsrpBoost = config.getIntArray(
                    CarrierConfigManager.KEY_NRARFCNS_RSRP_BOOST_INT_ARRAY);
            String[] nrarfcnsStringArrayForRsrpBoost = config.getStringArray(
                    CarrierConfigManager.KEY_BOOSTED_NRARFCNS_STRING_ARRAY);
            mNrarfcnRangeListForRsrpBoost = convertEarfcnStringArrayToPairList(
                    nrarfcnsStringArrayForRsrpBoost);

            if ((mNrRsrpBoost == null && mNrarfcnRangeListForRsrpBoost != null)
                    || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost == null)
                    || (mNrRsrpBoost != null && mNrarfcnRangeListForRsrpBoost != null
                    && mNrRsrpBoost.length != mNrarfcnRangeListForRsrpBoost.size())) {
                loge("Invalid parameters for NR RSRP boost");
                mNrRsrpBoost = null;
                mNrarfcnRangeListForRsrpBoost = null;
            }
        }
    }

@@ -5212,15 +5218,36 @@ public class ServiceStateTracker extends Handler {
        }
    }

    private void updateServiceStateLteEarfcnBoost(ServiceState serviceState, int lteEarfcn) {
        synchronized (mLteRsrpBoostLock) {
            if ((lteEarfcn != INVALID_LTE_EARFCN)
                    && containsEarfcnInEarfcnRange(mEarfcnPairListForRsrpBoost, lteEarfcn)) {
                serviceState.setLteEarfcnRsrpBoost(mLteRsrpBoost);
            } else {
                serviceState.setLteEarfcnRsrpBoost(0);
    private void updateServiceStateArfcnRsrpBoost(ServiceState serviceState,
            CellIdentity cellIdentity) {
        int rsrpBoost = 0;
        int arfcn;

        synchronized (mRsrpBoostLock) {
            switch (cellIdentity.getType()) {
                case CellInfo.TYPE_LTE:
                    arfcn = ((CellIdentityLte) cellIdentity).getEarfcn();
                    if (arfcn != INVALID_ARFCN
                            && containsEarfcnInEarfcnRange(mEarfcnPairListForRsrpBoost,
                            arfcn) != -1) {
                        rsrpBoost = mLteRsrpBoost;
                    }
                    break;
                case CellInfo.TYPE_NR:
                    arfcn = ((CellIdentityNr) cellIdentity).getNrarfcn();
                    if (arfcn != INVALID_ARFCN) {
                        int index = containsEarfcnInEarfcnRange(mNrarfcnRangeListForRsrpBoost,
                                arfcn);
                        if (index != -1) {
                            rsrpBoost = mNrRsrpBoost[index];
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        serviceState.setArfcnRsrpBoost(rsrpBoost);
    }

    /**
@@ -5469,11 +5496,12 @@ public class ServiceStateTracker extends Handler {
        }
    }

    private void dumpEarfcnPairList(PrintWriter pw) {
        pw.print(" mEarfcnPairListForRsrpBoost={");
        if (mEarfcnPairListForRsrpBoost != null) {
            int i = mEarfcnPairListForRsrpBoost.size();
            for (Pair<Integer, Integer> earfcnPair : mEarfcnPairListForRsrpBoost) {
    private void dumpEarfcnPairList(PrintWriter pw, ArrayList<Pair<Integer, Integer>> pairList,
            String name) {
        pw.print(" " + name + "={");
        if (pairList != null) {
            int i = pairList.size();
            for (Pair<Integer, Integer> earfcnPair : pairList) {
                pw.print("(");
                pw.print(earfcnPair.first);
                pw.print(",");
@@ -5570,9 +5598,11 @@ public class ServiceStateTracker extends Handler {
        pw.println(" mDeviceShuttingDown=" + mDeviceShuttingDown);
        pw.println(" mSpnUpdatePending=" + mSpnUpdatePending);
        pw.println(" mLteRsrpBoost=" + mLteRsrpBoost);
        pw.println(" mNrRsrpBoost=" + Arrays.toString(mNrRsrpBoost));
        pw.println(" mCellInfoMinIntervalMs=" + mCellInfoMinIntervalMs);
        pw.println(" mEriManager=" + mEriManager);
        dumpEarfcnPairList(pw);
        dumpEarfcnPairList(pw, mEarfcnPairListForRsrpBoost, "mEarfcnPairListForRsrpBoost");
        dumpEarfcnPairList(pw, mNrarfcnRangeListForRsrpBoost, "mNrarfcnRangeListForRsrpBoost");

        mLocaleTracker.dump(fd, pw, args);
        IndentingPrintWriter ipw = new IndentingPrintWriter(pw, "    ");
+36 −2
Original line number Diff line number Diff line
@@ -18,17 +18,23 @@ package com.android.internal.telephony;

import static com.google.common.truth.Truth.assertThat;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.doReturn;

import android.hardware.radio.V1_6.NrSignalStrength;
import android.os.Parcel;
import android.telephony.CellInfo;
import android.telephony.CellSignalStrength;
import android.telephony.CellSignalStrengthNr;
import android.test.AndroidTestCase;
import android.telephony.ServiceState;

import com.google.common.collect.BoundType;
import com.google.common.collect.Range;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;

import java.util.ArrayList;
import java.util.Arrays;
@@ -36,7 +42,7 @@ import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class CellSignalStrengthNrTest extends AndroidTestCase {
public class CellSignalStrengthNrTest extends TelephonyTest {
    private static final int CSIRSRP = -123;
    private static final int CSIRSRQ = -11;
    private static final int ANOTHER_CSIRSRP = -111;
@@ -51,6 +57,19 @@ public class CellSignalStrengthNrTest extends AndroidTestCase {
    private static final int SSRSRQ = -13;
    private static final int SSSINR = 32;

    @Mock
    ServiceState mSS;

    @Before
    public void setUp() throws Exception {
        super.setUp(this.getClass().getSimpleName());
    }

    @After
    public void tearDown() throws Exception {
        super.tearDown();
    }

    private List<Integer> getCsiCqiList() {
        return CSICQI_REPORT.stream()
                .map(cqi -> new Integer(Byte.toUnsignedInt(cqi)))
@@ -220,4 +239,19 @@ public class CellSignalStrengthNrTest extends AndroidTestCase {
        assertThat(anotherCss.getSsRsrq()).isEqualTo(SSRSRQ);
        assertThat(anotherCss.getSsSinr()).isEqualTo(SSSINR);
    }

    @Test
    public void testLevel() {
        CellSignalStrengthNr css = new CellSignalStrengthNr(CSIRSRP, CSIRSRQ, CSISINR, SSRSRP,
                SSRSRQ, SSSINR);

        // No keys in the bundle - should use RSRP and default levels.
        css.updateLevel(null, null);
        assertEquals(0 /* NONE or UNKNOWN */, css.getLevel());

        doReturn(10).when(mSS).getArfcnRsrpBoost();
        // Add rsrp boost and level should change to 1 - POOR
        css.updateLevel(null, mSS);
        assertEquals(1 /* MODERATE */, css.getLevel());
    }
}