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

Commit 460c7215 authored by Kai Shi's avatar Kai Shi Committed by Android (Google) Code Review
Browse files

Merge "Bug fixes of LinkBandwidthEstimator" into sc-dev

parents 6056517d c8ef618d
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -2707,10 +2707,10 @@ message BandwidthEstimatorStats {
    optional uint32 count = 2;
    // Average end-to-end bandwidth in kbps
    optional uint32 avg_bw_kbps = 3;
    // Normalized root mean square error (NRMSE) of static BW values in percent
    optional uint32 static_bw_nrmse_percent = 4;
    // Normalized root mean square error (NRMSE) of end-to-end BW estimation in percent
    optional uint32 bw_est_nrmse_percent = 5;
    // Normalized error of static BW values in percent
    optional uint32 static_bw_error_percent = 4;
    // Normalized error of end-to-end BW estimation in percent
    optional uint32 bw_est_error_percent = 5;
  }

  // Bandwidth stats of each RAT
+16 −10
Original line number Diff line number Diff line
@@ -1668,12 +1668,6 @@ public class DataConnection extends StateMachine {
        }
    }

    /** Update Tx and Rx link bandwidth estimation values */
    public void updateLinkBandwidthEstimation(int uplinkBandwidthKbps, int downlinkBandwidthKbps) {
        sendMessage(DataConnection.EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE,
                new Pair<Integer, Integer>(uplinkBandwidthKbps, downlinkBandwidthKbps));
    }

    private boolean isBandwidthSourceKey(String source) {
        return source.equals(mPhone.getContext().getResources().getString(
                com.android.internal.R.string.config_bandwidthEstimateSource));
@@ -2211,6 +2205,10 @@ public class DataConnection extends StateMachine {
                    DataConnection.EVENT_NR_FREQUENCY_CHANGED, null);
            mPhone.getServiceStateTracker().registerForCssIndicatorChanged(getHandler(),
                    DataConnection.EVENT_CSS_INDICATOR_CHANGED, null);
            if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) {
                mPhone.getLinkBandwidthEstimator().registerForBandwidthChanged(getHandler(),
                        DataConnection.EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE, null);
            }

            // Add ourselves to the list of data connections
            mDcController.addDc(DataConnection.this);
@@ -2228,6 +2226,9 @@ public class DataConnection extends StateMachine {
            mPhone.getServiceStateTracker().unregisterForNrStateChanged(getHandler());
            mPhone.getServiceStateTracker().unregisterForNrFrequencyChanged(getHandler());
            mPhone.getServiceStateTracker().unregisterForCssIndicatorChanged(getHandler());
            if (isBandwidthSourceKey(DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) {
                mPhone.getLinkBandwidthEstimator().unregisterForBandwidthChanged(getHandler());
            }

            // Remove ourselves from the DC lists
            mDcController.removeDc(DataConnection.this);
@@ -3235,11 +3236,16 @@ public class DataConnection extends StateMachine {
                    break;
                }
                case EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE: {
                    Pair<Integer, Integer> pair = (Pair<Integer, Integer>) msg.obj;
                    AsyncResult ar = (AsyncResult) msg.obj;
                    if (ar.exception != null) {
                        loge("EVENT_LINK_BANDWIDTH_ESTIMATOR_UPDATE e=" + ar.exception);
                    } else {
                        Pair<Integer, Integer> pair = (Pair<Integer, Integer>) ar.result;
                        if (isBandwidthSourceKey(
                                DctConstants.BANDWIDTH_SOURCE_BANDWIDTH_ESTIMATOR_KEY)) {
                            updateLinkBandwidthsFromBandwidthEstimator(pair.first, pair.second);
                        }
                    }
                    retVal = HANDLED;
                    break;
                }
+110 −48
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@ import android.os.Handler;
import android.os.HandlerExecutor;
import android.os.Message;
import android.os.OutcomeReceiver;
import android.os.Registrant;
import android.os.RegistrantList;
import android.preference.PreferenceManager;
import android.telephony.AccessNetworkConstants;
import android.telephony.CellIdentity;
@@ -53,7 +55,6 @@ import android.view.Display;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.telephony.DctConstants;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.TelephonyFacade;
import com.android.internal.telephony.metrics.TelephonyMetrics;
import com.android.internal.telephony.nano.TelephonyProto.NrMode;
@@ -86,6 +87,8 @@ public class LinkBandwidthEstimator extends Handler {
    static final int MSG_NR_FREQUENCY_CHANGED = 6;
    @VisibleForTesting
    static final int MSG_NR_STATE_CHANGED = 7;
    @VisibleForTesting
    static final int MSG_ACTIVE_PHONE_CHANGED = 8;

    // TODO: move the following parameters to xml file
    private static final int TRAFFIC_STATS_POLL_INTERVAL_MS = 1_000;
@@ -138,6 +141,7 @@ public class LinkBandwidthEstimator extends Handler {
            "LTE:30000,15000", "NR_NSA:47000,18000",
            "NR_NSA_MMWAVE:145000,60000", "NR:145000,60000", "NR_MMWAVE:145000,60000"};
    private static final Map<String, Pair<Integer, Integer>> AVG_BW_PER_RAT_MAP = new ArrayMap<>();
    private static final String UNKNOWN_PLMN = "";

    // To be used in the long term avg, each count needs to be above the following value
    public static final int BW_STATS_COUNT_THRESHOLD = 5;
@@ -146,6 +150,7 @@ public class LinkBandwidthEstimator extends Handler {
    public static final int LINK_RX = 1;
    public static final int NUM_LINK_DIRECTION = 2;

    // One common timestamp for all sim to avoid frequent modem polling
    private final Phone mPhone;
    private final TelephonyFacade mTelephonyFacade;
    private final TelephonyManager mTelephonyManager;
@@ -153,6 +158,7 @@ public class LinkBandwidthEstimator extends Handler {
    private final LocalLog mLocalLog = new LocalLog(512);
    private boolean mScreenOn = false;
    private boolean mIsOnDefaultRoute = false;
    private boolean mIsOnActiveData = false;
    private long mLastModemPollTimeMs;
    private boolean mLastTrafficValid = true;
    private long mLastMobileTxBytes;
@@ -166,19 +172,20 @@ public class LinkBandwidthEstimator extends Handler {
    private int mSignalLevel;
    private int mDataRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
    private int mTac;
    private String mPlmn = "";
    private String mPlmn = UNKNOWN_PLMN;
    private NetworkCapabilities mNetworkCapabilities;
    private NetworkBandwidth mPlaceholderNetwork;

    private long mFilterUpdateTimeMs;

    private int mBandwidthUpdateSignalDbm = -1;
    private int mBandwidthUpdateSignalLevel = -1;
    private int mBandwidthUpdateDataRat = TelephonyManager.NETWORK_TYPE_UNKNOWN;
    private String mBandwidthUpdatePlmn = "";
    private String mBandwidthUpdatePlmn = UNKNOWN_PLMN;
    private BandwidthState mTxState = new BandwidthState(LINK_TX);
    private BandwidthState mRxState = new BandwidthState(LINK_RX);

    private RegistrantList mBandwidthChangedRegistrants = new RegistrantList();

    private static void initAvgBwPerRatTable() {
        for (String config : AVG_BW_PER_RAT) {
            int rxKbps = 14;
@@ -256,9 +263,9 @@ public class LinkBandwidthEstimator extends Handler {
        mConnectivityManager.registerDefaultNetworkCallback(mDefaultNetworkCallback, this);
        mTelephonyManager.registerTelephonyCallback(new HandlerExecutor(this),
                mTelephonyCallback);
        mPlaceholderNetwork = new NetworkBandwidth("");
        mPlaceholderNetwork = new NetworkBandwidth(UNKNOWN_PLMN);
        initAvgBwPerRatTable();
        registerDataServiceState();
        registerNrStateFrequencyChange();
    }

    @Override
@@ -285,12 +292,35 @@ public class LinkBandwidthEstimator extends Handler {
            case MSG_NR_STATE_CHANGED:
                updateStaticBwValueResetFilter();
                break;
            case MSG_ACTIVE_PHONE_CHANGED:
                handleActivePhoneChanged((int) msg.obj);
                break;
            default:
                Rlog.e(TAG, "invalid message " + msg.what);
                break;
        }
    }

    /**
     * Registers for bandwidth estimation change. The bandwidth will be returned
     *      * {@link AsyncResult#result} as a {@link Pair} Object.
     *      * The {@link AsyncResult} will be in the notification {@link Message#obj}.
     * @param h handler to notify
     * @param what what code of message when delivered
     * @param obj placed in Message.obj
     */
    public void registerForBandwidthChanged(Handler h, int what, Object obj) {
        Registrant r = new Registrant(h, what, obj);
        mBandwidthChangedRegistrants.add(r);
    }

    /**
     * Unregisters for bandwidth estimation change.
     * @param h handler to notify
     */
    public void unregisterForBandwidthChanged(Handler h) {
        mBandwidthChangedRegistrants.remove(h);
    }
    /**
     * @return True if one the device's screen (e.g. main screen, wifi display, HDMI display etc...)
     * is on.
@@ -340,15 +370,26 @@ public class LinkBandwidthEstimator extends Handler {
        handleTrafficStatsPollConditionChanged();
    }

    private void handleActivePhoneChanged(int activeDataSubId) {
        boolean isOnActiveData = activeDataSubId == mPhone.getSubId();
        if (mIsOnActiveData == isOnActiveData) {
            return;
        }
        mIsOnActiveData = isOnActiveData;
        logd("mIsOnActiveData " + mIsOnActiveData + " activeDataSubId " + activeDataSubId);
        handleTrafficStatsPollConditionChanged();
    }

    private void handleTrafficStatsPollConditionChanged() {
        removeMessages(MSG_TRAFFIC_STATS_POLL);
        if (mScreenOn && mIsOnDefaultRoute) {
            updateDataRatCellIdentity();
        if (mScreenOn && mIsOnDefaultRoute && mIsOnActiveData) {
            updateDataRatCellIdentityBandwidth();
            handleTrafficStatsPoll();
        }
    }

    private void handleTrafficStatsPoll() {
        invalidateTxRxSamples();
        long mobileTxBytes = mTelephonyFacade.getMobileTxBytes();
        long mobileRxBytes = mTelephonyFacade.getMobileRxBytes();
        long txBytesDelta = mobileTxBytes - mLastMobileTxBytes;
@@ -396,7 +437,7 @@ public class LinkBandwidthEstimator extends Handler {
                    .append(" txByteDeltaAcc ").append(mTxBytesDeltaAcc)
                    .append(" rxByteDeltaAcc ").append(mRxBytesDeltaAcc)
                    .append(" trigger modem activity request").toString());
            updateDataRatCellIdentity();
            updateDataRatCellIdentityBandwidth();
            // Filter update will happen after the request
            makeRequestModemActivity();
            return;
@@ -405,10 +446,12 @@ public class LinkBandwidthEstimator extends Handler {
        long timeSinceLastFilterUpdateMs = currTimeMs - mFilterUpdateTimeMs;
        // Update filter
        if (timeSinceLastFilterUpdateMs >= FILTER_UPDATE_MAX_INTERVAL_MS) {
            updateDataRatCellIdentity();
            boolean updatedBandwidth = updateDataRatCellIdentityBandwidth();
            if (!updatedBandwidth) {
                updateTxRxBandwidthFilterSendToDataConnection();
            }
        }
    }

    private void makeRequestModemActivity() {
        mLastModemPollTimeMs = mTelephonyFacade.getElapsedSinceBootMillis();
@@ -422,7 +465,6 @@ public class LinkBandwidthEstimator extends Handler {
        mLastModemActivityInfo = result;
        // Update for next poll
        resetByteDeltaAcc();
        invalidateTxRxSamples();
    }

    private void resetByteDeltaAcc() {
@@ -495,11 +537,12 @@ public class LinkBandwidthEstimator extends Handler {
        mTxState.updateBandwidthFilter();
        mRxState.updateBandwidthFilter();

        if (mTxState.hasLargeBwChange()
        boolean isNetworkChanged = mTxState.hasLargeBwChange()
                || mRxState.hasLargeBwChange()
                || mBandwidthUpdateDataRat != mDataRat
                || mBandwidthUpdateSignalLevel != mSignalLevel
                || !mBandwidthUpdatePlmn.equals(mPlmn)) {
                || !mBandwidthUpdatePlmn.equals(mPlmn);
        if (isValidNetwork() && isNetworkChanged) {
            mTxState.mLastReportedBwKbps = mTxState.mAvgUsedKbps < 0 ? -1 : mTxState.mFilterKbps;
            mRxState.mLastReportedBwKbps  = mRxState.mAvgUsedKbps < 0 ? -1 : mRxState.mFilterKbps;
            sendLinkBandwidthToDataConnection(
@@ -515,6 +558,10 @@ public class LinkBandwidthEstimator extends Handler {
        mRxState.calculateError();
    }

    private boolean isValidNetwork() {
        return !mPlmn.equals(UNKNOWN_PLMN) && mDataRat != TelephonyManager.NETWORK_TYPE_UNKNOWN;
    }

    private class BandwidthState {
        private final int mLink;
        int mFilterKbps;
@@ -538,7 +585,11 @@ public class LinkBandwidthEstimator extends Handler {
            if (timeDeltaMs < TX_RX_TIME_MIN_MS) {
                return;
            }
            int linkBandwidthKbps = (int) (bytesDelta * 8 * 1000 / timeDeltaMs / 1024);
            long linkBandwidthLongKbps = bytesDelta * 8 / timeDeltaMs * 1000 / 1024;
            if (linkBandwidthLongKbps > Integer.MAX_VALUE || linkBandwidthLongKbps < 0) {
                return;
            }
            int linkBandwidthKbps = (int) linkBandwidthLongKbps;
            mBwSampleValid = true;
            mBwSampleKbps = linkBandwidthKbps;

@@ -578,14 +629,20 @@ public class LinkBandwidthEstimator extends Handler {
            }

            if (filterInKbps == mFilterKbps) {
                logv(mLink + " skip filter because the same input / current = " + filterInKbps);
                return;
            }

            int alpha = timeDeltaSec > LARGE_TIME_DECAY_RATIO * timeConstantSec ? 0
                    : (int) (FILTER_SCALE * Math.exp(-1.0 * timeDeltaSec / timeConstantSec));
            mFilterKbps = alpha == 0 ? filterInKbps : ((mFilterKbps * alpha
                    + filterInKbps * FILTER_SCALE - filterInKbps * alpha) / FILTER_SCALE);
            if (alpha == 0) {
                mFilterKbps = filterInKbps;
                return;
            }
            long filterOutKbps = (long) mFilterKbps * alpha
                    + filterInKbps * FILTER_SCALE - filterInKbps * alpha;
            filterOutKbps = filterOutKbps / FILTER_SCALE;
            mFilterKbps = (int) Math.min(filterOutKbps, Integer.MAX_VALUE);

            StringBuilder sb = new StringBuilder();
            logv(sb.append(mLink)
                    .append(" lastSampleWeight=").append(alpha)
@@ -631,6 +688,7 @@ public class LinkBandwidthEstimator extends Handler {
        }

        private void resetBandwidthFilter() {
            mBwSampleValid = false;
            mFilterKbps = getAvgLinkBandwidthKbps();
        }

@@ -660,8 +718,9 @@ public class LinkBandwidthEstimator extends Handler {

        // Calculate a byte count threshold for the given avg BW and observation window size
        private int calculateByteCountThreshold(int avgBwKbps, int durationMs) {
            int avgBytes = avgBwKbps / 8 * durationMs;
            return avgBytes * LOW_BW_TO_AVG_BW_RATIO_NUM / LOW_BW_TO_AVG_BW_RATIO_DEN;
            long avgBytes = (long) avgBwKbps / 8 * durationMs;
            long result = avgBytes * LOW_BW_TO_AVG_BW_RATIO_NUM / LOW_BW_TO_AVG_BW_RATIO_DEN;
            return (int) Math.min(result, Integer.MAX_VALUE);
        }

        public boolean hasLargeBwChange() {
@@ -671,7 +730,8 @@ public class LinkBandwidthEstimator extends Handler {
        }

        public void calculateError() {
            if (!mBwSampleValid || getCurrentCount() <= BW_STATS_COUNT_THRESHOLD + 1) {
            if (!mBwSampleValid || getCurrentCount() <= BW_STATS_COUNT_THRESHOLD + 1
                    || mAvgUsedKbps <= 0) {
                return;
            }
            int bwEstExtErrPercent = calculateErrorPercent(mLastReportedBwKbps, mBwSampleKbps);
@@ -680,8 +740,7 @@ public class LinkBandwidthEstimator extends Handler {
            int coldStartErrPercent = calculateErrorPercent(mStaticBwKbps, mBwSampleKbps);

            TelephonyMetrics.getInstance().writeBandwidthStats(mLink, mDataRat, getNrMode(mDataRat),
                    mSignalLevel, bwEstIntErrPercent, bwEstExtErrPercent,
                    coldStartErrPercent, mAvgUsedKbps);
                    mSignalLevel, bwEstExtErrPercent, coldStartErrPercent, mAvgUsedKbps);

            StringBuilder sb = new StringBuilder();
            logd(sb.append(mLink)
@@ -698,9 +757,8 @@ public class LinkBandwidthEstimator extends Handler {
        }

        private int calculateErrorPercent(int inKbps, int bwSampleKbps) {
            int errorKbps = inKbps - bwSampleKbps;
            int errorPercent = bwSampleKbps > 0 ? (errorKbps * 100 / bwSampleKbps) : 0;
            return Math.max(-MAX_ERROR_PERCENT, Math.min(errorPercent, MAX_ERROR_PERCENT));
            long errorPercent = 100L * (inKbps - bwSampleKbps) / bwSampleKbps;
            return (int) Math.max(-MAX_ERROR_PERCENT, Math.min(errorPercent, MAX_ERROR_PERCENT));
        }
    }

@@ -718,22 +776,15 @@ public class LinkBandwidthEstimator extends Handler {
    // Reset BW filter to a long term avg value (PLMN/RAT/TAC dependent) or static BW value.
    // It should be called whenever PLMN/RAT or static BW value is changed;
    private void resetBandwidthFilter() {
        StringBuilder sb = new StringBuilder();
        mTxState.resetBandwidthFilter();
        mRxState.resetBandwidthFilter();
    }

    private void sendLinkBandwidthToDataConnection(int linkBandwidthTxKps, int linkBandwidthRxKps) {
        DcTracker dt = mPhone.getDcTracker(AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
        if (dt == null) {
            return;
        }
        DataConnection dc = dt.getDataConnectionByApnType(PhoneConstants.APN_TYPE_DEFAULT);
        if (dc == null) {
            return;
        }
        logv("send to DC tx " + linkBandwidthTxKps + " rx " + linkBandwidthRxKps);
        dc.updateLinkBandwidthEstimation(linkBandwidthTxKps, linkBandwidthRxKps);
        Pair<Integer, Integer> bandwidthInfo =
                new Pair<Integer, Integer>(linkBandwidthTxKps, linkBandwidthRxKps);
        mBandwidthChangedRegistrants.notifyRegistrants(new AsyncResult(null, bandwidthInfo, null));
    }

    private void handleSignalStrengthChanged(SignalStrength signalStrength) {
@@ -741,17 +792,20 @@ public class LinkBandwidthEstimator extends Handler {
            return;
        }

        updateDataRatCellIdentity();

        mSignalStrengthDbm = signalStrength.getDbm();
        mSignalLevel = signalStrength.getLevel();
        if (Math.abs(mBandwidthUpdateSignalDbm - mSignalStrengthDbm) > RSSI_DELTA_THRESHOLD_DB) {
        updateByteCountThr();
        boolean updatedBandwidth = updateDataRatCellIdentityBandwidth();
        if (updatedBandwidth) {
            return;
        }

        if (Math.abs(mBandwidthUpdateSignalDbm - mSignalStrengthDbm) > RSSI_DELTA_THRESHOLD_DB) {
            updateTxRxBandwidthFilterSendToDataConnection();
        }
    }

    private void registerDataServiceState() {
    private void registerNrStateFrequencyChange() {
        mPhone.getServiceStateTracker().registerForNrStateChanged(this,
                MSG_NR_STATE_CHANGED, null);
        mPhone.getServiceStateTracker().registerForNrFrequencyChanged(this,
@@ -843,18 +897,19 @@ public class LinkBandwidthEstimator extends Handler {
                NetworkRegistrationInfo.DOMAIN_PS, AccessNetworkConstants.TRANSPORT_TYPE_WWAN);
    }

    private void updateDataRatCellIdentity() {
    private boolean updateDataRatCellIdentityBandwidth() {
        boolean updatedPlmn = false;
        CellIdentity cellIdentity = mPhone.getCurrentCellIdentity();
        mTac = getTac(cellIdentity);
        String plmn;

        if (mPhone.getServiceState().getOperatorNumeric() != null) {
            plmn = mPhone.getServiceState().getOperatorNumeric();
        } else {
            if (cellIdentity.getPlmn() != null) {
                plmn = cellIdentity.getPlmn();
            } else {
            if (cellIdentity.getOperatorAlphaShort() != null) {
                plmn = cellIdentity.getOperatorAlphaShort().toString();
            } else {
                plmn = "";
                plmn = UNKNOWN_PLMN;
            }
        }
        if (mPlmn == null || !plmn.equals(mPlmn)) {
@@ -874,10 +929,12 @@ public class LinkBandwidthEstimator extends Handler {
            }
        }

        if (updatedPlmn || updatedRat) {
        boolean updatedPlmnOrRat = updatedPlmn || updatedRat;
        if (updatedPlmnOrRat) {
            resetBandwidthFilter();
            updateTxRxBandwidthFilterSendToDataConnection();
        }
        return updatedPlmnOrRat;
    }

    private int getTac(@NonNull CellIdentity cellIdentity) {
@@ -900,11 +957,16 @@ public class LinkBandwidthEstimator extends Handler {
    }

    private class TelephonyCallbackImpl extends TelephonyCallback implements
            TelephonyCallback.SignalStrengthsListener {
            TelephonyCallback.SignalStrengthsListener,
            TelephonyCallback.ActiveDataSubscriptionIdListener {
        @Override
        public void onSignalStrengthsChanged(SignalStrength signalStrength) {
            obtainMessage(MSG_SIGNAL_STRENGTH_CHANGED, signalStrength).sendToTarget();
        }
        @Override
        public void onActiveDataSubscriptionIdChanged(int subId) {
            obtainMessage(MSG_ACTIVE_PHONE_CHANGED, subId).sendToTarget();
        }
    }

    void logv(String msg) {
+12 −17
Original line number Diff line number Diff line
@@ -2934,12 +2934,10 @@ public class TelephonyMetrics {
     * Write bandwidth estimator stats
     */
    public synchronized void writeBandwidthStats(int link, int rat, int nrMode,
            int signalLevel, int bwEstIntErrPercent,
            int bwEstExtErrPercent, int coldStartErrPercent, int avgUsedKbps) {
            int signalLevel, int bwEstExtErrPercent, int coldStartErrPercent, int avgUsedKbps) {
        BwEstimationStats stats = lookupEstimationStats(link, rat, nrMode);
        stats.mBwEstIntNse[signalLevel] += bwEstIntErrPercent * bwEstIntErrPercent;
        stats.mBwEstExtNse[signalLevel] += bwEstExtErrPercent * bwEstExtErrPercent;
        stats.mStaticBwNse[signalLevel] += coldStartErrPercent * coldStartErrPercent;
        stats.mBwEstErrorAcc[signalLevel] += Math.abs(bwEstExtErrPercent);
        stats.mStaticBwErrorAcc[signalLevel] += Math.abs(coldStartErrPercent);
        stats.mAvgBwKbps[signalLevel] = avgUsedKbps;
        stats.mCount[signalLevel]++;
    }
@@ -2976,9 +2974,8 @@ public class TelephonyMetrics {
    private static class BwEstimationStats {
        final int mRadioTechnology;
        final int mNrMode;
        final long[] mBwEstIntNse = new long[NUM_SIGNAL_LEVEL];
        final long[] mBwEstExtNse = new long[NUM_SIGNAL_LEVEL];
        final long[] mStaticBwNse = new long[NUM_SIGNAL_LEVEL];
        final long[] mBwEstErrorAcc = new long[NUM_SIGNAL_LEVEL];
        final long[] mStaticBwErrorAcc = new long[NUM_SIGNAL_LEVEL];
        final int[] mAvgBwKbps = new int[NUM_SIGNAL_LEVEL];
        final int[] mCount = new int[NUM_SIGNAL_LEVEL];

@@ -2993,9 +2990,8 @@ public class TelephonyMetrics {
            return sb.append(LinkBandwidthEstimator.getDataRatName(mRadioTechnology, mNrMode))
                    .append("\n Count\n").append(printValues(mCount))
                    .append("\n AvgKbps\n").append(printValues(mAvgBwKbps))
                    .append("\n Internal NRMSE\n").append(printAvgError(mBwEstIntNse, mCount))
                    .append("\n External NRMSE\n").append(printAvgError(mBwEstExtNse, mCount))
                    .append("\n StaticBw NRMSE\n").append(printAvgError(mStaticBwNse, mCount))
                    .append("\n BwEst Error\n").append(printAvgError(mBwEstErrorAcc, mCount))
                    .append("\n StaticBw Error\n").append(printAvgError(mStaticBwErrorAcc, mCount))
                    .toString();
        }

@@ -3010,8 +3006,7 @@ public class TelephonyMetrics {
        private String printAvgError(long[] stats, int[] count) {
            StringBuilder sb = new StringBuilder();
            for (int k = 0; k < NUM_SIGNAL_LEVEL; k++) {
                int avgStat = (count[k] > 0 && stats[k] >= 0)
                        ? (int) Math.sqrt(stats[k] / count[k]) : 0;
                int avgStat = calculateAvgError(stats[k], count[k]);
                sb.append(" " + avgStat);
            }
            return sb.toString();
@@ -3039,15 +3034,15 @@ public class TelephonyMetrics {
                stats.signalLevel = level;
                stats.count = count;
                stats.avgBwKbps = mAvgBwKbps[level];
                stats.staticBwNrmsePercent = calculateNrmse(mStaticBwNse[level], count);
                stats.bwEstNrmsePercent = calculateNrmse(mBwEstExtNse[level], count);
                stats.staticBwErrorPercent = calculateAvgError(mStaticBwErrorAcc[level], count);
                stats.bwEstErrorPercent = calculateAvgError(mBwEstErrorAcc[level], count);
                return stats;
            }
            return null;
        }

        private int calculateNrmse(long nse, int count) {
            return (count > 0  && nse >= 0) ? (int) Math.sqrt(nse / count) : 0;
        private int calculateAvgError(long errorAccPercent, int count) {
            return (count > 0) ? (int) (errorAccPercent / count) : 0;
        }
    }

+98 −23

File changed.

Preview size limit exceeded, changes collapsed.

Loading