• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package android.telephony;
18 
19 import android.annotation.IntDef;
20 import android.annotation.IntRange;
21 import android.annotation.NonNull;
22 import android.os.Parcel;
23 import android.os.Parcelable;
24 
25 import java.lang.annotation.Retention;
26 import java.lang.annotation.RetentionPolicy;
27 import java.util.Arrays;
28 import java.util.Objects;
29 
30 /**
31  * Defines the threshold value of the signal strength.
32  */
33 public final class SignalThresholdInfo implements Parcelable {
34 
35     /**
36      * Unknown signal measurement type.
37      */
38     public static final int SIGNAL_MEASUREMENT_TYPE_UNKNOWN = 0;
39 
40     /**
41      * Received Signal Strength Indication.
42      * Range: -113 dBm and -51 dBm
43      * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#GERAN},
44      *           {@link AccessNetworkConstants.AccessNetworkType#CDMA2000}
45      * Reference: 3GPP TS 27.007 section 8.5.
46      */
47     public static final int SIGNAL_MEASUREMENT_TYPE_RSSI = 1;
48 
49     /**
50      * Received Signal Code Power.
51      * Range: -120 dBm to -25 dBm;
52      * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#UTRAN}
53      * Reference: 3GPP TS 25.123, section 9.1.1.1
54      */
55     public static final int SIGNAL_MEASUREMENT_TYPE_RSCP = 2;
56 
57     /**
58      * Reference Signal Received Power.
59      * Range: -140 dBm to -44 dBm;
60      * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
61      * Reference: 3GPP TS 36.133 9.1.4
62      */
63     public static final int SIGNAL_MEASUREMENT_TYPE_RSRP = 3;
64 
65     /**
66      * Reference Signal Received Quality
67      * Range: -34 dB to 3 dB;
68      * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
69      * Reference: 3GPP TS 36.133 9.1.7
70      */
71     public static final int SIGNAL_MEASUREMENT_TYPE_RSRQ = 4;
72 
73     /**
74      * Reference Signal Signal to Noise Ratio
75      * Range: -20 dB to 30 dB;
76      * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#EUTRAN}
77      */
78     public static final int SIGNAL_MEASUREMENT_TYPE_RSSNR = 5;
79 
80     /**
81      * 5G SS reference signal received power.
82      * Range: -140 dBm to -44 dBm.
83      * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
84      * Reference: 3GPP TS 38.215.
85      */
86     public static final int SIGNAL_MEASUREMENT_TYPE_SSRSRP = 6;
87 
88     /**
89      * 5G SS reference signal received quality.
90      * Range: -43 dB to 20 dB.
91      * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
92      * Reference: 3GPP TS 38.133 section 10.1.11.1.
93      */
94     public static final int SIGNAL_MEASUREMENT_TYPE_SSRSRQ = 7;
95 
96     /**
97      * 5G SS signal-to-noise and interference ratio.
98      * Range: -23 dB to 40 dB
99      * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#NGRAN}
100      * Reference: 3GPP TS 38.215 section 5.1.*, 3GPP TS 38.133 section 10.1.16.1.
101      */
102     public static final int SIGNAL_MEASUREMENT_TYPE_SSSINR = 8;
103 
104     /**
105      * The ratio between the received energy from the pilot signal CPICH per chip (Ec) to the
106      * noise density (No).
107      * Range: -24 dBm to 1 dBm.
108      * Used RAN: {@link AccessNetworkConstants.AccessNetworkType#UTRAN}
109      * Reference: 3GPP TS 25.215 5.1.5
110      */
111     public static final int SIGNAL_MEASUREMENT_TYPE_ECNO = 9;
112 
113     /** @hide */
114     @IntDef(
115             prefix = {"SIGNAL_MEASUREMENT_TYPE_"},
116             value = {
117                 SIGNAL_MEASUREMENT_TYPE_UNKNOWN,
118                 SIGNAL_MEASUREMENT_TYPE_RSSI,
119                 SIGNAL_MEASUREMENT_TYPE_RSCP,
120                 SIGNAL_MEASUREMENT_TYPE_RSRP,
121                 SIGNAL_MEASUREMENT_TYPE_RSRQ,
122                 SIGNAL_MEASUREMENT_TYPE_RSSNR,
123                 SIGNAL_MEASUREMENT_TYPE_SSRSRP,
124                 SIGNAL_MEASUREMENT_TYPE_SSRSRQ,
125                 SIGNAL_MEASUREMENT_TYPE_SSSINR,
126                 SIGNAL_MEASUREMENT_TYPE_ECNO
127             })
128     @Retention(RetentionPolicy.SOURCE)
129     public @interface SignalMeasurementType {}
130 
131     @SignalMeasurementType private final int mSignalMeasurementType;
132 
133     /**
134      * A hysteresis time in milliseconds to prevent flapping.
135      * A value of 0 disables hysteresis
136      */
137     private final int mHysteresisMs;
138 
139     /**
140      * An interval in dB defining the required magnitude change between reports.
141      * hysteresisDb must be smaller than the smallest threshold delta.
142      * An interval value of 0 disables hysteresis.
143      */
144     private final int mHysteresisDb;
145 
146     /**
147      * List of threshold values.
148      * Range and unit must reference specific SignalMeasurementType
149      * The threshold values for which to apply criteria.
150      * A vector size of 0 disables the use of thresholds for reporting.
151      */
152     private final int[] mThresholds;
153 
154     /**
155      * {@code true} means modem must trigger the report based on the criteria;
156      * {@code false} means modem must not trigger the report based on the criteria.
157      */
158     private final boolean mIsEnabled;
159 
160     /**
161      * The radio access network type associated with the signal thresholds.
162      */
163     @AccessNetworkConstants.RadioAccessNetworkType private final int mRan;
164 
165     /**
166      * Indicates the hysteresisMs is disabled.
167      *
168      * @hide
169      */
170     public static final int HYSTERESIS_MS_DISABLED = 0;
171 
172     /**
173      * Indicates the default hysteresis value in dB.
174      *
175      * @hide
176      */
177     private static final int HYSTERESIS_DB_DEFAULT = 2;
178 
179     /**
180      * Indicates the hysteresisDb value is not set and to be initialised to default value.
181      *
182      * @hide
183      */
184     public static final int HYSTERESIS_DB_MINIMUM = 0;
185 
186     /**
187      * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSSI}.
188      *
189      * @hide
190      */
191     public static final int SIGNAL_RSSI_MIN_VALUE = -113;
192 
193     /**
194      * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSSI}.
195      *
196      * @hide
197      */
198     public static final int SIGNAL_RSSI_MAX_VALUE = -51;
199 
200     /**
201      * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSCP}.
202      *
203      * @hide
204      */
205     public static final int SIGNAL_RSCP_MIN_VALUE = -120;
206 
207     /**
208      * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSCP}.
209      *
210      * @hide
211      */
212     public static final int SIGNAL_RSCP_MAX_VALUE = -25;
213 
214     /**
215      * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSRP}.
216      *
217      * @hide
218      */
219     public static final int SIGNAL_RSRP_MIN_VALUE = -140;
220 
221     /**
222      * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSRP}.
223      *
224      * @hide
225      */
226     public static final int SIGNAL_RSRP_MAX_VALUE = -44;
227 
228     /**
229      * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSRQ}.
230      *
231      * @hide
232      */
233     public static final int SIGNAL_RSRQ_MIN_VALUE = -34;
234 
235     /**
236      * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSRQ}.
237      *
238      * @hide
239      */
240     public static final int SIGNAL_RSRQ_MAX_VALUE = 3;
241 
242     /**
243      * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSSNR}.
244      *
245      * @hide
246      */
247     public static final int SIGNAL_RSSNR_MIN_VALUE = -20;
248 
249     /**
250      * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_RSSNR}.
251      *
252      * @hide
253      */
254     public static final int SIGNAL_RSSNR_MAX_VALUE = 30;
255 
256     /**
257      * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSRSRP}.
258      *
259      * @hide
260      */
261     public static final int SIGNAL_SSRSRP_MIN_VALUE = -140;
262 
263     /**
264      * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSRSRP}.
265      *
266      * @hide
267      */
268     public static final int SIGNAL_SSRSRP_MAX_VALUE = -44;
269 
270     /**
271      * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSRSRQ}.
272      *
273      * @hide
274      */
275     public static final int SIGNAL_SSRSRQ_MIN_VALUE = -43;
276 
277     /**
278      * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSRSRQ}.
279      *
280      * @hide
281      */
282     public static final int SIGNAL_SSRSRQ_MAX_VALUE = 20;
283 
284     /**
285      * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSSINR}.
286      *
287      * @hide
288      */
289     public static final int SIGNAL_SSSINR_MIN_VALUE = -23;
290 
291     /**
292      * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_SSSINR}.
293      *
294      * @hide
295      */
296     public static final int SIGNAL_SSSINR_MAX_VALUE = 40;
297 
298     /**
299      * Minimum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_ECNO}.
300      *
301      * @hide
302      */
303     public static final int SIGNAL_ECNO_MIN_VALUE = -24;
304 
305     /**
306      * Maximum valid value for {@link #SIGNAL_MEASUREMENT_TYPE_ECNO}.
307      *
308      * @hide
309      */
310     public static final int SIGNAL_ECNO_MAX_VALUE = 1;
311 
312     /**
313      * The minimum number of thresholds allowed in each SignalThresholdInfo.
314      *
315      * @hide
316      */
317     public static final int MINIMUM_NUMBER_OF_THRESHOLDS_ALLOWED = 1;
318 
319     /**
320      * The maximum number of thresholds allowed in each SignalThresholdInfo.
321      *
322      * @hide
323      */
324     public static final int MAXIMUM_NUMBER_OF_THRESHOLDS_ALLOWED = 4;
325 
326     /**
327      * Constructor
328      *
329      * @param ran               Radio Access Network type
330      * @param signalMeasurementType Signal Measurement Type
331      * @param hysteresisMs      hysteresisMs
332      * @param hysteresisDb      hysteresisDb
333      * @param thresholds        threshold value
334      * @param isEnabled         isEnabled
335      */
SignalThresholdInfo( @ccessNetworkConstants.RadioAccessNetworkType int ran, @SignalMeasurementType int signalMeasurementType, int hysteresisMs, int hysteresisDb, @NonNull int[] thresholds, boolean isEnabled)336     private SignalThresholdInfo(
337             @AccessNetworkConstants.RadioAccessNetworkType int ran,
338             @SignalMeasurementType int signalMeasurementType,
339             int hysteresisMs,
340             int hysteresisDb,
341             @NonNull int[] thresholds,
342             boolean isEnabled) {
343         Objects.requireNonNull(thresholds, "thresholds must not be null");
344         validateRanWithMeasurementType(ran, signalMeasurementType);
345         validateThresholdRange(signalMeasurementType, thresholds);
346 
347         mRan = ran;
348         mSignalMeasurementType = signalMeasurementType;
349         mHysteresisMs = hysteresisMs < 0 ? HYSTERESIS_MS_DISABLED : hysteresisMs;
350         mHysteresisDb = hysteresisDb;
351         mThresholds = thresholds;
352         mIsEnabled = isEnabled;
353     }
354 
355     /**
356      * Builder class to create {@link SignalThresholdInfo} objects.
357      */
358     public static final class Builder {
359         private int mRan = AccessNetworkConstants.AccessNetworkType.UNKNOWN;
360         private int mSignalMeasurementType = SIGNAL_MEASUREMENT_TYPE_UNKNOWN;
361         private int mHysteresisMs = HYSTERESIS_MS_DISABLED;
362         private int mHysteresisDb = HYSTERESIS_DB_DEFAULT;
363         private int[] mThresholds = null;
364         private boolean mIsEnabled = false;
365 
366         /**
367          * Set the radio access network type for the builder instance.
368          *
369          * @param ran The radio access network type
370          * @return the builder to facilitate the chaining
371          */
372         @NonNull
373         public Builder setRadioAccessNetworkType(
374                 @AccessNetworkConstants.RadioAccessNetworkType int ran) {
375             mRan = ran;
376             return this;
377         }
378 
379         /**
380          * Set the signal measurement type for the builder instance.
381          *
382          * @param signalMeasurementType The signal measurement type
383          * @return the builder to facilitate the chaining
384          */
385         @NonNull
386         public Builder setSignalMeasurementType(
387                 @SignalMeasurementType int signalMeasurementType) {
388             mSignalMeasurementType = signalMeasurementType;
389             return this;
390         }
391 
392         /**
393          * Set the hysteresis time in milliseconds to prevent flapping. A value of 0 disables
394          * hysteresis.
395          *
396          * @param hysteresisMs the hysteresis time in milliseconds
397          * @return the builder to facilitate the chaining
398          * @hide
399          */
400         @NonNull
401         public Builder setHysteresisMs(int hysteresisMs) {
402             mHysteresisMs = hysteresisMs;
403             return this;
404         }
405 
406         /**
407          * Set the interval in dB defining the required minimum magnitude change to report a
408          * signal strength change. A value of zero disables dB-based hysteresis restrictions.
409          * Note:
410          * <p>Default hysteresis db value is 2. Minimum hysteresis db value allowed to set is 0.
411          * If hysteresis db value is not set, default hysteresis db value of 2 will be used.
412          *
413          * @param hysteresisDb the interval in dB
414          * @return the builder to facilitate the chaining
415          */
416         @NonNull
417         public Builder setHysteresisDb(@IntRange(from = 0) int hysteresisDb) {
418             if (hysteresisDb < 0) {
419                 throw new IllegalArgumentException("hysteresis db value should not be less than 0");
420             }
421             mHysteresisDb = hysteresisDb;
422             return this;
423         }
424 
425         /**
426          * Set the signal strength thresholds of the corresponding signal measurement type.
427          *
428          * The range and unit must reference specific SignalMeasurementType. The length of the
429          * thresholds should between the numbers return from
430          * {@link #getMinimumNumberOfThresholdsAllowed()} and
431          * {@link #getMaximumNumberOfThresholdsAllowed()}. An IllegalArgumentException will throw
432          * otherwise.
433          *
434          * @param thresholds array of integer as the signal threshold values
435          * @return the builder to facilitate the chaining
436          *
437          * @see #SIGNAL_MEASUREMENT_TYPE_RSSI
438          * @see #SIGNAL_MEASUREMENT_TYPE_RSCP
439          * @see #SIGNAL_MEASUREMENT_TYPE_RSRP
440          * @see #SIGNAL_MEASUREMENT_TYPE_RSRQ
441          * @see #SIGNAL_MEASUREMENT_TYPE_RSSNR
442          * @see #SIGNAL_MEASUREMENT_TYPE_SSRSRP
443          * @see #SIGNAL_MEASUREMENT_TYPE_SSRSRQ
444          * @see #SIGNAL_MEASUREMENT_TYPE_SSSINR
445          * @see #SIGNAL_MEASUREMENT_TYPE_ECNO
446          * @see #getThresholds() for more details on signal strength thresholds
447          */
448         @NonNull
449         public Builder setThresholds(@NonNull int[] thresholds) {
450             return setThresholds(thresholds, false /*isSystem*/);
451         }
452 
453         /**
454          * Set the signal strength thresholds for the corresponding signal measurement type.
455          *
456          * @param thresholds array of integer as the signal threshold values
457          * @param isSystem true is the caller is system which does not have restrictions on
458          *        the length of thresholds array.
459          * @return the builder to facilitate the chaining
460          *
461          * @hide
462          */
463         @NonNull
464         public Builder setThresholds(@NonNull int[] thresholds, boolean isSystem) {
465             Objects.requireNonNull(thresholds, "thresholds must not be null");
466             if (!isSystem
467                     && (thresholds.length < MINIMUM_NUMBER_OF_THRESHOLDS_ALLOWED
468                             || thresholds.length > MAXIMUM_NUMBER_OF_THRESHOLDS_ALLOWED)) {
469                 throw new IllegalArgumentException(
470                         "thresholds length must between "
471                                 + MINIMUM_NUMBER_OF_THRESHOLDS_ALLOWED
472                                 + " and "
473                                 + MAXIMUM_NUMBER_OF_THRESHOLDS_ALLOWED);
474             }
475             mThresholds = thresholds.clone();
476             Arrays.sort(mThresholds);
477             return this;
478         }
479 
480         /**
481          * Set if the modem should trigger the report based on the criteria.
482          *
483          * @param isEnabled true if the modem should trigger the report based on the criteria
484          * @return the builder to facilitate the chaining
485          * @hide
486          */
487         @NonNull
488         public Builder setIsEnabled(boolean isEnabled) {
489             mIsEnabled = isEnabled;
490             return this;
491         }
492 
493         /**
494          * Build {@link SignalThresholdInfo} object.
495          *
496          * @return the SignalThresholdInfo object build out
497          *
498          * @throws IllegalArgumentException if the signal measurement type is invalid, any value in
499          * the thresholds is out of range, or the RAN is not allowed to set with the signal
500          * measurement type
501          */
502         @NonNull
503         public SignalThresholdInfo build() {
504             return new SignalThresholdInfo(
505                     mRan,
506                     mSignalMeasurementType,
507                     mHysteresisMs,
508                     mHysteresisDb,
509                     mThresholds,
510                     mIsEnabled);
511         }
512     }
513 
514     /**
515      * Get the radio access network type.
516      *
517      * @return radio access network type
518      */
519     @AccessNetworkConstants.RadioAccessNetworkType
520     public int getRadioAccessNetworkType() {
521         return mRan;
522     }
523 
524     /**
525      * Get the signal measurement type.
526      *
527      * @return the SignalMeasurementType value
528      */
529     @SignalMeasurementType
530     public int getSignalMeasurementType() {
531         return mSignalMeasurementType;
532     }
533 
534     /** @hide */
535     public int getHysteresisMs() {
536         return mHysteresisMs;
537     }
538 
539     /**
540      * Get measurement hysteresis db.
541      *
542      * @return hysteresis db value
543      */
544     public int getHysteresisDb() {
545         return mHysteresisDb;
546     }
547 
548     /** @hide */
549     public boolean isEnabled() {
550         return mIsEnabled;
551     }
552 
553     /**
554      * Get the signal strength thresholds.
555      *
556      * Signal strength thresholds are a list of integer used for suggesting signal level and signal
557      * reporting criteria. The range and unit must reference specific SignalMeasurementType.
558      *
559      * Please refer to https://source.android.com/devices/tech/connect/signal-strength on how signal
560      * strength thresholds are used for signal strength reporting.
561      *
562      * @return array of integer of the signal thresholds
563      *
564      * @see #SIGNAL_MEASUREMENT_TYPE_RSSI
565      * @see #SIGNAL_MEASUREMENT_TYPE_RSCP
566      * @see #SIGNAL_MEASUREMENT_TYPE_RSRP
567      * @see #SIGNAL_MEASUREMENT_TYPE_RSRQ
568      * @see #SIGNAL_MEASUREMENT_TYPE_RSSNR
569      * @see #SIGNAL_MEASUREMENT_TYPE_SSRSRP
570      * @see #SIGNAL_MEASUREMENT_TYPE_SSRSRQ
571      * @see #SIGNAL_MEASUREMENT_TYPE_SSSINR
572      * @see #SIGNAL_MEASUREMENT_TYPE_ECNO
573      */
574     @NonNull
575     public int[] getThresholds() {
576         return mThresholds.clone();
577     }
578 
579     /**
580      * Get the minimum number of thresholds allowed in each SignalThresholdInfo.
581      *
582      * @return the minimum number of thresholds allowed
583      */
584     public static int getMinimumNumberOfThresholdsAllowed() {
585         return MINIMUM_NUMBER_OF_THRESHOLDS_ALLOWED;
586     }
587 
588     /**
589      * Get the maximum number of threshold allowed in each SignalThresholdInfo.
590      *
591      * @return the maximum number of thresholds allowed
592      */
593     public static int getMaximumNumberOfThresholdsAllowed() {
594         return MAXIMUM_NUMBER_OF_THRESHOLDS_ALLOWED;
595     }
596 
597     @Override
598     public int describeContents() {
599         return 0;
600     }
601 
602     @Override
603     public void writeToParcel(@NonNull Parcel out, int flags) {
604         out.writeInt(mRan);
605         out.writeInt(mSignalMeasurementType);
606         out.writeInt(mHysteresisMs);
607         out.writeInt(mHysteresisDb);
608         out.writeIntArray(mThresholds);
609         out.writeBoolean(mIsEnabled);
610     }
611 
612     private SignalThresholdInfo(Parcel in) {
613         mRan = in.readInt();
614         mSignalMeasurementType = in.readInt();
615         mHysteresisMs = in.readInt();
616         mHysteresisDb = in.readInt();
617         mThresholds = in.createIntArray();
618         mIsEnabled = in.readBoolean();
619     }
620 
621     @Override
622     public boolean equals(Object o) {
623         if (this == o) return true;
624 
625         if (!(o instanceof SignalThresholdInfo)) {
626             return false;
627         }
628 
629         SignalThresholdInfo other = (SignalThresholdInfo) o;
630         return mRan == other.mRan
631                 && mSignalMeasurementType == other.mSignalMeasurementType
632                 && mHysteresisMs == other.mHysteresisMs
633                 && mHysteresisDb == other.mHysteresisDb
634                 && Arrays.equals(mThresholds, other.mThresholds)
635                 && mIsEnabled == other.mIsEnabled;
636     }
637 
638     @Override
639     public int hashCode() {
640         return Objects.hash(
641                 mRan,
642                 mSignalMeasurementType,
643                 mHysteresisMs,
644                 mHysteresisDb,
645                 Arrays.hashCode(mThresholds),
646                 mIsEnabled);
647     }
648 
649     @NonNull
650     public static final Parcelable.Creator<SignalThresholdInfo> CREATOR =
651             new Parcelable.Creator<SignalThresholdInfo>() {
652                 @Override
653                 public SignalThresholdInfo createFromParcel(Parcel in) {
654                     return new SignalThresholdInfo(in);
655                 }
656 
657                 @Override
658                 public SignalThresholdInfo[] newArray(int size) {
659                     return new SignalThresholdInfo[size];
660                 }
661             };
662 
663     @Override
664     public String toString() {
665         return new StringBuilder("SignalThresholdInfo{")
666                 .append("mRan=")
667                 .append(mRan)
668                 .append(" mSignalMeasurementType=")
669                 .append(mSignalMeasurementType)
670                 .append(" mHysteresisMs=")
671                 .append(mHysteresisMs)
672                 .append(" mHysteresisDb=")
673                 .append(mHysteresisDb)
674                 .append(" mThresholds=")
675                 .append(Arrays.toString(mThresholds))
676                 .append(" mIsEnabled=")
677                 .append(mIsEnabled)
678                 .append("}")
679                 .toString();
680     }
681 
682     /**
683      * Return true if signal measurement type is valid and the threshold value is in range.
684      */
685     private static boolean isValidThreshold(@SignalMeasurementType int type, int threshold) {
686         switch (type) {
687             case SIGNAL_MEASUREMENT_TYPE_RSSI:
688                 return threshold >= SIGNAL_RSSI_MIN_VALUE && threshold <= SIGNAL_RSSI_MAX_VALUE;
689             case SIGNAL_MEASUREMENT_TYPE_RSCP:
690                 return threshold >= SIGNAL_RSCP_MIN_VALUE && threshold <= SIGNAL_RSCP_MAX_VALUE;
691             case SIGNAL_MEASUREMENT_TYPE_RSRP:
692                 return threshold >= SIGNAL_RSRP_MIN_VALUE && threshold <= SIGNAL_RSRP_MAX_VALUE;
693             case SIGNAL_MEASUREMENT_TYPE_RSRQ:
694                 return threshold >= SIGNAL_RSRQ_MIN_VALUE && threshold <= SIGNAL_RSRQ_MAX_VALUE;
695             case SIGNAL_MEASUREMENT_TYPE_RSSNR:
696                 return threshold >= SIGNAL_RSSNR_MIN_VALUE && threshold <= SIGNAL_RSSNR_MAX_VALUE;
697             case SIGNAL_MEASUREMENT_TYPE_SSRSRP:
698                 return threshold >= SIGNAL_SSRSRP_MIN_VALUE && threshold <= SIGNAL_SSRSRP_MAX_VALUE;
699             case SIGNAL_MEASUREMENT_TYPE_SSRSRQ:
700                 return threshold >= SIGNAL_SSRSRQ_MIN_VALUE && threshold <= SIGNAL_SSRSRQ_MAX_VALUE;
701             case SIGNAL_MEASUREMENT_TYPE_SSSINR:
702                 return threshold >= SIGNAL_SSSINR_MIN_VALUE && threshold <= SIGNAL_SSSINR_MAX_VALUE;
703             case SIGNAL_MEASUREMENT_TYPE_ECNO:
704                 return threshold >= SIGNAL_ECNO_MIN_VALUE && threshold <= SIGNAL_ECNO_MAX_VALUE;
705             default:
706                 return false;
707         }
708     }
709 
710     /**
711      * Return true if the radio access type is allowed to set with the measurement type.
712      */
713     private static boolean isValidRanWithMeasurementType(
714             @AccessNetworkConstants.RadioAccessNetworkType int ran,
715             @SignalMeasurementType int type) {
716         switch (type) {
717             case SIGNAL_MEASUREMENT_TYPE_RSSI:
718                 return ran == AccessNetworkConstants.AccessNetworkType.GERAN
719                         || ran == AccessNetworkConstants.AccessNetworkType.CDMA2000;
720             case SIGNAL_MEASUREMENT_TYPE_RSCP:
721             case SIGNAL_MEASUREMENT_TYPE_ECNO:
722                 return ran == AccessNetworkConstants.AccessNetworkType.UTRAN;
723             case SIGNAL_MEASUREMENT_TYPE_RSRP:
724             case SIGNAL_MEASUREMENT_TYPE_RSRQ:
725             case SIGNAL_MEASUREMENT_TYPE_RSSNR:
726                 return ran == AccessNetworkConstants.AccessNetworkType.EUTRAN;
727             case SIGNAL_MEASUREMENT_TYPE_SSRSRP:
728             case SIGNAL_MEASUREMENT_TYPE_SSRSRQ:
729             case SIGNAL_MEASUREMENT_TYPE_SSSINR:
730                 return ran == AccessNetworkConstants.AccessNetworkType.NGRAN;
731             default:
732                 return false;
733         }
734     }
735 
736     private void validateRanWithMeasurementType(
737             @AccessNetworkConstants.RadioAccessNetworkType int ran,
738             @SignalMeasurementType int signalMeasurement) {
739         if (!isValidRanWithMeasurementType(ran, signalMeasurement)) {
740             throw new IllegalArgumentException(
741                     "invalid RAN: " + ran + " with signal measurement type: " + signalMeasurement);
742         }
743     }
744 
745     private void validateThresholdRange(
746             @SignalMeasurementType int signalMeasurement, int[] thresholds) {
747         for (int threshold : thresholds) {
748             if (!isValidThreshold(signalMeasurement, threshold)) {
749                 throw new IllegalArgumentException(
750                         "invalid signal measurement type: "
751                                 + signalMeasurement
752                                 + " with threshold: "
753                                 + threshold);
754             }
755         }
756     }
757 }
758