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

Commit aac396d6 authored by Nathan Harold's avatar Nathan Harold
Browse files

Fix NPE in LinkBandwidthEstimator

Rearrange the null check protections and make
a number of small safety and readability improvements
to reduce the changes of another bug like this.

Bug: 270831206
Test: atest LinkBandwidthEstimatorTest #regression-test

Merged-In: Ib4f37db0cd5a5ca83e8fea10a8e76d902d1065d4
Change-Id: Ib4f37db0cd5a5ca83e8fea10a8e76d902d1065d4
parent df088874
Loading
Loading
Loading
Loading
+36 −24
Original line number Original line Diff line number Diff line
@@ -41,12 +41,14 @@ import android.telephony.CellIdentityLte;
import android.telephony.CellIdentityNr;
import android.telephony.CellIdentityNr;
import android.telephony.CellIdentityTdscdma;
import android.telephony.CellIdentityTdscdma;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellIdentityWcdma;
import android.telephony.CellInfo;
import android.telephony.ModemActivityInfo;
import android.telephony.ModemActivityInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.NetworkRegistrationInfo;
import android.telephony.ServiceState;
import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.SignalStrength;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyCallback;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.ArraySet;
import android.util.LocalLog;
import android.util.LocalLog;
@@ -95,6 +97,9 @@ public class LinkBandwidthEstimator extends Handler {
    @VisibleForTesting
    @VisibleForTesting
    static final int MSG_DATA_REG_STATE_OR_RAT_CHANGED = 9;
    static final int MSG_DATA_REG_STATE_OR_RAT_CHANGED = 9;


    @VisibleForTesting
    static final int UNKNOWN_TAC = CellInfo.UNAVAILABLE;

    // TODO: move the following parameters to xml file
    // TODO: move the following parameters to xml file
    private static final int TRAFFIC_STATS_POLL_INTERVAL_MS = 1_000;
    private static final int TRAFFIC_STATS_POLL_INTERVAL_MS = 1_000;
    private static final int MODEM_POLL_MIN_INTERVAL_MS = 5_000;
    private static final int MODEM_POLL_MIN_INTERVAL_MS = 5_000;
@@ -178,7 +183,7 @@ public class LinkBandwidthEstimator extends Handler {
    private int mSignalLevel;
    private int mSignalLevel;
    private int mDataRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
    private int mDataRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
    private int mTac;
    private int mTac;
    private String mPlmn = UNKNOWN_PLMN;
    @NonNull private String mPlmn = UNKNOWN_PLMN;
    private NetworkCapabilities mNetworkCapabilities;
    private NetworkCapabilities mNetworkCapabilities;
    private NetworkBandwidth mPlaceholderNetwork;
    private NetworkBandwidth mPlaceholderNetwork;
    private long mFilterUpdateTimeMs;
    private long mFilterUpdateTimeMs;
@@ -1029,22 +1034,28 @@ public class LinkBandwidthEstimator extends Handler {
    }
    }


    private boolean updateDataRatCellIdentityBandwidth() {
    private boolean updateDataRatCellIdentityBandwidth() {
        boolean updatedPlmn = false;
        final ServiceState ss = mPhone.getServiceState();
        CellIdentity cellIdentity = mPhone.getCurrentCellIdentity();
        final CellIdentity cellIdentity = mPhone.getCurrentCellIdentity();
        mTac = getTac(cellIdentity);

        boolean hasChanged = false;
        String plmn;
        String plmn;


        if (mPhone.getServiceState().getOperatorNumeric() != null) {
        // Why does updating the TAC not result in hasChanged == true?
            plmn = mPhone.getServiceState().getOperatorNumeric();
        // Legacy behavior is currently being preserved for now, but it might very
        } else {
        // well be incorrect. The TAC is part of the network key. This is very fishy.
            if (cellIdentity.getPlmn() != null) {
        mTac = getTac(cellIdentity);

        /* ss should always be non-null */
        if (!TextUtils.isEmpty(ss.getOperatorNumeric())) {
            plmn = ss.getOperatorNumeric();
        } else if (cellIdentity != null && !TextUtils.isEmpty(cellIdentity.getPlmn())) {
            plmn = cellIdentity.getPlmn();
            plmn = cellIdentity.getPlmn();
        } else {
        } else {
            plmn = UNKNOWN_PLMN;
            plmn = UNKNOWN_PLMN;
        }
        }
        }

        if (mPlmn == null || !plmn.equals(mPlmn)) {
        if (!mPlmn.equals(plmn)) {
            updatedPlmn = true;
            hasChanged = true;
            mPlmn = plmn;
            mPlmn = plmn;
        }
        }


@@ -1053,20 +1064,19 @@ public class LinkBandwidthEstimator extends Handler {
        if (nri != null) {
        if (nri != null) {
            int dataRat = nri.getAccessNetworkTechnology();
            int dataRat = nri.getAccessNetworkTechnology();
            if (dataRat != mDataRat) {
            if (dataRat != mDataRat) {
                updatedRat = true;
                hasChanged = true;
                mDataRat = dataRat;
                mDataRat = dataRat;
                updateStaticBwValue(mDataRat);
                updateStaticBwValue(mDataRat);
                updateByteCountThr();
                updateByteCountThr();
            }
            }
        }
        }


        boolean updatedPlmnOrRat = updatedPlmn || updatedRat;
        if (hasChanged) {
        if (updatedPlmnOrRat) {
            resetBandwidthFilter();
            resetBandwidthFilter();
            updateTxRxBandwidthFilterSendToDataConnection();
            updateTxRxBandwidthFilterSendToDataConnection();
            mLastPlmnOrRatChangeTimeMs = mTelephonyFacade.getElapsedSinceBootMillis();
            mLastPlmnOrRatChangeTimeMs = mTelephonyFacade.getElapsedSinceBootMillis();
        }
        }
        return updatedPlmnOrRat;
        return hasChanged;
    }
    }


    private int getTac(@NonNull CellIdentity cellIdentity) {
    private int getTac(@NonNull CellIdentity cellIdentity) {
@@ -1085,7 +1095,7 @@ public class LinkBandwidthEstimator extends Handler {
        if (cellIdentity instanceof CellIdentityGsm) {
        if (cellIdentity instanceof CellIdentityGsm) {
            return ((CellIdentityGsm) cellIdentity).getLac();
            return ((CellIdentityGsm) cellIdentity).getLac();
        }
        }
        return 0;
        return UNKNOWN_TAC;
    }
    }


    private class TelephonyCallbackImpl extends TelephonyCallback implements
    private class TelephonyCallbackImpl extends TelephonyCallback implements
@@ -1110,16 +1120,17 @@ public class LinkBandwidthEstimator extends Handler {
        mLocalLog.log(msg);
        mLocalLog.log(msg);
    }
    }


    @VisibleForTesting
    static final int UNKNOWN_TAC = -1;
    // Map with NetworkKey as the key and NetworkBandwidth as the value.
    // Map with NetworkKey as the key and NetworkBandwidth as the value.
    // NetworkKey is specified by the PLMN, data RAT and TAC of network.
    // NetworkKey is specified by the PLMN, data RAT and TAC of network.
    // NetworkBandwidth represents the bandwidth related stats of each network.
    // NetworkBandwidth represents the bandwidth related stats of each network.
    private final Map<NetworkKey, NetworkBandwidth> mNetworkMap = new ArrayMap<>();
    private final Map<NetworkKey, NetworkBandwidth> mNetworkMap = new ArrayMap<>();

    private static class NetworkKey {
    private static class NetworkKey {

        private final String mPlmn;
        private final String mPlmn;
        private final String mDataRat;
        private final String mDataRat;
        private final int mTac;
        private final int mTac;

        NetworkKey(String plmn, int tac, String dataRat) {
        NetworkKey(String plmn, int tac, String dataRat) {
            mPlmn = plmn;
            mPlmn = plmn;
            mTac = tac;
            mTac = tac;
@@ -1156,15 +1167,15 @@ public class LinkBandwidthEstimator extends Handler {
    }
    }


    @NonNull
    @NonNull
    private NetworkBandwidth lookupNetwork(String plmn, String dataRat) {
    private NetworkBandwidth lookupNetwork(@NonNull String plmn, String dataRat) {
        return lookupNetwork(plmn, UNKNOWN_TAC, dataRat);
        return lookupNetwork(plmn, UNKNOWN_TAC, dataRat);
    }
    }


    /** Look up NetworkBandwidth and create a new one if it doesn't exist */
    /** Look up NetworkBandwidth and create a new one if it doesn't exist */
    @VisibleForTesting
    @VisibleForTesting
    @NonNull
    @NonNull
    public NetworkBandwidth lookupNetwork(String plmn, int tac, String dataRat) {
    public NetworkBandwidth lookupNetwork(@NonNull String plmn, int tac, String dataRat) {
        if (plmn == null || dataRat.equals(
        if (dataRat.equals(
                TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_UNKNOWN))) {
                TelephonyManager.getNetworkTypeName(TelephonyManager.NETWORK_TYPE_UNKNOWN))) {
            return mPlaceholderNetwork;
            return mPlaceholderNetwork;
        }
        }
@@ -1180,7 +1191,9 @@ public class LinkBandwidthEstimator extends Handler {
    /** A class holding link bandwidth related stats */
    /** A class holding link bandwidth related stats */
    @VisibleForTesting
    @VisibleForTesting
    public class NetworkBandwidth {
    public class NetworkBandwidth {

        private final String mKey;
        private final String mKey;

        NetworkBandwidth(String key) {
        NetworkBandwidth(String key) {
            mKey = key;
            mKey = key;
        }
        }
@@ -1276,5 +1289,4 @@ public class LinkBandwidthEstimator extends Handler {
        pw.println();
        pw.println();
        pw.flush();
        pw.flush();
    }
    }

}
}