Home | History | Annotate | Download | only in telephony
      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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    250     public SignalStrength(SignalStrength s) {
    251         copyFrom(s);
    252     }
    253 
    254     /**
    255      * @hide
    256      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    516     public int getCdmaDbm() {
    517         return this.mCdmaDbm;
    518     }
    519 
    520     /**
    521      * Get the CDMA Ec/Io value in dB*10
    522      */
    523     public int getCdmaEcio() {
    524         return this.mCdmaEcio;
    525     }
    526 
    527     /**
    528      * Get the EVDO RSSI value in dBm
    529      */
    530     public int getEvdoDbm() {
    531         return this.mEvdoDbm;
    532     }
    533 
    534     /**
    535      * Get the EVDO Ec/Io value in dB*10
    536      */
    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      */
    544     public int getEvdoSnr() {
    545         return this.mEvdoSnr;
    546     }
    547 
    548     /** @hide */
    549     public int getLteSignalStrength() {
    550         return mLteSignalStrength;
    551     }
    552 
    553     /** @hide */
    554     public int getLteRsrp() {
    555         return mLteRsrp;
    556     }
    557 
    558     /** @hide */
    559     public int getLteRsrq() {
    560         return mLteRsrq;
    561     }
    562 
    563     /** @hide */
    564     public int getLteRssnr() {
    565         return mLteRssnr;
    566     }
    567 
    568     /** @hide */
    569     public int getLteCqi() {
    570         return mLteCqi;
    571     }
    572 
    573     /** @hide */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    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      */
    838     public int getLteDbm() {
    839         return mLteRsrp;
    840     }
    841 
    842     /**
    843      * Get LTE as level 0..4
    844      *
    845      * @hide
    846      */
    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      */
    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      */
    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      */
    970     public boolean useOnlyRsrpForLteLevel() {
    971         return this.mUseOnlyRsrpForLteLevel;
    972     }
    973 
    974     /**
    975      * @return get TD_SCDMA dbm
    976      *
    977      * @hide
    978      */
    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      */
    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      */
   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      */
   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      */
   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      */
   1060     public int getWcdmaDbm() {
   1061         return mWcdmaRscp;
   1062     }
   1063 
   1064     /**
   1065      * Get WCDMA as level 0..4
   1066      *
   1067      * @hide
   1068      */
   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
   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
   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
   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. */
   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. */
   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