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

Commit e630298f authored by Rambo Wang's avatar Rambo Wang Committed by Gerrit Code Review
Browse files

Merge "Preparation to expose SignalThresholdInfo as public class"

parents 4632bfaa 2436cff5
Loading
Loading
Loading
Loading
+417 −61
Original line number Diff line number Diff line
@@ -30,99 +30,117 @@ import java.util.Objects;
 * Defines the threshold value of the signal strength.
 * @hide
 */
public class SignalThresholdInfo implements Parcelable {
public final class SignalThresholdInfo implements Parcelable {

    /**
     * Unknown signal measurement type.
     * @hide
     */
    public static final int SIGNAL_MEASUREMENT_TYPE_UNKNOWN = 0;

    /**
     * Received Signal Strength Indication.
     * Range: -113 dBm and -51 dBm
     * Used RAN: GERAN, CDMA2000
     * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#GERAN},
     *           {@link AccessNetworkConstants.AccessNetworkType#CDMA2000}
     * Reference: 3GPP TS 27.007 section 8.5.
     * @hide
     */
    public static final int SIGNAL_RSSI = 1;
    public static final int SIGNAL_MEASUREMENT_TYPE_RSSI = 1;

    /**
     * Received Signal Code Power.
     * Range: -120 dBm to -25 dBm;
     * Used RAN: UTRAN
     * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#UTRAN}
     * Reference: 3GPP TS 25.123, section 9.1.1.1
     * @hide
     */
    public static final int SIGNAL_RSCP = 2;
    public static final int SIGNAL_MEASUREMENT_TYPE_RSCP = 2;

    /**
     * Reference Signal Received Power.
     * Range: -140 dBm to -44 dBm;
     * Used RAN: EUTRAN
     * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
     * Reference: 3GPP TS 36.133 9.1.4
     * @hide
     */
    public static final int SIGNAL_RSRP = 3;
    public static final int SIGNAL_MEASUREMENT_TYPE_RSRP = 3;

    /**
     * Reference Signal Received Quality
     * Range: -20 dB to -3 dB;
     * Used RAN: EUTRAN
     * Range: -34 dB to 3 dB;
     * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
     * Reference: 3GPP TS 36.133 9.1.7
     * @hide
     */
    public static final int SIGNAL_RSRQ = 4;
    public static final int SIGNAL_MEASUREMENT_TYPE_RSRQ = 4;

    /**
     * Reference Signal Signal to Noise Ratio
     * Range: -20 dB to 30 dB;
     * Used RAN: EUTRAN
     * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
     * @hide
     */
    public static final int SIGNAL_RSSNR = 5;
    public static final int SIGNAL_MEASUREMENT_TYPE_RSSNR = 5;

    /**
     * 5G SS reference signal received power.
     * Range: -140 dBm to -44 dBm.
     * Used RAN: NGRAN
     * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
     * Reference: 3GPP TS 38.215.
     * @hide
     */
    public static final int SIGNAL_SSRSRP = 6;
    public static final int SIGNAL_MEASUREMENT_TYPE_SSRSRP = 6;

    /**
     * 5G SS reference signal received quality.
     * Range: -20 dB to -3 dB.
     * Used RAN: NGRAN
     * Reference: 3GPP TS 38.215.
     * Range: -43 dB to 20 dB.
     * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
     * Reference: 3GPP TS 38.133 section 10.1.11.1.
     * @hide
     */
    public static final int SIGNAL_SSRSRQ = 7;
    public static final int SIGNAL_MEASUREMENT_TYPE_SSRSRQ = 7;

    /**
     * 5G SS signal-to-noise and interference ratio.
     * Range: -23 dB to 40 dB
     * Used RAN: NGRAN
     * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
     * Reference: 3GPP TS 38.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1.
     * @hide
     */
    public static final int SIGNAL_SSSINR = 8;
    public static final int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8;

    /** @hide */
    @IntDef(prefix = { "SIGNAL_" }, value = {
        SIGNAL_RSSI,
        SIGNAL_RSCP,
        SIGNAL_RSRP,
        SIGNAL_RSRQ,
        SIGNAL_RSSNR,
        SIGNAL_SSRSRP,
        SIGNAL_SSRSRQ,
        SIGNAL_SSSINR
    @IntDef(prefix = {"SIGNAL_MEASUREMENT_TYPE_"}, value = {
            SIGNAL_MEASUREMENT_TYPE_UNKNOWN,
            SIGNAL_MEASUREMENT_TYPE_RSSI,
            SIGNAL_MEASUREMENT_TYPE_RSCP,
            SIGNAL_MEASUREMENT_TYPE_RSRP,
            SIGNAL_MEASUREMENT_TYPE_RSRQ,
            SIGNAL_MEASUREMENT_TYPE_RSSNR,
            SIGNAL_MEASUREMENT_TYPE_SSRSRP,
            SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
            SIGNAL_MEASUREMENT_TYPE_SSSINR
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface SignalMeasurementType {}
    public @interface SignalMeasurementType {
    }

    @SignalMeasurementType
    private int mSignalMeasurement;
    private final int mSignalMeasurementType;

    /**
     * A hysteresis time in milliseconds to prevent flapping.
     * A value of 0 disables hysteresis
     */
    private int mHysteresisMs;
    private final int mHysteresisMs;

    /**
     * An interval in dB defining the required magnitude change between reports.
     * hysteresisDb must be smaller than the smallest threshold delta.
     * An interval value of 0 disables hysteresis.
     */
    private int mHysteresisDb;
    private final int mHysteresisDb;

    /**
     * List of threshold values.
@@ -130,60 +148,323 @@ public class SignalThresholdInfo implements Parcelable {
     * The threshold values for which to apply criteria.
     * A vector size of 0 disables the use of thresholds for reporting.
     */
    private int[] mThresholds = null;
    private final int[] mThresholds;

    /**
     * {@code true} means modem must trigger the report based on the criteria;
     * {@code false} means modem must not trigger the report based on the criteria.
     */
    private boolean mIsEnabled = true;
    private final boolean mIsEnabled;

    /**
     * The radio access network type associated with the signal thresholds.
     */
    @AccessNetworkConstants.RadioAccessNetworkType
    private final int mRan;

    /**
     * Indicates the hysteresisMs is disabled.
     *
     * @hide
     */
    public static final int HYSTERESIS_MS_DISABLED = 0;

    /**
     * Indicates the hysteresisDb is disabled.
     *
     * @hide
     */
    public static final int HYSTERESIS_DB_DISABLED = 0;


    /**
     * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSSI}.
     *
     * @hide
     */
    public static final int SIGNAL_RSSI_MIN_VALUE = -113;

    /**
     * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSSI}.
     *
     * @hide
     */
    public static final int SIGNAL_RSSI_MAX_VALUE = -51;

    /**
     * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSCP}.
     *
     * @hide
     */
    public static final int SIGNAL_RSCP_MIN_VALUE = -120;

    /**
     * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSCP}.
     *
     * @hide
     */
    public static final int SIGNAL_RSCP_MAX_VALUE = -25;

    /**
     * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSRP}.
     *
     * @hide
     */
    public static final int SIGNAL_RSRP_MIN_VALUE = -140;

    /**
     * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSRP}.
     *
     * @hide
     */
    public static final int SIGNAL_RSRP_MAX_VALUE = -44;

    /**
     * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSRQ}.
     *
     * @hide
     */
    public static final int SIGNAL_RSRQ_MIN_VALUE = -34;

    /**
     * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSRQ}.
     *
     * @hide
     */
    public static final int SIGNAL_RSRQ_MAX_VALUE = 3;

    /**
     * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSSNR}.
     *
     * @hide
     */
    public static final int SIGNAL_RSSNR_MIN_VALUE = -20;

    /**
     * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSSNR}.
     *
     * @hide
     */
    public static final int SIGNAL_RSSNR_MAX_VALUE = 30;

    /**
     * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSRSRP}.
     *
     * @hide
     */
    public static final int SIGNAL_SSRSRP_MIN_VALUE = -140;

    /**
     * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSRSRP}.
     *
     * @hide
     */
    public static final int SIGNAL_SSRSRP_MAX_VALUE = -44;

    /**
     * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSRSRQ}.
     *
     * @hide
     */
    public static final int SIGNAL_SSRSRQ_MIN_VALUE = -43;

    /**
     * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSRSRQ}.
     *
     * @hide
     */
    public static final int SIGNAL_SSRSRQ_MAX_VALUE = 20;

    /**
     * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSSINR}.
     *
     * @hide
     */
    public static final int SIGNAL_SSSINR_MIN_VALUE = -23;

    /**
     * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSSINR}.
     *
     * @hide
     */
    public static final int SIGNAL_SSSINR_MAX_VALUE = 40;

    /**
     * Constructor
     *
     * @param signalMeasurement Signal Measurement Type
     * @param ran               Radio Access Network type
     * @param signalMeasurementType Signal Measurement Type
     * @param hysteresisMs      hysteresisMs
     * @param hysteresisDb      hysteresisDb
     * @param thresholds        threshold value
     * @param isEnabled         isEnabled
     */
    public SignalThresholdInfo(@SignalMeasurementType int signalMeasurement,
            int hysteresisMs, int hysteresisDb, @NonNull int [] thresholds, boolean isEnabled) {
        mSignalMeasurement = signalMeasurement;
    private SignalThresholdInfo(@AccessNetworkConstants.RadioAccessNetworkType int ran,
            @SignalMeasurementType int signalMeasurementType, int hysteresisMs, int hysteresisDb,
            @NonNull int[] thresholds, boolean isEnabled) {
        Objects.requireNonNull(thresholds, "thresholds must not be null");
        validateRanWithMeasurementType(ran, signalMeasurementType);
        validateThresholdRange(signalMeasurementType, thresholds);

        mRan = ran;
        mSignalMeasurementType = signalMeasurementType;
        mHysteresisMs = hysteresisMs < 0 ? HYSTERESIS_MS_DISABLED : hysteresisMs;
        mHysteresisDb = hysteresisDb < 0 ? HYSTERESIS_DB_DISABLED : hysteresisDb;
        mThresholds = thresholds == null ? null : thresholds.clone();
        mThresholds = thresholds;
        mIsEnabled = isEnabled;
    }

    public @SignalMeasurementType int getSignalMeasurement() {
        return mSignalMeasurement;
    /**
     * Builder class to create {@link SignalThresholdInfo} objects.
     *
     * @hide
     */
    public static final class Builder {
        private int mRan = AccessNetworkConstants.AccessNetworkType.UNKNOWN;
        private int mSignalMeasurementType = SIGNAL_MEASUREMENT_TYPE_UNKNOWN;
        private int mHysteresisMs = HYSTERESIS_MS_DISABLED;
        private int mHysteresisDb = HYSTERESIS_DB_DISABLED;
        private int[] mThresholds = null;
        private boolean mIsEnabled = false;

        /**
         * Set the radio access network type for the builder instance.
         *
         * @param ran The radio access network type
         * @return the builder to facilitate the chaining
         */
        public @NonNull Builder setRadioAccessNetworkType(
                @AccessNetworkConstants.RadioAccessNetworkType int ran) {
            mRan = ran;
            return this;
        }

        /**
         * Set the signal measurement type for the builder instance.
         *
         * @param signalMeasurementType The signal measurement type
         * @return the builder to facilitate the chaining
         */
        public @NonNull Builder setSignalMeasurementType(
                @SignalMeasurementType int signalMeasurementType) {
            mSignalMeasurementType = signalMeasurementType;
            return this;
        }

        /**
         * Set the hysteresis time in milliseconds to prevent flapping. A value of 0 disables
         * hysteresis.
         *
         * @param hysteresisMs the hysteresis time in milliseconds
         * @return the builder to facilitate the chaining
         * @hide
         */
        public @NonNull Builder setHysteresisMs(int hysteresisMs) {
            mHysteresisMs = hysteresisMs;
            return this;
        }

        /**
         * Set the interval in dB defining the required magnitude change between reports. A value of
         * zero disabled dB-based hysteresis restrictions.
         *
         * @param hysteresisDb the interval in dB
         * @return the builder to facilitate the chaining
         * @hide
         */
        public @NonNull Builder setHysteresisDb(int hysteresisDb) {
            mHysteresisDb = hysteresisDb;
            return this;
        }

        /**
         * Set the signal threshold values of the corresponding signal measurement type.
         *
         * The range and unit must reference specific SignalMeasurementType.
         *
         * @param thresholds array of integer as the signal threshold values
         * @return the builder to facilitate the chaining
         */
        public @NonNull Builder setThresholds(@NonNull int[] thresholds) {
            Objects.requireNonNull(thresholds, "thresholds must not be null");
            mThresholds = thresholds.clone();
            Arrays.sort(mThresholds);
            return this;
        }

        /**
         * Set if the modem should trigger the report based on the criteria.
         *
         * @param isEnabled true if the modem should trigger the report based on the criteria
         * @return the builder to facilitate the chaining
         * @hide
         */
        public @NonNull Builder setIsEnabled(boolean isEnabled) {
            mIsEnabled = isEnabled;
            return this;
        }

        /**
         * Build {@link SignalThresholdInfo} object.
         *
         * @return the SignalThresholdInfo object build out
         *
         * @throws IllegalArgumentException if the signal measurement type is invalid, any value in
         * the thresholds is out of range, or the RAN is not allowed to set with the signal
         * measurement type
         */
        public @NonNull SignalThresholdInfo build() {
            return new SignalThresholdInfo(mRan, mSignalMeasurementType, mHysteresisMs,
                    mHysteresisDb, mThresholds, mIsEnabled);
        }
    }

    /**
     * Get the radio access network type.
     *
     * @return radio access network type
     *
     * @hide
     */
    public @AccessNetworkConstants.RadioAccessNetworkType int getRadioAccessNetworkType() {
        return mRan;
    }

    /**
     * Get the signal measurement type.
     *
     * @return the SignalMeasurementType value
     *
     * @hide
     */
    public @SignalMeasurementType int getSignalMeasurementType() {
        return mSignalMeasurementType;
    }

    /** @hide */
    public int getHysteresisMs() {
        return mHysteresisMs;
    }

    /** @hide */
    public int getHysteresisDb() {
        return mHysteresisDb;
    }

    /** @hide */
    public boolean isEnabled() {
        return mIsEnabled;
    }

    public int[] getThresholds() {
        return mThresholds == null ? null : mThresholds.clone();
    /**
     * Get the signal threshold values.
     *
     * @return array of integer of the signal thresholds
     *
     * @hide
     */
    public @NonNull int[] getThresholds() {
        return mThresholds.clone();
    }

    @Override
@@ -192,8 +473,9 @@ public class SignalThresholdInfo implements Parcelable {
    }

    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mSignalMeasurement);
    public void writeToParcel(@NonNull Parcel out, int flags) {
        out.writeInt(mRan);
        out.writeInt(mSignalMeasurementType);
        out.writeInt(mHysteresisMs);
        out.writeInt(mHysteresisDb);
        out.writeIntArray(mThresholds);
@@ -201,7 +483,8 @@ public class SignalThresholdInfo implements Parcelable {
    }

    private SignalThresholdInfo(Parcel in) {
        mSignalMeasurement = in.readInt();
        mRan = in.readInt();
        mSignalMeasurementType = in.readInt();
        mHysteresisMs = in.readInt();
        mHysteresisDb = in.readInt();
        mThresholds = in.createIntArray();
@@ -217,7 +500,8 @@ public class SignalThresholdInfo implements Parcelable {
        }

        SignalThresholdInfo other = (SignalThresholdInfo) o;
        return mSignalMeasurement == other.mSignalMeasurement
        return mRan == other.mRan
                && mSignalMeasurementType == other.mSignalMeasurementType
                && mHysteresisMs == other.mHysteresisMs
                && mHysteresisDb == other.mHysteresisDb
                && Arrays.equals(mThresholds, other.mThresholds)
@@ -226,8 +510,8 @@ public class SignalThresholdInfo implements Parcelable {

    @Override
    public int hashCode() {
        return Objects.hash(
                mSignalMeasurement, mHysteresisMs, mHysteresisDb, mThresholds, mIsEnabled);
        return Objects.hash(mRan, mSignalMeasurementType, mHysteresisMs, mHysteresisDb, mThresholds,
                mIsEnabled);
    }

    public static final @NonNull Parcelable.Creator<SignalThresholdInfo> CREATOR =
@@ -246,11 +530,83 @@ public class SignalThresholdInfo implements Parcelable {
    @Override
    public String toString() {
        return new StringBuilder("SignalThresholdInfo{")
            .append("mSignalMeasurement=").append(mSignalMeasurement)
            .append("mHysteresisMs=").append(mSignalMeasurement)
                .append("mRan=").append(mRan)
                .append(" mSignalMeasurementType=").append(mSignalMeasurementType)
                .append(" mHysteresisMs=").append(mHysteresisMs)
                .append(" mHysteresisDb=").append(mHysteresisDb)
                .append(" mThresholds=").append(Arrays.toString(mThresholds))
                .append(" mIsEnabled=").append(mIsEnabled)
                .append("}").toString();
    }

    /**
     * Return true if signal measurement type is valid and the threshold value is in range.
     */
    private static boolean isValidThreshold(@SignalMeasurementType int type, int threshold) {
        switch (type) {
            case SIGNAL_MEASUREMENT_TYPE_RSSI:
                return threshold >= SIGNAL_RSSI_MIN_VALUE && threshold <= SIGNAL_RSSI_MAX_VALUE;
            case SIGNAL_MEASUREMENT_TYPE_RSCP:
                return threshold >= SIGNAL_RSCP_MIN_VALUE && threshold <= SIGNAL_RSCP_MAX_VALUE;
            case SIGNAL_MEASUREMENT_TYPE_RSRP:
                return threshold >= SIGNAL_RSRP_MIN_VALUE && threshold <= SIGNAL_RSRP_MAX_VALUE;
            case SIGNAL_MEASUREMENT_TYPE_RSRQ:
                return threshold >= SIGNAL_RSRQ_MIN_VALUE && threshold <= SIGNAL_RSRQ_MAX_VALUE;
            case SIGNAL_MEASUREMENT_TYPE_RSSNR:
                return threshold >= SIGNAL_RSSNR_MIN_VALUE && threshold <= SIGNAL_RSSNR_MAX_VALUE;
            case SIGNAL_MEASUREMENT_TYPE_SSRSRP:
                return threshold >= SIGNAL_SSRSRP_MIN_VALUE && threshold <= SIGNAL_SSRSRP_MAX_VALUE;
            case SIGNAL_MEASUREMENT_TYPE_SSRSRQ:
                return threshold >= SIGNAL_SSRSRQ_MIN_VALUE && threshold <= SIGNAL_SSRSRQ_MAX_VALUE;
            case SIGNAL_MEASUREMENT_TYPE_SSSINR:
                return threshold >= SIGNAL_SSSINR_MIN_VALUE && threshold <= SIGNAL_SSSINR_MAX_VALUE;
            default:
                return false;
        }
    }

    /**
     * Return true if the radio access type is allowed to set with the measurement type.
     */
    private static boolean isValidRanWithMeasurementType(
            @AccessNetworkConstants.RadioAccessNetworkType int ran,
            @SignalMeasurementType int type) {
        switch (type) {
            case SIGNAL_MEASUREMENT_TYPE_RSSI:
                return ran == AccessNetworkConstants.AccessNetworkType.GERAN
                        || ran == AccessNetworkConstants.AccessNetworkType.CDMA2000;
            case SIGNAL_MEASUREMENT_TYPE_RSCP:
                return ran == AccessNetworkConstants.AccessNetworkType.UTRAN;
            case SIGNAL_MEASUREMENT_TYPE_RSRP:
            case SIGNAL_MEASUREMENT_TYPE_RSRQ:
            case SIGNAL_MEASUREMENT_TYPE_RSSNR:
                return ran == AccessNetworkConstants.AccessNetworkType.EUTRAN;
            case SIGNAL_MEASUREMENT_TYPE_SSRSRP:
            case SIGNAL_MEASUREMENT_TYPE_SSRSRQ:
            case SIGNAL_MEASUREMENT_TYPE_SSSINR:
                return ran == AccessNetworkConstants.AccessNetworkType.NGRAN;
            default:
                return false;
        }
    }

    private void validateRanWithMeasurementType(
            @AccessNetworkConstants.RadioAccessNetworkType int ran,
            @SignalMeasurementType int signalMeasurement) {
        if (!isValidRanWithMeasurementType(ran, signalMeasurement)) {
            throw new IllegalArgumentException(
                    "invalid RAN: " + ran + " with signal measurement type: " + signalMeasurement);
        }
    }

    private void validateThresholdRange(@SignalMeasurementType int signalMeasurement,
            int[] thresholds) {
        for (int threshold : thresholds) {
            if (!isValidThreshold(signalMeasurement, threshold)) {
                throw new IllegalArgumentException(
                        "invalid signal measurement type: " + signalMeasurement
                                + " with threshold: " + threshold);
            }
        }
    }
}