• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.Rlog;
23 import android.util.Log;
24 import android.content.res.Resources;
25 
26 /**
27  * Contains phone signal strength related information.
28  */
29 public class SignalStrength implements Parcelable {
30 
31     private static final String LOG_TAG = "SignalStrength";
32     private static final boolean DBG = false;
33 
34     /** @hide */
35     public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0;
36     /** @hide */
37     public static final int SIGNAL_STRENGTH_POOR = 1;
38     /** @hide */
39     public static final int SIGNAL_STRENGTH_MODERATE = 2;
40     /** @hide */
41     public static final int SIGNAL_STRENGTH_GOOD = 3;
42     /** @hide */
43     public static final int SIGNAL_STRENGTH_GREAT = 4;
44     /** @hide */
45     public static final int NUM_SIGNAL_STRENGTH_BINS = 5;
46     /** @hide */
47     public static final String[] SIGNAL_STRENGTH_NAMES = {
48         "none", "poor", "moderate", "good", "great"
49     };
50 
51     /** @hide */
52     //Use int max, as -1 is a valid value in signal strength
53     public static final int INVALID = 0x7FFFFFFF;
54 
55     private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
56     private int mGsmBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
57     private int mCdmaDbm;   // This value is the RSSI value
58     private int mCdmaEcio;  // This value is the Ec/Io
59     private int mEvdoDbm;   // This value is the EVDO RSSI value
60     private int mEvdoEcio;  // This value is the EVDO Ec/Io
61     private int mEvdoSnr;   // Valid values are 0-8.  8 is the highest signal to noise ratio
62     private int mLteSignalStrength;
63     private int mLteRsrp;
64     private int mLteRsrq;
65     private int mLteRssnr;
66     private int mLteCqi;
67     private int mLteRsrpBoost; // offset to be reduced from the rsrp threshold while calculating
68                                 // signal strength level
69     private int mTdScdmaRscp;
70 
71     private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult
72 
73     /**
74      * Create a new SignalStrength from a intent notifier Bundle
75      *
76      * This method is used by PhoneStateIntentReceiver and maybe by
77      * external applications.
78      *
79      * @param m Bundle from intent notifier
80      * @return newly created SignalStrength
81      *
82      * @hide
83      */
newFromBundle(Bundle m)84     public static SignalStrength newFromBundle(Bundle m) {
85         SignalStrength ret;
86         ret = new SignalStrength();
87         ret.setFromNotifierBundle(m);
88         return ret;
89     }
90 
91     /**
92      * Empty constructor
93      *
94      * @hide
95      */
SignalStrength()96     public SignalStrength() {
97         mGsmSignalStrength = 99;
98         mGsmBitErrorRate = -1;
99         mCdmaDbm = -1;
100         mCdmaEcio = -1;
101         mEvdoDbm = -1;
102         mEvdoEcio = -1;
103         mEvdoSnr = -1;
104         mLteSignalStrength = 99;
105         mLteRsrp = INVALID;
106         mLteRsrq = INVALID;
107         mLteRssnr = INVALID;
108         mLteCqi = INVALID;
109         mLteRsrpBoost = 0;
110         mTdScdmaRscp = INVALID;
111         isGsm = true;
112     }
113 
114     /**
115      * This constructor is used to create SignalStrength with default
116      * values and set the isGsmFlag with the value passed in the input
117      *
118      * @param gsmFlag true if Gsm Phone,false if Cdma phone
119      * @return newly created SignalStrength
120      * @hide
121      */
SignalStrength(boolean gsmFlag)122     public SignalStrength(boolean gsmFlag) {
123         mGsmSignalStrength = 99;
124         mGsmBitErrorRate = -1;
125         mCdmaDbm = -1;
126         mCdmaEcio = -1;
127         mEvdoDbm = -1;
128         mEvdoEcio = -1;
129         mEvdoSnr = -1;
130         mLteSignalStrength = 99;
131         mLteRsrp = INVALID;
132         mLteRsrq = INVALID;
133         mLteRssnr = INVALID;
134         mLteCqi = INVALID;
135         mLteRsrpBoost = 0;
136         mTdScdmaRscp = INVALID;
137         isGsm = gsmFlag;
138     }
139 
140     /**
141      * Constructor
142      *
143      * @hide
144      */
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 lteRsrpBoost, int tdScdmaRscp, boolean gsmFlag)145     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
146             int cdmaDbm, int cdmaEcio,
147             int evdoDbm, int evdoEcio, int evdoSnr,
148             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
149             int lteRsrpBoost, int tdScdmaRscp, boolean gsmFlag) {
150         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
151                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
152                 lteRsrq, lteRssnr, lteCqi, lteRsrpBoost, gsmFlag);
153         mTdScdmaRscp = tdScdmaRscp;
154     }
155 
156     /**
157      * Constructor
158      *
159      * @hide
160      */
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, boolean gsmFlag)161     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
162             int cdmaDbm, int cdmaEcio,
163             int evdoDbm, int evdoEcio, int evdoSnr,
164             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
165             int tdScdmaRscp, boolean gsmFlag) {
166         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
167                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
168                 lteRsrq, lteRssnr, lteCqi, 0, gsmFlag);
169         mTdScdmaRscp = tdScdmaRscp;
170     }
171 
172     /**
173      * Constructor
174      *
175      * @hide
176      */
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, boolean gsmFlag)177     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
178             int cdmaDbm, int cdmaEcio,
179             int evdoDbm, int evdoEcio, int evdoSnr,
180             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
181             boolean gsmFlag) {
182         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
183                 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp,
184                 lteRsrq, lteRssnr, lteCqi, 0, gsmFlag);
185     }
186 
187     /**
188      * Constructor
189      *
190      * @hide
191      */
SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, boolean gsmFlag)192     public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate,
193             int cdmaDbm, int cdmaEcio,
194             int evdoDbm, int evdoEcio, int evdoSnr,
195             boolean gsmFlag) {
196         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
197                 evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
198                 INVALID, INVALID, INVALID, 0, gsmFlag);
199     }
200 
201     /**
202      * Copy constructors
203      *
204      * @param s Source SignalStrength
205      *
206      * @hide
207      */
SignalStrength(SignalStrength s)208     public SignalStrength(SignalStrength s) {
209         copyFrom(s);
210     }
211 
212     /**
213      * Initialize gsm/cdma values, sets lte values to defaults.
214      *
215      * @param gsmSignalStrength
216      * @param gsmBitErrorRate
217      * @param cdmaDbm
218      * @param cdmaEcio
219      * @param evdoDbm
220      * @param evdoEcio
221      * @param evdoSnr
222      * @param gsm
223      *
224      * @hide
225      */
initialize(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, boolean gsm)226     public void initialize(int gsmSignalStrength, int gsmBitErrorRate,
227             int cdmaDbm, int cdmaEcio,
228             int evdoDbm, int evdoEcio, int evdoSnr,
229             boolean gsm) {
230         initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio,
231                 evdoDbm, evdoEcio, evdoSnr, 99, INVALID,
232                 INVALID, INVALID, INVALID, 0, gsm);
233     }
234 
235     /**
236      * Initialize all the values
237      *
238      * @param gsmSignalStrength
239      * @param gsmBitErrorRate
240      * @param cdmaDbm
241      * @param cdmaEcio
242      * @param evdoDbm
243      * @param evdoEcio
244      * @param evdoSnr
245      * @param lteSignalStrength
246      * @param lteRsrp
247      * @param lteRsrq
248      * @param lteRssnr
249      * @param lteCqi
250      * @param lteRsrpBoost
251      * @param gsm
252      *
253      * @hide
254      */
initialize(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 lteRsrpBoost, boolean gsm)255     public void initialize(int gsmSignalStrength, int gsmBitErrorRate,
256             int cdmaDbm, int cdmaEcio,
257             int evdoDbm, int evdoEcio, int evdoSnr,
258             int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi,
259             int lteRsrpBoost, boolean gsm) {
260         mGsmSignalStrength = gsmSignalStrength;
261         mGsmBitErrorRate = gsmBitErrorRate;
262         mCdmaDbm = cdmaDbm;
263         mCdmaEcio = cdmaEcio;
264         mEvdoDbm = evdoDbm;
265         mEvdoEcio = evdoEcio;
266         mEvdoSnr = evdoSnr;
267         mLteSignalStrength = lteSignalStrength;
268         mLteRsrp = lteRsrp;
269         mLteRsrq = lteRsrq;
270         mLteRssnr = lteRssnr;
271         mLteCqi = lteCqi;
272         mLteRsrpBoost = lteRsrpBoost;
273         mTdScdmaRscp = INVALID;
274         isGsm = gsm;
275         if (DBG) log("initialize: " + toString());
276     }
277 
278     /**
279      * @hide
280      */
copyFrom(SignalStrength s)281     protected void copyFrom(SignalStrength s) {
282         mGsmSignalStrength = s.mGsmSignalStrength;
283         mGsmBitErrorRate = s.mGsmBitErrorRate;
284         mCdmaDbm = s.mCdmaDbm;
285         mCdmaEcio = s.mCdmaEcio;
286         mEvdoDbm = s.mEvdoDbm;
287         mEvdoEcio = s.mEvdoEcio;
288         mEvdoSnr = s.mEvdoSnr;
289         mLteSignalStrength = s.mLteSignalStrength;
290         mLteRsrp = s.mLteRsrp;
291         mLteRsrq = s.mLteRsrq;
292         mLteRssnr = s.mLteRssnr;
293         mLteCqi = s.mLteCqi;
294         mLteRsrpBoost = s.mLteRsrpBoost;
295         mTdScdmaRscp = s.mTdScdmaRscp;
296         isGsm = s.isGsm;
297     }
298 
299     /**
300      * Construct a SignalStrength object from the given parcel.
301      *
302      * @hide
303      */
SignalStrength(Parcel in)304     public SignalStrength(Parcel in) {
305         if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
306 
307         mGsmSignalStrength = in.readInt();
308         mGsmBitErrorRate = in.readInt();
309         mCdmaDbm = in.readInt();
310         mCdmaEcio = in.readInt();
311         mEvdoDbm = in.readInt();
312         mEvdoEcio = in.readInt();
313         mEvdoSnr = in.readInt();
314         mLteSignalStrength = in.readInt();
315         mLteRsrp = in.readInt();
316         mLteRsrq = in.readInt();
317         mLteRssnr = in.readInt();
318         mLteCqi = in.readInt();
319         mLteRsrpBoost = in.readInt();
320         mTdScdmaRscp = in.readInt();
321         isGsm = (in.readInt() != 0);
322     }
323 
324     /**
325      * Make a SignalStrength object from the given parcel as passed up by
326      * the ril which does not have isGsm. isGsm will be changed by ServiceStateTracker
327      * so the default is a don't care.
328      *
329      * @hide
330      */
makeSignalStrengthFromRilParcel(Parcel in)331     public static SignalStrength makeSignalStrengthFromRilParcel(Parcel in) {
332         if (DBG) log("Size of signalstrength parcel:" + in.dataSize());
333 
334         SignalStrength ss = new SignalStrength();
335         ss.mGsmSignalStrength = in.readInt();
336         ss.mGsmBitErrorRate = in.readInt();
337         ss.mCdmaDbm = in.readInt();
338         ss.mCdmaEcio = in.readInt();
339         ss.mEvdoDbm = in.readInt();
340         ss.mEvdoEcio = in.readInt();
341         ss.mEvdoSnr = in.readInt();
342         ss.mLteSignalStrength = in.readInt();
343         ss.mLteRsrp = in.readInt();
344         ss.mLteRsrq = in.readInt();
345         ss.mLteRssnr = in.readInt();
346         ss.mLteCqi = in.readInt();
347         ss.mTdScdmaRscp = in.readInt();
348         return ss;
349     }
350 
351     /**
352      * {@link Parcelable#writeToParcel}
353      */
writeToParcel(Parcel out, int flags)354     public void writeToParcel(Parcel out, int flags) {
355         out.writeInt(mGsmSignalStrength);
356         out.writeInt(mGsmBitErrorRate);
357         out.writeInt(mCdmaDbm);
358         out.writeInt(mCdmaEcio);
359         out.writeInt(mEvdoDbm);
360         out.writeInt(mEvdoEcio);
361         out.writeInt(mEvdoSnr);
362         out.writeInt(mLteSignalStrength);
363         out.writeInt(mLteRsrp);
364         out.writeInt(mLteRsrq);
365         out.writeInt(mLteRssnr);
366         out.writeInt(mLteCqi);
367         out.writeInt(mLteRsrpBoost);
368         out.writeInt(mTdScdmaRscp);
369         out.writeInt(isGsm ? 1 : 0);
370     }
371 
372     /**
373      * {@link Parcelable#describeContents}
374      */
describeContents()375     public int describeContents() {
376         return 0;
377     }
378 
379     /**
380      * {@link Parcelable.Creator}
381      *
382      * @hide
383      */
384     public static final Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() {
385         public SignalStrength createFromParcel(Parcel in) {
386             return new SignalStrength(in);
387         }
388 
389         public SignalStrength[] newArray(int size) {
390             return new SignalStrength[size];
391         }
392     };
393 
394     /**
395      * Validate the individual signal strength fields as per the range
396      * specified in ril.h
397      * Set to invalid any field that is not in the valid range
398      * Cdma, evdo, lte rsrp & rsrq values are sign converted
399      * when received from ril interface
400      *
401      * @return
402      *      Valid values for all signalstrength fields
403      * @hide
404      */
validateInput()405     public void validateInput() {
406         if (DBG) log("Signal before validate=" + this);
407         // TS 27.007 8.5
408         mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99;
409         // BER no change;
410 
411         mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120;
412         mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160;
413 
414         mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120;
415         mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -1;
416         mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1;
417 
418         // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC
419         mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99;
420         mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID;
421         mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID;
422         mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr
423                 : SignalStrength.INVALID;
424 
425         mTdScdmaRscp = ((mTdScdmaRscp >= 25) && (mTdScdmaRscp <= 120))
426                 ? -mTdScdmaRscp : SignalStrength.INVALID;
427         // Cqi no change
428         if (DBG) log("Signal after validate=" + this);
429     }
430 
431     /**
432      * @param true - Gsm, Lte phones
433      *        false - Cdma phones
434      *
435      * Used by voice phone to set the isGsm
436      *        flag
437      * @hide
438      */
setGsm(boolean gsmFlag)439     public void setGsm(boolean gsmFlag) {
440         isGsm = gsmFlag;
441     }
442 
443     /**
444      * @param lteRsrpBoost - signal strength offset
445      *
446      * Used by phone to set the lte signal strength offset which will be
447      * reduced from rsrp threshold while calculating signal strength level
448      *
449      * @hide
450      */
setLteRsrpBoost(int lteRsrpBoost)451     public void setLteRsrpBoost(int lteRsrpBoost) {
452         mLteRsrpBoost = lteRsrpBoost;
453     }
454 
455     /**
456      * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS
457      * 27.007 8.5
458      */
getGsmSignalStrength()459     public int getGsmSignalStrength() {
460         return this.mGsmSignalStrength;
461     }
462 
463     /**
464      * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5
465      */
getGsmBitErrorRate()466     public int getGsmBitErrorRate() {
467         return this.mGsmBitErrorRate;
468     }
469 
470     /**
471      * Get the CDMA RSSI value in dBm
472      */
getCdmaDbm()473     public int getCdmaDbm() {
474         return this.mCdmaDbm;
475     }
476 
477     /**
478      * Get the CDMA Ec/Io value in dB*10
479      */
getCdmaEcio()480     public int getCdmaEcio() {
481         return this.mCdmaEcio;
482     }
483 
484     /**
485      * Get the EVDO RSSI value in dBm
486      */
getEvdoDbm()487     public int getEvdoDbm() {
488         return this.mEvdoDbm;
489     }
490 
491     /**
492      * Get the EVDO Ec/Io value in dB*10
493      */
getEvdoEcio()494     public int getEvdoEcio() {
495         return this.mEvdoEcio;
496     }
497 
498     /**
499      * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
500      */
getEvdoSnr()501     public int getEvdoSnr() {
502         return this.mEvdoSnr;
503     }
504 
505     /** @hide */
getLteSignalStrength()506     public int getLteSignalStrength() {
507         return mLteSignalStrength;
508     }
509 
510     /** @hide */
getLteRsrp()511     public int getLteRsrp() {
512         return mLteRsrp;
513     }
514 
515     /** @hide */
getLteRsrq()516     public int getLteRsrq() {
517         return mLteRsrq;
518     }
519 
520     /** @hide */
getLteRssnr()521     public int getLteRssnr() {
522         return mLteRssnr;
523     }
524 
525     /** @hide */
getLteCqi()526     public int getLteCqi() {
527         return mLteCqi;
528     }
529 
530     /** @hide */
getLteRsrpBoost()531     public int getLteRsrpBoost() {
532         return mLteRsrpBoost;
533     }
534 
535     /**
536      * Retrieve an abstract level value for the overall signal strength.
537      *
538      * @return a single integer from 0 to 4 representing the general signal quality.
539      *     This may take into account many different radio technology inputs.
540      *     0 represents very poor signal strength
541      *     while 4 represents a very strong signal strength.
542      */
getLevel()543     public int getLevel() {
544         int level = 0;
545 
546         if (isGsm) {
547             level = getLteLevel();
548             if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
549                 level = getTdScdmaLevel();
550                 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
551                     level = getGsmLevel();
552                 }
553             }
554         } else {
555             int cdmaLevel = getCdmaLevel();
556             int evdoLevel = getEvdoLevel();
557             if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
558                 /* We don't know evdo, use cdma */
559                 level = cdmaLevel;
560             } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
561                 /* We don't know cdma, use evdo */
562                 level = evdoLevel;
563             } else {
564                 /* We know both, use the lowest level */
565                 level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
566             }
567         }
568         if (DBG) log("getLevel=" + level);
569         return level;
570     }
571 
572     /**
573      * Get the signal level as an asu value between 0..31, 99 is unknown
574      *
575      * @hide
576      */
577     public int getAsuLevel() {
578         int asuLevel = 0;
579         if (isGsm) {
580             if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
581                 if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
582                     asuLevel = getGsmAsuLevel();
583                 } else {
584                     asuLevel = getTdScdmaAsuLevel();
585                 }
586             } else {
587                 asuLevel = getLteAsuLevel();
588             }
589         } else {
590             int cdmaAsuLevel = getCdmaAsuLevel();
591             int evdoAsuLevel = getEvdoAsuLevel();
592             if (evdoAsuLevel == 0) {
593                 /* We don't know evdo use, cdma */
594                 asuLevel = cdmaAsuLevel;
595             } else if (cdmaAsuLevel == 0) {
596                 /* We don't know cdma use, evdo */
597                 asuLevel = evdoAsuLevel;
598             } else {
599                 /* We know both, use the lowest level */
600                 asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel;
601             }
602         }
603         if (DBG) log("getAsuLevel=" + asuLevel);
604         return asuLevel;
605     }
606 
607     /**
608      * Get the signal strength as dBm
609      *
610      * @hide
611      */
612     public int getDbm() {
613         int dBm = INVALID;
614 
615         if(isGsm()) {
616             dBm = getLteDbm();
617             if (dBm == INVALID) {
618                 if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
619                     dBm = getGsmDbm();
620                 } else {
621                     dBm = getTdScdmaDbm();
622                 }
623             }
624         } else {
625             int cdmaDbm = getCdmaDbm();
626             int evdoDbm = getEvdoDbm();
627 
628             return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm
629                     : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm));
630         }
631         if (DBG) log("getDbm=" + dBm);
632         return dBm;
633     }
634 
635     /**
636      * Get Gsm signal strength as dBm
637      *
638      * @hide
639      */
640     public int getGsmDbm() {
641         int dBm;
642 
643         int gsmSignalStrength = getGsmSignalStrength();
644         int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength);
645         if (asu != -1) {
646             dBm = -113 + (2 * asu);
647         } else {
648             dBm = -1;
649         }
650         if (DBG) log("getGsmDbm=" + dBm);
651         return dBm;
652     }
653 
654     /**
655      * Get gsm as level 0..4
656      *
657      * @hide
658      */
659     public int getGsmLevel() {
660         int level;
661 
662         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
663         // asu = 0 (-113dB or less) is very weak
664         // signal, its better to show 0 bars to the user in such cases.
665         // asu = 99 is a special case, where the signal strength is unknown.
666         int asu = getGsmSignalStrength();
667         if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
668         else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT;
669         else if (asu >= 8)  level = SIGNAL_STRENGTH_GOOD;
670         else if (asu >= 5)  level = SIGNAL_STRENGTH_MODERATE;
671         else level = SIGNAL_STRENGTH_POOR;
672         if (DBG) log("getGsmLevel=" + level);
673         return level;
674     }
675 
676     /**
677      * Get the gsm signal level as an asu value between 0..31, 99 is unknown
678      *
679      * @hide
680      */
681     public int getGsmAsuLevel() {
682         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
683         // asu = 0 (-113dB or less) is very weak
684         // signal, its better to show 0 bars to the user in such cases.
685         // asu = 99 is a special case, where the signal strength is unknown.
686         int level = getGsmSignalStrength();
687         if (DBG) log("getGsmAsuLevel=" + level);
688         return level;
689     }
690 
691     /**
692      * Get cdma as level 0..4
693      *
694      * @hide
695      */
696     public int getCdmaLevel() {
697         final int cdmaDbm = getCdmaDbm();
698         final int cdmaEcio = getCdmaEcio();
699         int levelDbm;
700         int levelEcio;
701 
702         if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
703         else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
704         else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
705         else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
706         else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
707 
708         // Ec/Io are in dB*10
709         if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
710         else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
711         else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
712         else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
713         else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
714 
715         int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
716         if (DBG) log("getCdmaLevel=" + level);
717         return level;
718     }
719 
720     /**
721      * Get the cdma signal level as an asu value between 0..31, 99 is unknown
722      *
723      * @hide
724      */
getCdmaAsuLevel()725     public int getCdmaAsuLevel() {
726         final int cdmaDbm = getCdmaDbm();
727         final int cdmaEcio = getCdmaEcio();
728         int cdmaAsuLevel;
729         int ecioAsuLevel;
730 
731         if (cdmaDbm >= -75) cdmaAsuLevel = 16;
732         else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
733         else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
734         else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
735         else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
736         else cdmaAsuLevel = 99;
737 
738         // Ec/Io are in dB*10
739         if (cdmaEcio >= -90) ecioAsuLevel = 16;
740         else if (cdmaEcio >= -100) ecioAsuLevel = 8;
741         else if (cdmaEcio >= -115) ecioAsuLevel = 4;
742         else if (cdmaEcio >= -130) ecioAsuLevel = 2;
743         else if (cdmaEcio >= -150) ecioAsuLevel = 1;
744         else ecioAsuLevel = 99;
745 
746         int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
747         if (DBG) log("getCdmaAsuLevel=" + level);
748         return level;
749     }
750 
751     /**
752      * Get Evdo as level 0..4
753      *
754      * @hide
755      */
getEvdoLevel()756     public int getEvdoLevel() {
757         int evdoDbm = getEvdoDbm();
758         int evdoSnr = getEvdoSnr();
759         int levelEvdoDbm;
760         int levelEvdoSnr;
761 
762         if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
763         else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
764         else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
765         else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
766         else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
767 
768         if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
769         else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
770         else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
771         else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
772         else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
773 
774         int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
775         if (DBG) log("getEvdoLevel=" + level);
776         return level;
777     }
778 
779     /**
780      * Get the evdo signal level as an asu value between 0..31, 99 is unknown
781      *
782      * @hide
783      */
getEvdoAsuLevel()784     public int getEvdoAsuLevel() {
785         int evdoDbm = getEvdoDbm();
786         int evdoSnr = getEvdoSnr();
787         int levelEvdoDbm;
788         int levelEvdoSnr;
789 
790         if (evdoDbm >= -65) levelEvdoDbm = 16;
791         else if (evdoDbm >= -75) levelEvdoDbm = 8;
792         else if (evdoDbm >= -85) levelEvdoDbm = 4;
793         else if (evdoDbm >= -95) levelEvdoDbm = 2;
794         else if (evdoDbm >= -105) levelEvdoDbm = 1;
795         else levelEvdoDbm = 99;
796 
797         if (evdoSnr >= 7) levelEvdoSnr = 16;
798         else if (evdoSnr >= 6) levelEvdoSnr = 8;
799         else if (evdoSnr >= 5) levelEvdoSnr = 4;
800         else if (evdoSnr >= 3) levelEvdoSnr = 2;
801         else if (evdoSnr >= 1) levelEvdoSnr = 1;
802         else levelEvdoSnr = 99;
803 
804         int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
805         if (DBG) log("getEvdoAsuLevel=" + level);
806         return level;
807     }
808 
809     /**
810      * Get LTE as dBm
811      *
812      * @hide
813      */
getLteDbm()814     public int getLteDbm() {
815         return mLteRsrp;
816     }
817 
818     /**
819      * Get LTE as level 0..4
820      *
821      * @hide
822      */
getLteLevel()823     public int getLteLevel() {
824         /*
825          * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received
826          * signal + noise RSRP = reference signal dBm RSRQ = quality of signal
827          * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio
828          * = -10log P1/P2 dB
829          */
830         int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1;
831 
832         int[] threshRsrp = Resources.getSystem().getIntArray(
833                 com.android.internal.R.array.config_lteDbmThresholds);
834         if (threshRsrp.length != 6) {
835             Log.wtf(LOG_TAG, "getLteLevel - config_lteDbmThresholds has invalid num of elements."
836                     + " Cannot evaluate RSRP signal.");
837         } else {
838             if (mLteRsrp > threshRsrp[5]) {
839                 rsrpIconLevel = -1;
840             } else if (mLteRsrp >= (threshRsrp[4] - mLteRsrpBoost)) {
841                 rsrpIconLevel = SIGNAL_STRENGTH_GREAT;
842             } else if (mLteRsrp >= (threshRsrp[3] - mLteRsrpBoost)) {
843                 rsrpIconLevel = SIGNAL_STRENGTH_GOOD;
844             } else if (mLteRsrp >= (threshRsrp[2] - mLteRsrpBoost)) {
845                 rsrpIconLevel = SIGNAL_STRENGTH_MODERATE;
846             } else if (mLteRsrp >= (threshRsrp[1] - mLteRsrpBoost)) {
847                 rsrpIconLevel = SIGNAL_STRENGTH_POOR;
848             } else if (mLteRsrp >= threshRsrp[0]) {
849                 rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
850             }
851         }
852 
853         /*
854          * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5
855          * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars
856          * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna
857          * Icon Only
858          */
859         if (mLteRssnr > 300) snrIconLevel = -1;
860         else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT;
861         else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD;
862         else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE;
863         else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR;
864         else if (mLteRssnr >= -200)
865             snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
866 
867         if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:"
868                 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel
869                 + " lteRsrpBoost:" + mLteRsrpBoost);
870 
871         /* Choose a measurement type to use for notification */
872         if (snrIconLevel != -1 && rsrpIconLevel != -1) {
873             /*
874              * The number of bars displayed shall be the smaller of the bars
875              * associated with LTE RSRP and the bars associated with the LTE
876              * RS_SNR
877              */
878             return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel);
879         }
880 
881         if (snrIconLevel != -1) return snrIconLevel;
882 
883         if (rsrpIconLevel != -1) return rsrpIconLevel;
884 
885         /* Valid values are (0-63, 99) as defined in TS 36.331 */
886         if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
887         else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT;
888         else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD;
889         else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE;
890         else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR;
891 
892         if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:"
893                 + rssiIconLevel);
894         return rssiIconLevel;
895 
896     }
897     /**
898      * Get the LTE signal level as an asu value between 0..97, 99 is unknown
899      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
900      *
901      * @hide
902      */
getLteAsuLevel()903     public int getLteAsuLevel() {
904         int lteAsuLevel = 99;
905         int lteDbm = getLteDbm();
906         /*
907          * 3GPP 27.007 (Ver 10.3.0) Sec 8.69
908          * 0   -140 dBm or less
909          * 1   -139 dBm
910          * 2...96  -138... -44 dBm
911          * 97  -43 dBm or greater
912          * 255 not known or not detectable
913          */
914         /*
915          * validateInput will always give a valid range between -140 t0 -44 as
916          * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255
917          * and not 97 or 0
918          */
919         if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255;
920         else lteAsuLevel = lteDbm + 140;
921         if (DBG) log("Lte Asu level: "+lteAsuLevel);
922         return lteAsuLevel;
923     }
924 
925     /**
926      * @return true if this is for GSM
927      */
isGsm()928     public boolean isGsm() {
929         return this.isGsm;
930     }
931 
932     /**
933      * @return get TD_SCDMA dbm
934      *
935      * @hide
936      */
getTdScdmaDbm()937     public int getTdScdmaDbm() {
938         return this.mTdScdmaRscp;
939     }
940 
941     /**
942      * Get TD-SCDMA as level 0..4
943      * Range : 25 to 120
944      * INT_MAX: 0x7FFFFFFF denotes invalid value
945      * Reference: 3GPP TS 25.123, section 9.1.1.1
946      *
947      * @hide
948      */
getTdScdmaLevel()949     public int getTdScdmaLevel() {
950         final int tdScdmaDbm = getTdScdmaDbm();
951         int level;
952 
953         if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID))
954                 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
955         else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT;
956         else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD;
957         else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE;
958         else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR;
959         else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
960 
961         if (DBG) log("getTdScdmaLevel = " + level);
962         return level;
963      }
964 
965     /**
966      * Get the TD-SCDMA signal level as an asu value.
967      *
968      * @hide
969      */
getTdScdmaAsuLevel()970     public int getTdScdmaAsuLevel() {
971         final int tdScdmaDbm = getTdScdmaDbm();
972         int tdScdmaAsuLevel;
973 
974         if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255;
975         else tdScdmaAsuLevel = tdScdmaDbm + 120;
976         if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel);
977         return tdScdmaAsuLevel;
978     }
979 
980    /**
981      * @return hash code
982      */
983     @Override
hashCode()984     public int hashCode() {
985         int primeNum = 31;
986         return ((mGsmSignalStrength * primeNum)
987                 + (mGsmBitErrorRate * primeNum)
988                 + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum)
989                 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum)
990                 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum)
991                 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum)
992                 + (mLteRsrpBoost * primeNum) + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0));
993     }
994 
995     /**
996      * @return true if the signal strengths are the same
997      */
998     @Override
equals(Object o)999     public boolean equals (Object o) {
1000         SignalStrength s;
1001 
1002         try {
1003             s = (SignalStrength) o;
1004         } catch (ClassCastException ex) {
1005             return false;
1006         }
1007 
1008         if (o == null) {
1009             return false;
1010         }
1011 
1012         return (mGsmSignalStrength == s.mGsmSignalStrength
1013                 && mGsmBitErrorRate == s.mGsmBitErrorRate
1014                 && mCdmaDbm == s.mCdmaDbm
1015                 && mCdmaEcio == s.mCdmaEcio
1016                 && mEvdoDbm == s.mEvdoDbm
1017                 && mEvdoEcio == s.mEvdoEcio
1018                 && mEvdoSnr == s.mEvdoSnr
1019                 && mLteSignalStrength == s.mLteSignalStrength
1020                 && mLteRsrp == s.mLteRsrp
1021                 && mLteRsrq == s.mLteRsrq
1022                 && mLteRssnr == s.mLteRssnr
1023                 && mLteCqi == s.mLteCqi
1024                 && mLteRsrpBoost == s.mLteRsrpBoost
1025                 && mTdScdmaRscp == s.mTdScdmaRscp
1026                 && isGsm == s.isGsm);
1027     }
1028 
1029     /**
1030      * @return string representation.
1031      */
1032     @Override
toString()1033     public String toString() {
1034         return ("SignalStrength:"
1035                 + " " + mGsmSignalStrength
1036                 + " " + mGsmBitErrorRate
1037                 + " " + mCdmaDbm
1038                 + " " + mCdmaEcio
1039                 + " " + mEvdoDbm
1040                 + " " + mEvdoEcio
1041                 + " " + mEvdoSnr
1042                 + " " + mLteSignalStrength
1043                 + " " + mLteRsrp
1044                 + " " + mLteRsrq
1045                 + " " + mLteRssnr
1046                 + " " + mLteCqi
1047                 + " " + mLteRsrpBoost
1048                 + " " + mTdScdmaRscp
1049                 + " " + (isGsm ? "gsm|lte" : "cdma"));
1050     }
1051 
1052     /**
1053      * Set SignalStrength based on intent notifier map
1054      *
1055      * @param m intent notifier map
1056      * @hide
1057      */
setFromNotifierBundle(Bundle m)1058     private void setFromNotifierBundle(Bundle m) {
1059         mGsmSignalStrength = m.getInt("GsmSignalStrength");
1060         mGsmBitErrorRate = m.getInt("GsmBitErrorRate");
1061         mCdmaDbm = m.getInt("CdmaDbm");
1062         mCdmaEcio = m.getInt("CdmaEcio");
1063         mEvdoDbm = m.getInt("EvdoDbm");
1064         mEvdoEcio = m.getInt("EvdoEcio");
1065         mEvdoSnr = m.getInt("EvdoSnr");
1066         mLteSignalStrength = m.getInt("LteSignalStrength");
1067         mLteRsrp = m.getInt("LteRsrp");
1068         mLteRsrq = m.getInt("LteRsrq");
1069         mLteRssnr = m.getInt("LteRssnr");
1070         mLteCqi = m.getInt("LteCqi");
1071         mLteRsrpBoost = m.getInt("lteRsrpBoost");
1072         mTdScdmaRscp = m.getInt("TdScdma");
1073         isGsm = m.getBoolean("isGsm");
1074     }
1075 
1076     /**
1077      * Set intent notifier Bundle based on SignalStrength
1078      *
1079      * @param m intent notifier Bundle
1080      * @hide
1081      */
fillInNotifierBundle(Bundle m)1082     public void fillInNotifierBundle(Bundle m) {
1083         m.putInt("GsmSignalStrength", mGsmSignalStrength);
1084         m.putInt("GsmBitErrorRate", mGsmBitErrorRate);
1085         m.putInt("CdmaDbm", mCdmaDbm);
1086         m.putInt("CdmaEcio", mCdmaEcio);
1087         m.putInt("EvdoDbm", mEvdoDbm);
1088         m.putInt("EvdoEcio", mEvdoEcio);
1089         m.putInt("EvdoSnr", mEvdoSnr);
1090         m.putInt("LteSignalStrength", mLteSignalStrength);
1091         m.putInt("LteRsrp", mLteRsrp);
1092         m.putInt("LteRsrq", mLteRsrq);
1093         m.putInt("LteRssnr", mLteRssnr);
1094         m.putInt("LteCqi", mLteCqi);
1095         m.putInt("lteRsrpBoost", mLteRsrpBoost);
1096         m.putInt("TdScdma", mTdScdmaRscp);
1097         m.putBoolean("isGsm", isGsm);
1098     }
1099 
1100     /**
1101      * log
1102      */
log(String s)1103     private static void log(String s) {
1104         Rlog.w(LOG_TAG, s);
1105     }
1106 }
1107