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

Commit 8f2ef44c authored by Eric Schwarzenbach's avatar Eric Schwarzenbach
Browse files

Add reporting criteria to DeviceStateMonitor and ServiceStateTracker.

Sends down per-RAN reporting criteria to the modem onRilConnected.

Updates the IndicationFilter to include the new LINK_CAPACITY_ESTIMATE
and PHYSICAL_CHANNEL_CONFIG bits.

Adds default AccessNetworkThresholds for reporting criteria threshold.

Updates LTE and WCDMA SignalStrength reporting criteria when carrier
config changes.

Bug: 70638175
Bug: 72117365
Bug: 74008993
Test: make, runtest
Change-Id: I12f724405bf31d2c48e6a52b5751ddd86f633596
parent eebc0c0b
Loading
Loading
Loading
Loading
+32 −0
Original line number Diff line number Diff line
@@ -2125,6 +2125,38 @@ public interface CommandsInterface {
     */
    void setUnsolResponseFilter(int filter, Message result);

    /**
     * Send the signal strength reporting criteria to the modem.
     *
     * @param hysteresisMs A hysteresis time in milliseconds. A value of 0 disables hysteresis.
     * @param hysteresisDb An interval in dB defining the required magnitude change between reports.
     *     A value of 0 disables hysteresis.
     * @param thresholdsDbm An array of trigger thresholds in dBm. A size of 0 disables thresholds.
     * @param ran RadioAccessNetwork for which to apply criteria.
     * @param result callback message contains the information of SUCCESS/FAILURE
     */
    void setSignalStrengthReportingCriteria(int hysteresisMs, int hysteresisDb, int[] thresholdsDbm,
            int ran, Message result);

    /**
     * Send the link capacity reporting criteria to the modem
     *
     * @param hysteresisMs A hysteresis time in milliseconds. A value of 0 disables hysteresis.
     * @param hysteresisDlKbps An interval in kbps defining the required magnitude change between DL
     *     reports. A value of 0 disables hysteresis.
     * @param hysteresisUlKbps An interval in kbps defining the required magnitude change between UL
     *     reports. A value of 0 disables hysteresis.
     * @param thresholdsDlKbps An array of trigger thresholds in kbps for downlink reports. A size
     *     of 0 disables thresholds.
     * @param thresholdsUlKbps An array of trigger thresholds in kbps for uplink reports. A size
     *     of 0 disables thresholds.
     * @param ran RadioAccessNetwork for which to apply criteria.
     * @param result callback message contains the information of SUCCESS/FAILURE
     */
    void setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps,
            int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran,
            Message result);

    /**
     * Set SIM card power up or down
     *
+163 −1
Original line number Diff line number Diff line
@@ -25,12 +25,14 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.display.DisplayManager;
import android.hardware.radio.V1_0.IndicationFilter;
import android.hardware.radio.V1_2.IndicationFilter;
import android.net.ConnectivityManager;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.Message;
import android.os.PowerManager;
import android.telephony.AccessNetworkConstants.AccessNetworkType;
import android.telephony.CarrierConfigManager;
import android.telephony.Rlog;
import android.telephony.TelephonyManager;
import android.util.LocalLog;
@@ -63,6 +65,9 @@ public class DeviceStateMonitor extends Handler {
    private static final int EVENT_CHARGING_STATE_CHANGED       = 4;
    private static final int EVENT_TETHERING_STATE_CHANGED      = 5;

    // TODO(b/74006656) load hysteresis values from a property when DeviceStateMonitor starts
    private static final int HYSTERESIS_KBPS = 50;

    private final Phone mPhone;

    private final LocalLog mLocalLog = new LocalLog(100);
@@ -278,6 +283,44 @@ public class DeviceStateMonitor extends Handler {
        return true;
    }

    /**
     * @return True if link capacity estimate update should be turned off.
     */
    private boolean shouldTurnOffLinkCapacityEstimate() {
        // We should not turn off link capacity update if one of the following condition is true.
        // 1. The device is charging.
        // 2. When the screen is on.
        // 3. When data tethering is on.
        // 4. When the update mode is IGNORE_SCREEN_OFF.
        if (mIsCharging || mIsScreenOn || mIsTetheringOn
                || mUpdateModes.get(TelephonyManager.INDICATION_FILTER_LINK_CAPACITY_ESTIMATE)
                == TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF) {
            return false;
        }

        // In all other cases, we turn off link capacity update.
        return true;
    }

    /**
     * @return True if physical channel config update should be turned off.
     */
    private boolean shouldTurnOffPhysicalChannelConfig() {
        // We should not turn off physical channel update if one of the following condition is true.
        // 1. The device is charging.
        // 2. When the screen is on.
        // 3. When data tethering is on.
        // 4. When the update mode is IGNORE_SCREEN_OFF.
        if (mIsCharging || mIsScreenOn || mIsTetheringOn
                || mUpdateModes.get(TelephonyManager.INDICATION_FILTER_PHYSICAL_CHANNEL_CONFIG)
                == TelephonyManager.INDICATION_UPDATE_MODE_IGNORE_SCREEN_OFF) {
            return false;
        }

        // In all other cases, we turn off physical channel config update.
        return true;
    }

    /**
     * Set indication update mode
     *
@@ -298,6 +341,12 @@ public class DeviceStateMonitor extends Handler {
        if ((filters & TelephonyManager.INDICATION_FILTER_DATA_CALL_DORMANCY_CHANGED) != 0) {
            mUpdateModes.put(TelephonyManager.INDICATION_FILTER_DATA_CALL_DORMANCY_CHANGED, mode);
        }
        if ((filters & TelephonyManager.INDICATION_FILTER_LINK_CAPACITY_ESTIMATE) != 0) {
            mUpdateModes.put(TelephonyManager.INDICATION_FILTER_LINK_CAPACITY_ESTIMATE, mode);
        }
        if ((filters & TelephonyManager.INDICATION_FILTER_PHYSICAL_CHANNEL_CONFIG) != 0) {
            mUpdateModes.put(TelephonyManager.INDICATION_FILTER_PHYSICAL_CHANNEL_CONFIG, mode);
        }
    }

    /**
@@ -374,6 +423,14 @@ public class DeviceStateMonitor extends Handler {
            newFilter |= IndicationFilter.DATA_CALL_DORMANCY_CHANGED;
        }

        if (!shouldTurnOffLinkCapacityEstimate()) {
            newFilter |= IndicationFilter.LINK_CAPACITY_ESTIMATE;
        }

        if (!shouldTurnOffPhysicalChannelConfig()) {
            newFilter |= IndicationFilter.PHYSICAL_CHANNEL_CONFIG;
        }

        setUnsolResponseFilter(newFilter, false);
    }

@@ -390,6 +447,8 @@ public class DeviceStateMonitor extends Handler {
        sendDeviceState(LOW_DATA_EXPECTED, mIsLowDataExpected);
        sendDeviceState(POWER_SAVE_MODE, mIsPowerSaveOn);
        setUnsolResponseFilter(mUnsolicitedResponseFilter, true);
        setSignalStrengthReportingCriteria();
        setLinkCapacityReportingCriteria();
    }

    /**
@@ -432,6 +491,28 @@ public class DeviceStateMonitor extends Handler {
        }
    }

    private void setSignalStrengthReportingCriteria() {
        mPhone.setSignalStrengthReportingCriteria(
                AccessNetworkThresholds.GERAN, AccessNetworkType.GERAN);
        mPhone.setSignalStrengthReportingCriteria(
                AccessNetworkThresholds.UTRAN, AccessNetworkType.UTRAN);
        mPhone.setSignalStrengthReportingCriteria(
                AccessNetworkThresholds.EUTRAN, AccessNetworkType.EUTRAN);
        mPhone.setSignalStrengthReportingCriteria(
                AccessNetworkThresholds.CDMA2000, AccessNetworkType.CDMA2000);
    }

    private void setLinkCapacityReportingCriteria() {
        mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
                LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.GERAN);
        mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
                LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.UTRAN);
        mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
                LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.EUTRAN);
        mPhone.setLinkCapacityReportingCriteria(LINK_CAPACITY_DOWNLINK_THRESHOLDS,
                LINK_CAPACITY_UPLINK_THRESHOLDS, AccessNetworkType.CDMA2000);
    }

    /**
     * @return True if the device is currently in power save mode.
     * See {@link android.os.BatteryManager#isPowerSaveMode BatteryManager.isPowerSaveMode()}.
@@ -517,4 +598,85 @@ public class DeviceStateMonitor extends Handler {
        ipw.decreaseIndent();
        ipw.flush();
    }

    /**
     * dBm thresholds that correspond to changes in signal strength indications.
     */
    private static final class AccessNetworkThresholds {

        /**
         * List of dBm thresholds for GERAN {@link AccessNetworkType}.
         *
         * Calculated from GSM asu level thresholds - TS 27.007 Sec 8.5
         */
        public static final int[] GERAN = new int[] {
            -109,
            -103,
            -97,
            -89,
        };

        /**
         * List of default dBm thresholds for UTRAN {@link AccessNetworkType}.
         *
         * These thresholds are taken from the WCDMA RSCP defaults in {@link CarrierConfigManager}.
         * See TS 27.007 Sec 8.69.
         */
        public static final int[] UTRAN = new int[] {
            -114, /* SIGNAL_STRENGTH_POOR */
            -104, /* SIGNAL_STRENGTH_MODERATE */
            -94,  /* SIGNAL_STRENGTH_GOOD */
            -84   /* SIGNAL_STRENGTH_GREAT */
        };

        /**
         * List of default dBm thresholds for EUTRAN {@link AccessNetworkType}.
         *
         * These thresholds are taken from the LTE RSRP defaults in {@link CarrierConfigManager}.
         */
        public static final int[] EUTRAN = new int[] {
            -140, /* SIGNAL_STRENGTH_NONE_OR_UNKNOWN */
            -128, /* SIGNAL_STRENGTH_POOR */
            -118, /* SIGNAL_STRENGTH_MODERATE */
            -108, /* SIGNAL_STRENGTH_GOOD */
            -98,  /* SIGNAL_STRENGTH_GREAT */
            -44   /* SIGNAL_STRENGTH_NONE_OR_UNKNOWN */
        };

        /**
         * List of dBm thresholds for CDMA2000 {@link AccessNetworkType}.
         *
         * These correspond to EVDO level thresholds.
         */
        public static final int[] CDMA2000 = new int[] {
            -105,
            -90,
            -75,
            -65
        };
    }

    /**
     * Downlink reporting thresholds in kbps
     *
     * <p>Threshold values taken from FCC Speed Guide
     * (https://www.fcc.gov/reports-research/guides/broadband-speed-guide) and Android WiFi speed
     * labels (https://support.google.com/pixelphone/answer/2819519#strength_speed).
     */
    private static final int[] LINK_CAPACITY_DOWNLINK_THRESHOLDS = new int[] {
            500,   // Web browsing
            1000,  // SD video streaming
            5000,  // HD video streaming
            10000, // file downloading
            20000, // 4K video streaming
    };

    /** Uplink reporting thresholds in kbps */
    private static final int[] LINK_CAPACITY_UPLINK_THRESHOLDS = new int[] {
            100,   // VoIP calls
            500,
            1000,
            5000,
            10000,
    };
}
+19 −0
Original line number Diff line number Diff line
@@ -108,6 +108,13 @@ public class GsmCdmaPhone extends Phone {
    private static final boolean DBG = true;
    private static final boolean VDBG = false; /* STOPSHIP if true */

    /** Required magnitude change between unsolicited SignalStrength reports. */
    private static final int REPORTING_HYSTERESIS_DB = 2;
    /** Required throughput change between unsolicited LinkCapacityEstimate reports. */
    private static final int REPORTING_HYSTERESIS_KBPS = 50;
    /** Minimum time between unsolicited SignalStrength and LinkCapacityEstimate reports. */
    private static final int REPORTING_HYSTERESIS_MILLIS = 3000;

    //GSM
    // Key used to read/write voice mail number
    private static final String VM_NUMBER = "vm_number_key";
@@ -3347,6 +3354,18 @@ public class GsmCdmaPhone extends Phone {
        }
    }

    @Override
    public void setSignalStrengthReportingCriteria(int[] thresholds, int ran) {
        mCi.setSignalStrengthReportingCriteria(REPORTING_HYSTERESIS_MILLIS, REPORTING_HYSTERESIS_DB,
                thresholds, ran, null);
    }

    @Override
    public void setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran) {
        mCi.setLinkCapacityReportingCriteria(REPORTING_HYSTERESIS_MILLIS, REPORTING_HYSTERESIS_KBPS,
                REPORTING_HYSTERESIS_KBPS, dlThresholds, ulThresholds, ran, null);
    }

    @Override
    public IccSmsInterfaceManager getIccSmsInterfaceManager(){
        return mIccSmsInterfaceManager;
+10 −0
Original line number Diff line number Diff line
@@ -3422,6 +3422,16 @@ public abstract class Phone extends Handler implements PhoneInternalInterface {
        mCi.setAllowedCarriers(carriers, response);
    }

    /** Sets the SignalStrength reporting criteria. */
    public void setSignalStrengthReportingCriteria(int[] thresholds, int ran) {
        // no-op default implementation
    }

    /** Sets the SignalStrength reporting criteria. */
    public void setLinkCapacityReportingCriteria(int[] dlThresholds, int[] ulThresholds, int ran) {
        // no-op default implementation
    }

    /**
     * Get allowed carriers
     */
+107 −2
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import android.hardware.radio.V1_0.HardwareConfigModem;
import android.hardware.radio.V1_0.IRadio;
import android.hardware.radio.V1_0.IccIo;
import android.hardware.radio.V1_0.ImsSmsMessage;
import android.hardware.radio.V1_0.IndicationFilter;
import android.hardware.radio.V1_0.LceDataInfo;
import android.hardware.radio.V1_0.MvnoType;
import android.hardware.radio.V1_0.NvWriteItem;
@@ -51,6 +52,7 @@ import android.hardware.radio.V1_0.SelectUiccSub;
import android.hardware.radio.V1_0.SimApdu;
import android.hardware.radio.V1_0.SmsWriteArgs;
import android.hardware.radio.V1_0.UusInfo;
import android.hardware.radio.V1_2.AccessNetwork;
import android.net.ConnectivityManager;
import android.net.KeepalivePacketData;
import android.net.LinkProperties;
@@ -3602,13 +3604,103 @@ public class RIL extends BaseCommands implements CommandsInterface {
                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest) + " " + filter);
            }

            android.hardware.radio.V1_2.IRadio radioProxy12 =
                    android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);

            if (radioProxy12 != null) {
                try {
                    radioProxy12.setIndicationFilter_1_2(rr.mSerial, filter);
                } catch (RemoteException | RuntimeException e) {
                    handleRadioProxyExceptionForRR(rr, "setIndicationFilter_1_2", e);
                }
            } else {
                try {
                radioProxy.setIndicationFilter(rr.mSerial, filter);
                    int filter10 = filter & IndicationFilter.ALL;
                    radioProxy.setIndicationFilter(rr.mSerial, filter10);
                } catch (RemoteException | RuntimeException e) {
                    handleRadioProxyExceptionForRR(rr, "setIndicationFilter", e);
                }
            }
        }
    }

    @Override
    public void setSignalStrengthReportingCriteria(int hysteresisMs, int hysteresisDb,
            int[] thresholdsDbm, int ran, Message result) {
        IRadio radioProxy = getRadioProxy(result);
        if (radioProxy != null) {
            android.hardware.radio.V1_2.IRadio radioProxy12 =
                    android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
            if (radioProxy12 == null) {
                riljLoge("setSignalStrengthReportingCriteria ignored. RadioProxy 1.2 is null!");
                return;
            }

            RILRequest rr = obtainRequest(RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA,
                    result, mRILDefaultWorkSource);

            if (RILJ_LOGD) {
                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
            }

            try {
                radioProxy12.setSignalStrengthReportingCriteria(rr.mSerial, hysteresisMs,
                        hysteresisDb, primitiveArrayToArrayList(thresholdsDbm),
                        convertRanToHalRan(ran));
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR(rr, "setSignalStrengthReportingCriteria", e);
            }
        }
    }

    @Override
    public void setLinkCapacityReportingCriteria(int hysteresisMs, int hysteresisDlKbps,
            int hysteresisUlKbps, int[] thresholdsDlKbps, int[] thresholdsUlKbps, int ran,
            Message result) {
        IRadio radioProxy = getRadioProxy(result);
        if (radioProxy != null) {
            android.hardware.radio.V1_2.IRadio radioProxy12 =
                    android.hardware.radio.V1_2.IRadio.castFrom(radioProxy);
            if (radioProxy12 == null) {
                riljLoge("setLinkCapacityReportingCriteria ignored. RadioProxy 1.2 is null!");
                return;
            }

            RILRequest rr = obtainRequest(RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA,
                    result, mRILDefaultWorkSource);

            if (RILJ_LOGD) {
                riljLog(rr.serialString() + "> " + requestToString(rr.mRequest));
            }

            try {
                radioProxy12.setLinkCapacityReportingCriteria(rr.mSerial, hysteresisMs,
                        hysteresisDlKbps, hysteresisUlKbps,
                        primitiveArrayToArrayList(thresholdsDlKbps),
                        primitiveArrayToArrayList(thresholdsUlKbps), convertRanToHalRan(ran));
            } catch (RemoteException | RuntimeException e) {
                handleRadioProxyExceptionForRR(rr, "setLinkCapacityReportingCriteria", e);
            }
        }
    }

    private static int convertRanToHalRan(int radioAccessNetwork) {
        switch (radioAccessNetwork) {
            case AccessNetworkType.GERAN:
                return AccessNetwork.GERAN;
            case AccessNetworkType.UTRAN:
                return AccessNetwork.UTRAN;
            case AccessNetworkType.EUTRAN:
                return AccessNetwork.EUTRAN;
            case AccessNetworkType.CDMA2000:
                return AccessNetwork.CDMA2000;
            case AccessNetworkType.IWLAN:
                return AccessNetwork.IWLAN;
            case AccessNetworkType.UNKNOWN:
            default:
                return 0;
        }
    }

    @Override
    public void setSimCardPower(int state, Message result) {
@@ -4716,6 +4808,10 @@ public class RIL extends BaseCommands implements CommandsInterface {
                return "RIL_REQUEST_START_KEEPALIVE";
            case RIL_REQUEST_STOP_KEEPALIVE:
                return "RIL_REQUEST_STOP_KEEPALIVE";
            case RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA:
                return "RIL_REQUEST_SET_SIGNAL_STRENGTH_REPORTING_CRITERIA";
            case RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA:
                return "RIL_REQUEST_SET_LINK_CAPACITY_REPORTING_CRITERIA";
            default: return "<unknown request>";
        }
    }
@@ -4917,6 +5013,15 @@ public class RIL extends BaseCommands implements CommandsInterface {
        return arrayList;
    }

    /** Convert a primitive int array to an ArrayList<Integer>. */
    public static ArrayList<Integer> primitiveArrayToArrayList(int[] arr) {
        ArrayList<Integer> arrayList = new ArrayList<>(arr.length);
        for (int i : arr) {
            arrayList.add(i);
        }
        return arrayList;
    }

    /** Convert an ArrayList of Bytes to an exactly-sized primitive array */
    public static byte[] arrayListToPrimitiveArray(ArrayList<Byte> bytes) {
        byte[] ret = new byte[bytes.size()];
Loading