1 /*
2  * Copyright (C) 2012 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.os.Bundle;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.telephony.CarrierConfigManager;
23 import android.util.Log;
24 import android.content.res.Resources;
25 
26 import java.util.ArrayList;
27 import java.util.Arrays;
28 import java.util.Objects;
29 
30 /**
31  * Contains phone signal strength related information.
32  */
33 public class SignalStrength implements Parcelable {
34 
35     private static final String LOG_TAG = "SignalStrength";
36     private static final boolean DBG = false;
37 
38     /** @hide */
39     public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN
40             = TelephonyProtoEnums.SIGNAL_STRENGTH_NONE_OR_UNKNOWN; // = 0
41     /** @hide */
42     public static final int SIGNAL_STRENGTH_POOR
43             = TelephonyProtoEnums.SIGNAL_STRENGTH_POOR; // = 1
44     /** @hide */
45     public static final int SIGNAL_STRENGTH_MODERATE
46             = TelephonyProtoEnums.SIGNAL_STRENGTH_MODERATE; // = 2
47     /** @hide */
48     public static final int SIGNAL_STRENGTH_GOOD
49             = TelephonyProtoEnums.SIGNAL_STRENGTH_GOOD; // = 3
50     /** @hide */
51     public static final int SIGNAL_STRENGTH_GREAT
52             = TelephonyProtoEnums.SIGNAL_STRENGTH_GREAT; // = 4
53     /** @hide */
54     public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
55     /** @hide */
56     public static final String[] SIGNAL_STRENGTH_NAMES = {
57         "none", "poor", "moderate", "good", "great"
58     };
59 
60     /**
61      * Use Integer.MAX_VALUE because -1 is a valid value in signal strength.
62      * @hide
63      */
64     public static final int INVALID = Integer.MAX_VALUE;
65 
66     private static final int LTE_RSRP_THRESHOLDS_NUM = 4;
67     private static final int MAX_LTE_RSRP = -44;
68     private static final int MIN_LTE_RSRP = -140;
69 
70     private static final int WCDMA_RSCP_THRESHOLDS_NUM = 4;
71     private static final int MAX_WCDMA_RSCP = -24;
72     private static final int MIN_WCDMA_RSCP = -120;
73 
74     /* The type of signal measurement */
75     private static final String MEASUMENT_TYPE_RSCP = "rscp";
76 
77     /** Parameters reported by the Radio */
78     private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
79     private int mGsmBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
80     private int mCdmaDbm;   // This value is the RSSI value
81     private int mCdmaEcio;  // This value is the Ec/Io
82     private int mEvdoDbm;   // This value is the EVDO RSSI value
83     private int mEvdoEcio;  // This value is the EVDO Ec/Io
84     private int mEvdoSnr;   // Valid values are 0-8.  8 is the highest signal to noise ratio
85     private int mLteSignalStrength;
86     private int mLteRsrp;
87     private int mLteRsrq;
88     private int mLteRssnr;
89     private int mLteCqi;
90     private int mTdScdmaRscp; // Valid values are -24...-120dBm or INVALID if unknown
91     private int mWcdmaSignalStrength;
92     private int mWcdmaRscpAsu;  // the WCDMA RSCP in ASU as reported from the HAL
93     private int mWcdmaRscp;     // the WCDMA RSCP in dBm
94 
95     /** Parameters from the framework */
96     private int mLteRsrpBoost; // offset to be reduced from the rsrp threshold while calculating
97                                 // signal strength level
98     private boolean mIsGsm; // This value is set by the ServiceStateTracker
99                             // onSignalStrengthResult.
100     private boolean mUseOnlyRsrpForLteLevel; // Use only RSRP for the number of LTE signal bar.
101 
102     // The threshold of LTE RSRP for determining the display level of LTE signal bar. Note that the
103     // min and max are fixed at MIN_LTE_RSRP (-140) and MAX_LTE_RSRP (-44).
104     private int mLteRsrpThresholds[] = new int[LTE_RSRP_THRESHOLDS_NUM];
105 
106     // The type of default measurement for determining the display level of WCDMA signal bar.
107     private String mWcdmaDefaultSignalMeasurement;
108 
109     // The threshold of WCDMA RSCP for determining the display level of WCDMA signal bar. Note that
110     // the min and max are fixed at MIN_WCDMA_RSCP (-120) and MAX_WCDMA_RSCP (-24).
111     private int mWcdmaRscpThresholds[] = new int[WCDMA_RSCP_THRESHOLDS_NUM];
112 
113     /**
114      * Create a new SignalStrength from a intent notifier Bundle
115      *
116      * This method is used by PhoneStateIntentReceiver and maybe by
117      * external applications.
118      *
119      * @param m Bundle from intent notifier
120      * @return newly created SignalStrength
121      *
122      * @hide
123      */
newFromBundle(Bundle m)124     public static SignalStrength newFromBundle(Bundle m) {
125         SignalStrength ret;
126         ret = new SignalStrength();
127         ret.setFromNotifierBundle(m);
128         return ret;
129     }
130 
131     /**
132      * Empty constructor
133      *
134      * @hide
135      */
SignalStrength()136     public SignalStrength() {
137         this(true);
138     }
139 
140     /**
141      * This constructor is used to create SignalStrength with default
142      * values and set the gsmFlag with the value passed in the input
143      *
144      * @param gsmFlag true if Gsm Phone,false if Cdma phone
145      * @return newly created SignalStrength
146      * @hide
147      */
SignalStrength(boolean gsmFlag)148     public SignalStrength(boolean gsmFlag) {
149         mGsmSignalStrength = 99;
150         mGsmBitErrorRate = -1;
151         mCdmaDbm = -1;
152         mCdmaEcio = -1;
153         mEvdoDbm = -1;
154         mEvdoEcio = -1;
155         mEvdoSnr = -1;
156         mLteSignalStrength = 99;
157         mLteRsrp = INVALID;
158         mLteRsrq = INVALID;
159         mLteRssnr = INVALID;
160         mLteCqi = INVALID;
161         mTdScdmaRscp = INVALID;
162         mWcdmaSignalStrength = 99;
163         mWcdmaRscp = INVALID;
164         mWcdmaRscpAsu = 255;
165         mLteRsrpBoost = 0;
166         mIsGsm = gsmFlag;
167         mUseOnlyRsrpForLteLevel = false;
168         mWcdmaDefaultSignalMeasurement = "";
169         setLteRsrpThresholds(getDefaultLteRsrpThresholds());
170         setWcdmaRscpThresholds(getDefaultWcdmaRscpThresholds());
171     }
172 
173     /**
174      * Constructor with all fields present
175      *
176      * @hide
177      */
SignalStrength( int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscpAsu, int lteRsrpBoost, boolean gsmFlag, boolean lteLevelBaseOnRsrp, String wcdmaDefaultMeasurement)178     public SignalStrength(
179             int gsmSignalStrength, int gsmBitErrorRate,
180             int cdmaDbm, int cdmaEcio,
181             int evdoDbm, int evdoEcio, int evdoSnr,
182             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
183             int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscpAsu,
184             // values Added by config
185             int lteRsrpBoost, boolean gsmFlag, boolean lteLevelBaseOnRsrp,
186             String wcdmaDefaultMeasurement) {
187         mGsmSignalStrength = gsmSignalStrength;
188         mGsmBitErrorRate = gsmBitErrorRate;
189         mCdmaDbm = cdmaDbm;
190         mCdmaEcio = cdmaEcio;
191         mEvdoDbm = evdoDbm;
192         mEvdoEcio = evdoEcio;
193         mEvdoSnr = evdoSnr;
194         mLteSignalStrength = lteSignalStrength;
195         mLteRsrp = lteRsrp;
196         mLteRsrq = lteRsrq;
197         mLteRssnr = lteRssnr;
198         mLteCqi = lteCqi;
199         mTdScdmaRscp = INVALID;
200         mWcdmaSignalStrength = wcdmaSignalStrength;
201         mWcdmaRscpAsu = wcdmaRscpAsu;
202         mWcdmaRscp = wcdmaRscpAsu - 120;
203         mLteRsrpBoost = lteRsrpBoost;
204         mIsGsm = gsmFlag;
205         mUseOnlyRsrpForLteLevel = lteLevelBaseOnRsrp;
206         mWcdmaDefaultSignalMeasurement = wcdmaDefaultMeasurement;
207         setLteRsrpThresholds(getDefaultLteRsrpThresholds());
208         setWcdmaRscpThresholds(getDefaultWcdmaRscpThresholds());
209         if (DBG) log("initialize: " + toString());
210     }
211 
212     /**
213      * Constructor for only values provided by Radio HAL V1.0
214      *
215      * @hide
216      */
SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, int tdScdmaRscp)217     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
218             int cdmaDbm, int cdmaEcio,
219             int evdoDbm, int evdoEcio, int evdoSnr,
220             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
221             int tdScdmaRscp) {
222         this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
223                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
224                 lteRsrq, lteRssnr, lteCqi, tdScdmaRscp, 99, INVALID, 0, true, false, "");
225     }
226 
227     /**
228      * Constructor for only values provided by Radio HAL V1.2
229      *
230      * @hide
231      */
SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscp)232     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
233             int cdmaDbm, int cdmaEcio,
234             int evdoDbm, int evdoEcio, int evdoSnr,
235             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
236             int tdScdmaRscp, int wcdmaSignalStrength, int wcdmaRscp) {
237         this(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
238                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
239                 lteRsrq, lteRssnr, lteCqi, tdScdmaRscp, wcdmaSignalStrength, wcdmaRscp, 0, true,
240                 false, "");
241     }
242 
243     /**
244      * Copy constructors
245      *
246      * @param s Source SignalStrength
247      *
248      * @hide
249      */
SignalStrength(SignalStrength s)250     public SignalStrength(SignalStrength s) {
251         copyFrom(s);
252     }
253 
254     /**
255      * @hide
256      */
copyFrom(SignalStrength s)257     protected void copyFrom(SignalStrength s) {
258         mGsmSignalStrength = s.mGsmSignalStrength;
259         mGsmBitErrorRate = s.mGsmBitErrorRate;
260         mCdmaDbm = s.mCdmaDbm;
261         mCdmaEcio = s.mCdmaEcio;
262         mEvdoDbm = s.mEvdoDbm;
263         mEvdoEcio = s.mEvdoEcio;
264         mEvdoSnr = s.mEvdoSnr;
265         mLteSignalStrength = s.mLteSignalStrength;
266         mLteRsrp = s.mLteRsrp;
267         mLteRsrq = s.mLteRsrq;
268         mLteRssnr = s.mLteRssnr;
269         mLteCqi = s.mLteCqi;
270         mTdScdmaRscp = s.mTdScdmaRscp;
271         mWcdmaSignalStrength = s.mWcdmaSignalStrength;
272         mWcdmaRscpAsu = s.mWcdmaRscpAsu;
273         mWcdmaRscp = s.mWcdmaRscp;
274         mLteRsrpBoost = s.mLteRsrpBoost;
275         mIsGsm = s.mIsGsm;
276         mUseOnlyRsrpForLteLevel = s.mUseOnlyRsrpForLteLevel;
277         mWcdmaDefaultSignalMeasurement = s.mWcdmaDefaultSignalMeasurement;
278         setLteRsrpThresholds(s.mLteRsrpThresholds);
279         setWcdmaRscpThresholds(s.mWcdmaRscpThresholds);
280     }
281 
282     /**
283      * Construct a SignalStrength object from the given parcel.
284      *
285      * @hide
286      */
SignalStrength(Parcel in)287     public SignalStrength(Parcel in) {
288         if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
289 
290         mGsmSignalStrength = in.readInt();
291         mGsmBitErrorRate = in.readInt();
292         mCdmaDbm = in.readInt();
293         mCdmaEcio = in.readInt();
294         mEvdoDbm = in.readInt();
295         mEvdoEcio = in.readInt();
296         mEvdoSnr = in.readInt();
297         mLteSignalStrength = in.readInt();
298         mLteRsrp = in.readInt();
299         mLteRsrq = in.readInt();
300         mLteRssnr = in.readInt();
301         mLteCqi = in.readInt();
302         mTdScdmaRscp = in.readInt();
303         mWcdmaSignalStrength = in.readInt();
304         mWcdmaRscpAsu = in.readInt();
305         mWcdmaRscp = in.readInt();
306         mLteRsrpBoost = in.readInt();
307         mIsGsm = in.readBoolean();
308         mUseOnlyRsrpForLteLevel = in.readBoolean();
309         mWcdmaDefaultSignalMeasurement = in.readString();
310         in.readIntArray(mLteRsrpThresholds);
311         in.readIntArray(mWcdmaRscpThresholds);
312     }
313 
314     /**
315      * {@link Parcelable#writeToParcel}
316      */
writeToParcel(Parcel out, int flags)317     public void writeToParcel(Parcel out, int flags) {
318         out.writeInt(mGsmSignalStrength);
319         out.writeInt(mGsmBitErrorRate);
320         out.writeInt(mCdmaDbm);
321         out.writeInt(mCdmaEcio);
322         out.writeInt(mEvdoDbm);
323         out.writeInt(mEvdoEcio);
324         out.writeInt(mEvdoSnr);
325         out.writeInt(mLteSignalStrength);
326         out.writeInt(mLteRsrp);
327         out.writeInt(mLteRsrq);
328         out.writeInt(mLteRssnr);
329         out.writeInt(mLteCqi);
330         out.writeInt(mTdScdmaRscp);
331         out.writeInt(mWcdmaSignalStrength);
332         out.writeInt(mWcdmaRscpAsu);
333         out.writeInt(mWcdmaRscp);
334         out.writeInt(mLteRsrpBoost);
335         out.writeBoolean(mIsGsm);
336         out.writeBoolean(mUseOnlyRsrpForLteLevel);
337         out.writeString(mWcdmaDefaultSignalMeasurement);
338         out.writeIntArray(mLteRsrpThresholds);
339         out.writeIntArray(mWcdmaRscpThresholds);
340     }
341 
342     /**
343      * {@link Parcelable#describeContents}
344      */
describeContents()345     public int describeContents() {
346         return 0;
347     }
348 
349     /**
350      * {@link Parcelable.Creator}
351      *
352      * @hide
353      */
354     public static final Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() {
355         public SignalStrength createFromParcel(Parcel in) {
356             return new SignalStrength(in);
357         }
358 
359         public SignalStrength[] newArray(int size) {
360             return new SignalStrength[size];
361         }
362     };
363 
364     /**
365      * Validate the individual signal strength fields as per the range
366      * specified in ril.h
367      * Set to invalid any field that is not in the valid range
368      * Cdma, evdo, lte rsrp & rsrq values are sign converted
369      * when received from ril interface
370      *
371      * @return
372      *      Valid values for all signalstrength fields
373      * @hide
374      */
validateInput()375     public void validateInput() {
376         if (DBG) log("Signal before validate=" + this);
377         // TS 27.007 8.5
378         mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
379         mWcdmaSignalStrength = (mWcdmaSignalStrength >= 0) ? mWcdmaSignalStrength : 99;
380         mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
381         // BER no change;
382 
383         // WCDMA RSCP valid values are -120 through -24 as defined in TS 27.007 8.69
384         // but are reported in ASU which is 0 through 96, so we do the conversion here
385         mWcdmaRscpAsu =
386                 ((mWcdmaRscpAsu - 120 >= MIN_WCDMA_RSCP) && (mWcdmaRscpAsu - 120 <= MAX_WCDMA_RSCP))
387                 ? mWcdmaRscpAsu : 255;
388         mWcdmaRscp = ((mWcdmaRscp >= MIN_WCDMA_RSCP) && (mWcdmaRscp <= MAX_WCDMA_RSCP))
389                 ? mWcdmaRscp : INVALID;
390 
391         mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
392         mCdmaEcio = (mCdmaEcio >= 0) ? -mCdmaEcio : -160;
393 
394         mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
395         mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -160;
396         mEvdoSnr = ((mEvdoSnr >= 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
397 
398         // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
399         mLteRsrp = ((-mLteRsrp >= MIN_LTE_RSRP) && (-mLteRsrp <= MAX_LTE_RSRP)) ? -mLteRsrp
400                                 : SignalStrength.INVALID;
401         mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
402         mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
403                 : SignalStrength.INVALID;
404 
405         mTdScdmaRscp = ((mTdScdmaRscp >= 0) && (mTdScdmaRscp <= 96))
406                 ? (mTdScdmaRscp - 120) : SignalStrength.INVALID;
407         // Cqi no change
408         if (DBG) log("Signal after validate=" + this);
409     }
410 
411     /**
412      * Fix {@link #mIsGsm} based on the signal strength data.
413      *
414      * @hide
415      */
fixType()416     public void fixType() {
417         mIsGsm = getCdmaRelatedSignalStrength() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
418     }
419 
420     /**
421      * @param true - Gsm, Lte phones
422      *        false - Cdma phones
423      *
424      * Used by voice phone to set the mIsGsm
425      *        flag
426      * @hide
427      */
setGsm(boolean gsmFlag)428     public void setGsm(boolean gsmFlag) {
429         mIsGsm = gsmFlag;
430     }
431 
432     /**
433      * @param useOnlyRsrpForLteLevel true if it uses only RSRP for the number of LTE signal bar,
434      * otherwise false.
435      *
436      * Used by phone to use only RSRP or not for the number of LTE signal bar.
437      * @hide
438      */
setUseOnlyRsrpForLteLevel(boolean useOnlyRsrpForLteLevel)439     public void setUseOnlyRsrpForLteLevel(boolean useOnlyRsrpForLteLevel) {
440         mUseOnlyRsrpForLteLevel = useOnlyRsrpForLteLevel;
441     }
442 
443     /**
444      * @param defaultMeasurement sets the type of WCDMA default signal measurement
445      *
446      * Used by phone to determine default measurement type for calculation WCDMA signal level.
447      * @hide
448      */
setWcdmaDefaultSignalMeasurement(String defaultMeasurement)449     public void setWcdmaDefaultSignalMeasurement(String defaultMeasurement) {
450         mWcdmaDefaultSignalMeasurement = defaultMeasurement;
451     }
452 
453     /**
454      * @param lteRsrpBoost - signal strength offset
455      *
456      * Used by phone to set the lte signal strength offset which will be
457      * reduced from rsrp threshold while calculating signal strength level
458      *
459      * @hide
460      */
setLteRsrpBoost(int lteRsrpBoost)461     public void setLteRsrpBoost(int lteRsrpBoost) {
462         mLteRsrpBoost = lteRsrpBoost;
463     }
464 
465     /**
466      * Sets the threshold array for determining the display level of LTE signal bar.
467      *
468      * @param lteRsrpThresholds int array for determining the display level.
469      *
470      * @hide
471      */
setLteRsrpThresholds(int[] lteRsrpThresholds)472     public void setLteRsrpThresholds(int[] lteRsrpThresholds) {
473         if ((lteRsrpThresholds == null)
474                 || (lteRsrpThresholds.length != LTE_RSRP_THRESHOLDS_NUM)) {
475             Log.wtf(LOG_TAG, "setLteRsrpThresholds - lteRsrpThresholds is invalid.");
476             return;
477         }
478         System.arraycopy(lteRsrpThresholds, 0, mLteRsrpThresholds, 0, LTE_RSRP_THRESHOLDS_NUM);
479     }
480 
481     /**
482      * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS
483      * 27.007 8.5
484      */
getGsmSignalStrength()485     public int getGsmSignalStrength() {
486         return this.mGsmSignalStrength;
487     }
488 
489     /**
490      * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5
491      */
getGsmBitErrorRate()492     public int getGsmBitErrorRate() {
493         return this.mGsmBitErrorRate;
494     }
495 
496     /**
497      * Sets the threshold array for determining the display level of WCDMA signal bar.
498      *
499      * @param wcdmaRscpThresholds int array for determining the display level.
500      *
501      * @hide
502      */
setWcdmaRscpThresholds(int[] wcdmaRscpThresholds)503     public void setWcdmaRscpThresholds(int[] wcdmaRscpThresholds) {
504         if ((wcdmaRscpThresholds == null)
505                 || (wcdmaRscpThresholds.length != WCDMA_RSCP_THRESHOLDS_NUM)) {
506             Log.wtf(LOG_TAG, "setWcdmaRscpThresholds - wcdmaRscpThresholds is invalid.");
507             return;
508         }
509         System.arraycopy(wcdmaRscpThresholds, 0, mWcdmaRscpThresholds, 0,
510                 WCDMA_RSCP_THRESHOLDS_NUM);
511     }
512 
513     /**
514      * Get the CDMA RSSI value in dBm
515      */
getCdmaDbm()516     public int getCdmaDbm() {
517         return this.mCdmaDbm;
518     }
519 
520     /**
521      * Get the CDMA Ec/Io value in dB*10
522      */
getCdmaEcio()523     public int getCdmaEcio() {
524         return this.mCdmaEcio;
525     }
526 
527     /**
528      * Get the EVDO RSSI value in dBm
529      */
getEvdoDbm()530     public int getEvdoDbm() {
531         return this.mEvdoDbm;
532     }
533 
534     /**
535      * Get the EVDO Ec/Io value in dB*10
536      */
getEvdoEcio()537     public int getEvdoEcio() {
538         return this.mEvdoEcio;
539     }
540 
541     /**
542      * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
543      */
getEvdoSnr()544     public int getEvdoSnr() {
545         return this.mEvdoSnr;
546     }
547 
548     /** @hide */
getLteSignalStrength()549     public int getLteSignalStrength() {
550         return mLteSignalStrength;
551     }
552 
553     /** @hide */
getLteRsrp()554     public int getLteRsrp() {
555         return mLteRsrp;
556     }
557 
558     /** @hide */
getLteRsrq()559     public int getLteRsrq() {
560         return mLteRsrq;
561     }
562 
563     /** @hide */
getLteRssnr()564     public int getLteRssnr() {
565         return mLteRssnr;
566     }
567 
568     /** @hide */
getLteCqi()569     public int getLteCqi() {
570         return mLteCqi;
571     }
572 
573     /** @hide */
getLteRsrpBoost()574     public int getLteRsrpBoost() {
575         return mLteRsrpBoost;
576     }
577 
578     /**
579      * Retrieve an abstract level value for the overall signal strength.
580      *
581      * @return a single integer from 0 to 4 representing the general signal quality.
582      *     This may take into account many different radio technology inputs.
583      *     0 represents very poor signal strength
584      *     while 4 represents a very strong signal strength.
585      */
getLevel()586     public int getLevel() {
587         int level = mIsGsm ? getGsmRelatedSignalStrength() : getCdmaRelatedSignalStrength();
588         if (DBG) log("getLevel=" + level);
589         return level;
590     }
591 
592     /**
593      * Get the signal level as an asu value between 0..31, 99 is unknown
594      *
595      * @hide
596      */
getAsuLevel()597     public int getAsuLevel() {
598         int asuLevel = 0;
599         if (mIsGsm) {
600             if (mLteRsrp != SignalStrength.INVALID) {
601                 asuLevel = getLteAsuLevel();
602             } else if (mTdScdmaRscp != SignalStrength.INVALID) {
603                 asuLevel = getTdScdmaAsuLevel();
604             } else if (mWcdmaRscp != SignalStrength.INVALID) {
605                 asuLevel = getWcdmaAsuLevel();
606             } else {
607                 asuLevel = getGsmAsuLevel();
608             }
609         } else {
610             int cdmaAsuLevel = getCdmaAsuLevel();
611             int evdoAsuLevel = getEvdoAsuLevel();
612             if (evdoAsuLevel == 0) {
613                 /* We don't know evdo use, cdma */
614                 asuLevel = cdmaAsuLevel;
615             } else if (cdmaAsuLevel == 0) {
616                 /* We don't know cdma use, evdo */
617                 asuLevel = evdoAsuLevel;
618             } else {
619                 /* We know both, use the lowest level */
620                 asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel;
621             }
622         }
623         if (DBG) log("getAsuLevel=" + asuLevel);
624         return asuLevel;
625     }
626 
627     /**
628      * Get the signal strength as dBm
629      *
630      * @hide
631      */
632     public int getDbm() {
633         int dBm = INVALID;
634 
635         if(isGsm()) {
636             dBm = getLteDbm();
637             if (dBm == INVALID) {
638                 if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
639                     if (getWcdmaDbm() == INVALID) {
640                         dBm = getGsmDbm();
641                     } else {
642                         dBm = getWcdmaDbm();
643                     }
644                 } else {
645                     dBm = getTdScdmaDbm();
646                 }
647             }
648         } else {
649             int cdmaDbm = getCdmaDbm();
650             int evdoDbm = getEvdoDbm();
651 
652             return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm
653                     : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm));
654         }
655         if (DBG) log("getDbm=" + dBm);
656         return dBm;
657     }
658 
659     /**
660      * Get Gsm signal strength as dBm
661      *
662      * @hide
663      */
664     public int getGsmDbm() {
665         int dBm;
666 
667         int gsmSignalStrength = getGsmSignalStrength();
668         int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
669         if (asu != -1) {
670             dBm = -113 + (2 * asu);
671         } else {
672             dBm = -1;
673         }
674         if (DBG) log("getGsmDbm=" + dBm);
675         return dBm;
676     }
677 
678     /**
679      * Get gsm as level 0..4
680      *
681      * @hide
682      */
683     public int getGsmLevel() {
684         int level;
685 
686         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
687         // asu = 0 (-113dB or less) is very weak
688         // signal, its better to show 0 bars to the user in such cases.
689         // asu = 99 is a special case, where the signal strength is unknown.
690         int asu = getGsmSignalStrength();
691         if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
692         else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
693         else if (asu >= 8)  level = SIGNAL_STRENGTH_GOOD;
694         else if (asu >= 5)  level = SIGNAL_STRENGTH_MODERATE;
695         else level = SIGNAL_STRENGTH_POOR;
696         if (DBG) log("getGsmLevel=" + level);
697         return level;
698     }
699 
700     /**
701      * Get the gsm signal level as an asu value between 0..31, 99 is unknown
702      *
703      * @hide
704      */
getGsmAsuLevel()705     public int getGsmAsuLevel() {
706         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
707         // asu = 0 (-113dB or less) is very weak
708         // signal, its better to show 0 bars to the user in such cases.
709         // asu = 99 is a special case, where the signal strength is unknown.
710         int level = getGsmSignalStrength();
711         if (DBG) log("getGsmAsuLevel=" + level);
712         return level;
713     }
714 
715     /**
716      * Get cdma as level 0..4
717      *
718      * @hide
719      */
getCdmaLevel()720     public int getCdmaLevel() {
721         final int cdmaDbm = getCdmaDbm();
722         final int cdmaEcio = getCdmaEcio();
723         int levelDbm;
724         int levelEcio;
725 
726         if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
727         else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
728         else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
729         else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
730         else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
731 
732         // Ec/Io are in dB*10
733         if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
734         else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
735         else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
736         else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
737         else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
738 
739         int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
740         if (DBG) log("getCdmaLevel=" + level);
741         return level;
742     }
743 
744     /**
745      * Get the cdma signal level as an asu value between 0..31, 99 is unknown
746      *
747      * @hide
748      */
getCdmaAsuLevel()749     public int getCdmaAsuLevel() {
750         final int cdmaDbm = getCdmaDbm();
751         final int cdmaEcio = getCdmaEcio();
752         int cdmaAsuLevel;
753         int ecioAsuLevel;
754 
755         if (cdmaDbm >= -75) cdmaAsuLevel = 16;
756         else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
757         else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
758         else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
759         else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
760         else cdmaAsuLevel = 99;
761 
762         // Ec/Io are in dB*10
763         if (cdmaEcio >= -90) ecioAsuLevel = 16;
764         else if (cdmaEcio >= -100) ecioAsuLevel = 8;
765         else if (cdmaEcio >= -115) ecioAsuLevel = 4;
766         else if (cdmaEcio >= -130) ecioAsuLevel = 2;
767         else if (cdmaEcio >= -150) ecioAsuLevel = 1;
768         else ecioAsuLevel = 99;
769 
770         int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
771         if (DBG) log("getCdmaAsuLevel=" + level);
772         return level;
773     }
774 
775     /**
776      * Get Evdo as level 0..4
777      *
778      * @hide
779      */
getEvdoLevel()780     public int getEvdoLevel() {
781         int evdoDbm = getEvdoDbm();
782         int evdoSnr = getEvdoSnr();
783         int levelEvdoDbm;
784         int levelEvdoSnr;
785 
786         if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
787         else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
788         else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
789         else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
790         else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
791 
792         if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
793         else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
794         else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
795         else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
796         else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
797 
798         int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
799         if (DBG) log("getEvdoLevel=" + level);
800         return level;
801     }
802 
803     /**
804      * Get the evdo signal level as an asu value between 0..31, 99 is unknown
805      *
806      * @hide
807      */
getEvdoAsuLevel()808     public int getEvdoAsuLevel() {
809         int evdoDbm = getEvdoDbm();
810         int evdoSnr = getEvdoSnr();
811         int levelEvdoDbm;
812         int levelEvdoSnr;
813 
814         if (evdoDbm >= -65) levelEvdoDbm = 16;
815         else if (evdoDbm >= -75) levelEvdoDbm = 8;
816         else if (evdoDbm >= -85) levelEvdoDbm = 4;
817         else if (evdoDbm >= -95) levelEvdoDbm = 2;
818         else if (evdoDbm >= -105) levelEvdoDbm = 1;
819         else levelEvdoDbm = 99;
820 
821         if (evdoSnr >= 7) levelEvdoSnr = 16;
822         else if (evdoSnr >= 6) levelEvdoSnr = 8;
823         else if (evdoSnr >= 5) levelEvdoSnr = 4;
824         else if (evdoSnr >= 3) levelEvdoSnr = 2;
825         else if (evdoSnr >= 1) levelEvdoSnr = 1;
826         else levelEvdoSnr = 99;
827 
828         int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
829         if (DBG) log("getEvdoAsuLevel=" + level);
830         return level;
831     }
832 
833     /**
834      * Get LTE as dBm
835      *
836      * @hide
837      */
getLteDbm()838     public int getLteDbm() {
839         return mLteRsrp;
840     }
841 
842     /**
843      * Get LTE as level 0..4
844      *
845      * @hide
846      */
getLteLevel()847     public int getLteLevel() {
848         /*
849          * TS 36.214 Physical Layer Section 5.1.3
850          * TS 36.331 RRC
851          *
852          * RSSI = received signal + noise
853          * RSRP = reference signal dBm
854          * RSRQ = quality of signal dB = Number of Resource blocks*RSRP/RSSI
855          * SNR = gain = signal/noise ratio = -10log P1/P2 dB
856          */
857         int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
858 
859         if (mLteRsrp > MAX_LTE_RSRP || mLteRsrp < MIN_LTE_RSRP) {
860             if (mLteRsrp != INVALID) {
861                 Log.wtf(LOG_TAG, "getLteLevel - invalid lte rsrp: mLteRsrp=" + mLteRsrp);
862             }
863         } else if (mLteRsrp >= (mLteRsrpThresholds[3] - mLteRsrpBoost)) {
864             rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
865         } else if (mLteRsrp >= (mLteRsrpThresholds[2] - mLteRsrpBoost)) {
866             rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
867         } else if (mLteRsrp >= (mLteRsrpThresholds[1] - mLteRsrpBoost)) {
868             rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
869         } else if (mLteRsrp >= (mLteRsrpThresholds[0] - mLteRsrpBoost)) {
870             rsrpIconLevel = SIGNAL_STRENGTH_POOR;
871         } else {
872             rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
873         }
874 
875         if (useOnlyRsrpForLteLevel()) {
876             log("getLTELevel - rsrp = " + rsrpIconLevel);
877             if (rsrpIconLevel != -1) {
878                 return rsrpIconLevel;
879             }
880         }
881 
882         /*
883          * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
884          * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
885          * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
886          * Icon Only
887          */
888         if (mLteRssnr > 300) snrIconLevel = -1;
889         else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
890         else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
891         else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
892         else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
893         else if (mLteRssnr >= -200)
894             snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
895 
896         if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
897                 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel
898                 + " lteRsrpBoost:" + mLteRsrpBoost);
899 
900         /* Choose a measurement type to use for notification */
901         if (snrIconLevel != -1 && rsrpIconLevel != -1) {
902             /*
903              * The number of bars displayed shall be the smaller of the bars
904              * associated with LTE RSRP and the bars associated with the LTE
905              * RS_SNR
906              */
907             return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
908         }
909 
910         if (snrIconLevel != -1) return snrIconLevel;
911 
912         if (rsrpIconLevel != -1) return rsrpIconLevel;
913 
914         /* Valid values are (0-63, 99) as defined in TS 36.331 */
915         // TODO the range here is probably supposed to be (0..31, 99). It's unclear if anyone relies
916         // on the current incorrect range check, so this will be fixed in a future release with more
917         // soak time
918         if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
919         else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
920         else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
921         else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
922         else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
923 
924         if (DBG) log("getLteLevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
925                 + rssiIconLevel);
926         return rssiIconLevel;
927 
928     }
929 
930     /**
931      * Get the LTE signal level as an asu value between 0..97, 99 is unknown
932      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
933      *
934      * @hide
935      */
getLteAsuLevel()936     public int getLteAsuLevel() {
937         int lteAsuLevel = 99;
938         int lteDbm = getLteDbm();
939         /*
940          * 3GPP 27.007 (Ver 10.3.0) Sec 8.69
941          * 0   -140 dBm or less
942          * 1   -139 dBm
943          * 2...96  -138... -44 dBm
944          * 97  -43 dBm or greater
945          * 255 not known or not detectable
946          */
947         /*
948          * validateInput will always give a valid range between -140 t0 -44 as
949          * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255
950          * and not 97 or 0
951          */
952         if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255;
953         else lteAsuLevel = lteDbm + 140;
954         if (DBG) log("Lte Asu level: "+lteAsuLevel);
955         return lteAsuLevel;
956     }
957 
958     /**
959      * @return true if this is for GSM
960      */
isGsm()961     public boolean isGsm() {
962         return this.mIsGsm;
963     }
964 
965     /**
966      * @return true if it uses only RSRP for the number of LTE signal bar, otherwise false.
967      *
968      * @hide
969      */
useOnlyRsrpForLteLevel()970     public boolean useOnlyRsrpForLteLevel() {
971         return this.mUseOnlyRsrpForLteLevel;
972     }
973 
974     /**
975      * @return get TD_SCDMA dbm
976      *
977      * @hide
978      */
getTdScdmaDbm()979     public int getTdScdmaDbm() {
980         return this.mTdScdmaRscp;
981     }
982 
983     /**
984      * Get TD-SCDMA as level 0..4
985      * Range : 25 to 120
986      * INT_MAX: 0x7FFFFFFF denotes invalid value
987      * Reference: 3GPP TS 25.123, section 9.1.1.1
988      *
989      * @hide
990      */
getTdScdmaLevel()991     public int getTdScdmaLevel() {
992         final int tdScdmaDbm = getTdScdmaDbm();
993         int level;
994 
995         if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID))
996                 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
997         else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT;
998         else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD;
999         else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE;
1000         else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR;
1001         else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1002 
1003         if (DBG) log("getTdScdmaLevel = " + level);
1004         return level;
1005      }
1006 
1007     /**
1008      * Get the TD-SCDMA signal level as an asu value.
1009      *
1010      * @hide
1011      */
getTdScdmaAsuLevel()1012     public int getTdScdmaAsuLevel() {
1013         final int tdScdmaDbm = getTdScdmaDbm();
1014         int tdScdmaAsuLevel;
1015 
1016         if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255;
1017         else tdScdmaAsuLevel = tdScdmaDbm + 120;
1018         if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel);
1019         return tdScdmaAsuLevel;
1020     }
1021 
1022     /**
1023      * Gets WCDMA RSCP as a dbm value between -120 and -24, as defined in TS 27.007 8.69.
1024      *
1025      * @hide
1026      */
getWcdmaRscp()1027     public int getWcdmaRscp() {
1028         return mWcdmaRscp;
1029     }
1030 
1031     /**
1032      * Get the WCDMA signal level as an ASU value between 0-96, 255 is unknown
1033      *
1034      * @hide
1035      */
getWcdmaAsuLevel()1036     public int getWcdmaAsuLevel() {
1037         /*
1038          * 3GPP 27.007 (Ver 10.3.0) Sec 8.69
1039          * 0      -120 dBm or less
1040          * 1      -119 dBm
1041          * 2...95 -118... -25 dBm
1042          * 96     -24 dBm or greater
1043          * 255    not known or not detectable
1044          */
1045         final int wcdmaDbm = getWcdmaDbm();
1046         int wcdmaAsuLevel = 255;
1047         // validateInput will always give a valid range between -120 to -24 as per ril.h. so RSCP
1048         // outside range is already set to INVALID
1049         if (wcdmaDbm == SignalStrength.INVALID) wcdmaAsuLevel =  255;
1050         else wcdmaAsuLevel = wcdmaDbm + 120;
1051         if (DBG) log("Wcdma Asu level: " + wcdmaAsuLevel);
1052         return wcdmaAsuLevel;
1053     }
1054 
1055     /**
1056      * Gets WCDMA signal strength as a dbm value between -120 and -24, as defined in TS 27.007 8.69.
1057      *
1058      * @hide
1059      */
getWcdmaDbm()1060     public int getWcdmaDbm() {
1061         return mWcdmaRscp;
1062     }
1063 
1064     /**
1065      * Get WCDMA as level 0..4
1066      *
1067      * @hide
1068      */
getWcdmaLevel()1069     public int getWcdmaLevel() {
1070         int level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
1071 
1072         if (mWcdmaDefaultSignalMeasurement == null) {
1073             Log.wtf(LOG_TAG, "getWcdmaLevel - WCDMA default signal measurement is invalid.");
1074             return level;
1075         }
1076 
1077         switch (mWcdmaDefaultSignalMeasurement) {
1078             case MEASUMENT_TYPE_RSCP:
1079                 // RSCP valid values are (-120 through -24) as defined in TS 27.007 8.69
1080                 if (mWcdmaRscp < MIN_WCDMA_RSCP || mWcdmaRscp > MAX_WCDMA_RSCP) {
1081                     if (mWcdmaRscp != INVALID) {
1082                         Log.wtf(LOG_TAG, "getWcdmaLevel - invalid WCDMA RSCP: mWcdmaRscp="
1083                                 + mWcdmaRscp);
1084                     }
1085                 } else if (mWcdmaRscp >= mWcdmaRscpThresholds[3]) {
1086                     level = SIGNAL_STRENGTH_GREAT;
1087                 } else if (mWcdmaRscp >= mWcdmaRscpThresholds[2]) {
1088                     level = SIGNAL_STRENGTH_GOOD;
1089                 } else if (mWcdmaRscp >= mWcdmaRscpThresholds[1]) {
1090                     level = SIGNAL_STRENGTH_MODERATE;
1091                 } else if (mWcdmaRscp >= mWcdmaRscpThresholds[0]) {
1092                     level = SIGNAL_STRENGTH_POOR;
1093                 }
1094                 if (DBG) log("getWcdmaLevel=" + level + " WcdmaRscp=" + mWcdmaRscp);
1095                 break;
1096 
1097             default:
1098                 // RSSI valid values are (0..31) as defined in TS 27.007 8.5
1099                 if (mWcdmaSignalStrength < 0 || mWcdmaSignalStrength > 31) {
1100                     if (mWcdmaSignalStrength != 99) {
1101                         Log.wtf(LOG_TAG, "getWcdmaLevel - invalid WCDMA RSSI: mWcdmaSignalStrength="
1102                                 + mWcdmaSignalStrength);
1103                     }
1104                 } else if (mWcdmaSignalStrength >= 18) {
1105                     level = SIGNAL_STRENGTH_GREAT;
1106                 } else if (mWcdmaSignalStrength >= 13) {
1107                     level = SIGNAL_STRENGTH_GOOD;
1108                 } else if (mWcdmaSignalStrength >= 8) {
1109                     level = SIGNAL_STRENGTH_MODERATE;
1110                 } else if (mWcdmaSignalStrength >= 3) {
1111                     level = SIGNAL_STRENGTH_POOR;
1112                 }
1113                 if (DBG) log("getWcdmaLevel=" + level + " WcdmaSignalStrength=" +
1114                         mWcdmaSignalStrength);
1115                 break;
1116 
1117         }
1118         return level;
1119     }
1120 
1121    /**
1122      * @return hash code
1123      */
1124     @Override
hashCode()1125     public int hashCode() {
1126         int primeNum = 31;
1127         return ((mGsmSignalStrength * primeNum)
1128                 + (mGsmBitErrorRate * primeNum)
1129                 + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum)
1130                 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
1131                 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
1132                 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
1133                 + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum)
1134                 + (mWcdmaSignalStrength * primeNum) + (mWcdmaRscpAsu * primeNum)
1135                 + (mWcdmaRscp * primeNum) + (mIsGsm ? 1 : 0) + (mUseOnlyRsrpForLteLevel ? 1 : 0)
1136                 + (Objects.hashCode(mWcdmaDefaultSignalMeasurement))
1137                 + (Arrays.hashCode(mLteRsrpThresholds)) + (Arrays.hashCode(mWcdmaRscpThresholds)));
1138     }
1139 
1140     /**
1141      * @return true if the signal strengths are the same
1142      */
1143     @Override
equals(Object o)1144     public boolean equals (Object o) {
1145         SignalStrength s;
1146 
1147         try {
1148             s = (SignalStrength) o;
1149         } catch (ClassCastException ex) {
1150             return false;
1151         }
1152 
1153         if (o == null) {
1154             return false;
1155         }
1156 
1157         return (mGsmSignalStrength == s.mGsmSignalStrength
1158                 && mGsmBitErrorRate == s.mGsmBitErrorRate
1159                 && mCdmaDbm == s.mCdmaDbm
1160                 && mCdmaEcio == s.mCdmaEcio
1161                 && mEvdoDbm == s.mEvdoDbm
1162                 && mEvdoEcio == s.mEvdoEcio
1163                 && mEvdoSnr == s.mEvdoSnr
1164                 && mLteSignalStrength == s.mLteSignalStrength
1165                 && mLteRsrp == s.mLteRsrp
1166                 && mLteRsrq == s.mLteRsrq
1167                 && mLteRssnr == s.mLteRssnr
1168                 && mLteCqi == s.mLteCqi
1169                 && mLteRsrpBoost == s.mLteRsrpBoost
1170                 && mTdScdmaRscp == s.mTdScdmaRscp
1171                 && mWcdmaSignalStrength == s.mWcdmaSignalStrength
1172                 && mWcdmaRscpAsu == s.mWcdmaRscpAsu
1173                 && mWcdmaRscp == s.mWcdmaRscp
1174                 && mIsGsm == s.mIsGsm
1175                 && mUseOnlyRsrpForLteLevel == s.mUseOnlyRsrpForLteLevel
1176                 && Objects.equals(mWcdmaDefaultSignalMeasurement, s.mWcdmaDefaultSignalMeasurement)
1177                 && Arrays.equals(mLteRsrpThresholds, s.mLteRsrpThresholds)
1178                 && Arrays.equals(mWcdmaRscpThresholds, s.mWcdmaRscpThresholds));
1179     }
1180 
1181     /**
1182      * @return string representation.
1183      */
1184     @Override
toString()1185     public String toString() {
1186         return ("SignalStrength:"
1187                 + " " + mGsmSignalStrength
1188                 + " " + mGsmBitErrorRate
1189                 + " " + mCdmaDbm
1190                 + " " + mCdmaEcio
1191                 + " " + mEvdoDbm
1192                 + " " + mEvdoEcio
1193                 + " " + mEvdoSnr
1194                 + " " + mLteSignalStrength
1195                 + " " + mLteRsrp
1196                 + " " + mLteRsrq
1197                 + " " + mLteRssnr
1198                 + " " + mLteCqi
1199                 + " " + mLteRsrpBoost
1200                 + " " + mTdScdmaRscp
1201                 + " " + mWcdmaSignalStrength
1202                 + " " + mWcdmaRscpAsu
1203                 + " " + mWcdmaRscp
1204                 + " " + (mIsGsm ? "gsm|lte" : "cdma")
1205                 + " " + (mUseOnlyRsrpForLteLevel ? "use_only_rsrp_for_lte_level" :
1206                          "use_rsrp_and_rssnr_for_lte_level")
1207                 + " " + mWcdmaDefaultSignalMeasurement
1208                 + " " + (Arrays.toString(mLteRsrpThresholds))
1209                 + " " + (Arrays.toString(mWcdmaRscpThresholds)));
1210     }
1211 
1212     /** Returns the signal strength related to GSM. */
getGsmRelatedSignalStrength()1213     private int getGsmRelatedSignalStrength() {
1214         int level = getLteLevel();
1215         if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
1216             level = getTdScdmaLevel();
1217             if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
1218                 level = getWcdmaLevel();
1219                 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
1220                     level = getGsmLevel();
1221                 }
1222             }
1223         }
1224         return level;
1225     }
1226 
1227     /** Returns the signal strength related to CDMA. */
getCdmaRelatedSignalStrength()1228     private int getCdmaRelatedSignalStrength() {
1229         int level;
1230         int cdmaLevel = getCdmaLevel();
1231         int evdoLevel = getEvdoLevel();
1232         if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
1233             /* We don't know evdo, use cdma */
1234             level = cdmaLevel;
1235         } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
1236             /* We don't know cdma, use evdo */
1237             level = evdoLevel;
1238         } else {
1239             /* We know both, use the lowest level */
1240             level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
1241         }
1242         return level;
1243     }
1244 
1245     /**
1246      * Set SignalStrength based on intent notifier map
1247      *
1248      * @param m intent notifier map
1249      * @hide
1250      */
1251     private void setFromNotifierBundle(Bundle m) {
1252         mGsmSignalStrength = m.getInt("GsmSignalStrength");
1253         mGsmBitErrorRate = m.getInt("GsmBitErrorRate");
1254         mCdmaDbm = m.getInt("CdmaDbm");
1255         mCdmaEcio = m.getInt("CdmaEcio");
1256         mEvdoDbm = m.getInt("EvdoDbm");
1257         mEvdoEcio = m.getInt("EvdoEcio");
1258         mEvdoSnr = m.getInt("EvdoSnr");
1259         mLteSignalStrength = m.getInt("LteSignalStrength");
1260         mLteRsrp = m.getInt("LteRsrp");
1261         mLteRsrq = m.getInt("LteRsrq");
1262         mLteRssnr = m.getInt("LteRssnr");
1263         mLteCqi = m.getInt("LteCqi");
1264         mLteRsrpBoost = m.getInt("LteRsrpBoost");
1265         mTdScdmaRscp = m.getInt("TdScdma");
1266         mWcdmaSignalStrength = m.getInt("WcdmaSignalStrength");
1267         mWcdmaRscpAsu = m.getInt("WcdmaRscpAsu");
1268         mWcdmaRscp = m.getInt("WcdmaRscp");
1269         mIsGsm = m.getBoolean("IsGsm");
1270         mUseOnlyRsrpForLteLevel = m.getBoolean("UseOnlyRsrpForLteLevel");
1271         mWcdmaDefaultSignalMeasurement = m.getString("WcdmaDefaultSignalMeasurement");
1272         ArrayList<Integer> lteRsrpThresholds = m.getIntegerArrayList("lteRsrpThresholds");
1273         for (int i = 0; i < lteRsrpThresholds.size(); i++) {
1274             mLteRsrpThresholds[i] = lteRsrpThresholds.get(i);
1275         }
1276         ArrayList<Integer> wcdmaRscpThresholds = m.getIntegerArrayList("wcdmaRscpThresholds");
1277         for (int i = 0; i < wcdmaRscpThresholds.size(); i++) {
1278             mWcdmaRscpThresholds[i] = wcdmaRscpThresholds.get(i);
1279         }
1280     }
1281 
1282     /**
1283      * Set intent notifier Bundle based on SignalStrength
1284      *
1285      * @param m intent notifier Bundle
1286      * @hide
1287      */
1288     public void fillInNotifierBundle(Bundle m) {
1289         m.putInt("GsmSignalStrength", mGsmSignalStrength);
1290         m.putInt("GsmBitErrorRate", mGsmBitErrorRate);
1291         m.putInt("CdmaDbm", mCdmaDbm);
1292         m.putInt("CdmaEcio", mCdmaEcio);
1293         m.putInt("EvdoDbm", mEvdoDbm);
1294         m.putInt("EvdoEcio", mEvdoEcio);
1295         m.putInt("EvdoSnr", mEvdoSnr);
1296         m.putInt("LteSignalStrength", mLteSignalStrength);
1297         m.putInt("LteRsrp", mLteRsrp);
1298         m.putInt("LteRsrq", mLteRsrq);
1299         m.putInt("LteRssnr", mLteRssnr);
1300         m.putInt("LteCqi", mLteCqi);
1301         m.putInt("LteRsrpBoost", mLteRsrpBoost);
1302         m.putInt("TdScdma", mTdScdmaRscp);
1303         m.putInt("WcdmaSignalStrength", mWcdmaSignalStrength);
1304         m.putInt("WcdmaRscpAsu", mWcdmaRscpAsu);
1305         m.putInt("WcdmaRscp", mWcdmaRscp);
1306         m.putBoolean("IsGsm", mIsGsm);
1307         m.putBoolean("UseOnlyRsrpForLteLevel", mUseOnlyRsrpForLteLevel);
1308         m.putString("WcdmaDefaultSignalMeasurement", mWcdmaDefaultSignalMeasurement);
1309         ArrayList<Integer> lteRsrpThresholds = new ArrayList<Integer>();
1310         for (int value : mLteRsrpThresholds) {
1311             lteRsrpThresholds.add(value);
1312         }
1313         m.putIntegerArrayList("lteRsrpThresholds", lteRsrpThresholds);
1314         ArrayList<Integer> wcdmaRscpThresholds = new ArrayList<Integer>();
1315         for (int value : mWcdmaRscpThresholds) {
1316             wcdmaRscpThresholds.add(value);
1317         }
1318         m.putIntegerArrayList("wcdmaRscpThresholds", wcdmaRscpThresholds);
1319     }
1320 
1321     /**
1322      * Gets the default threshold array for determining the display level of LTE signal bar.
1323      *
1324      * @return int array for determining the display level.
1325      */
1326     private int[] getDefaultLteRsrpThresholds() {
1327         return CarrierConfigManager.getDefaultConfig().getIntArray(
1328                 CarrierConfigManager.KEY_LTE_RSRP_THRESHOLDS_INT_ARRAY);
1329     }
1330 
1331     /**
1332      * Gets the default threshold array for determining the display level of WCDMA signal bar.
1333      *
1334      * @return int array for determining the display level.
1335      */
1336     private int[] getDefaultWcdmaRscpThresholds() {
1337         return CarrierConfigManager.getDefaultConfig().getIntArray(
1338                 CarrierConfigManager.KEY_WCDMA_RSCP_THRESHOLDS_INT_ARRAY);
1339     }
1340 
1341     /**
1342      * log
1343      */
1344     private static void log(String s) {
1345         Rlog.w(LOG_TAG, s);
1346     }
1347 }
1348