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.Parcel;
     20 import android.os.Parcelable;
     21 import android.telephony.Rlog;
     22 
     23 import java.util.Objects;
     24 
     25 /**
     26  * Signal strength related information.
     27  */
     28 public final class CellSignalStrengthCdma extends CellSignalStrength implements Parcelable {
     29 
     30     private static final String LOG_TAG = "CellSignalStrengthCdma";
     31     private static final boolean DBG = false;
     32 
     33     private int mCdmaDbm;   // This value is the RSSI value
     34     private int mCdmaEcio;  // This value is the Ec/Io
     35     private int mEvdoDbm;   // This value is the EVDO RSSI value
     36     private int mEvdoEcio;  // This value is the EVDO Ec/Io
     37     private int mEvdoSnr;   // Valid values are 0-8.  8 is the highest signal to noise ratio
     38 
     39     /** @hide */
     40     public CellSignalStrengthCdma() {
     41         setDefaultValues();
     42     }
     43 
     44     /**
     45      * SignalStrength constructor for input from the HAL.
     46      *
     47      * Note that values received from the HAL require coersion to be compatible here. All values
     48      * reported through IRadio are the negative of the actual values (which results in a positive
     49      * input to this method.
     50      *
     51      * <p>Note that this HAL is inconsistent with UMTS-based radio techs as the value indicating
     52      * that a field is unreported is negative, rather than a large(r) positive number.
     53      * <p>Also note that to keep the public-facing methods of this class consistent with others,
     54      * unreported values are coerced to Integer.MAX_VALUE rather than left as -1, which is
     55      * a departure from SignalStrength, which is stuck with the values it currently reports.
     56      *
     57      * @param cdmaDbm negative of the CDMA signal strength value or -1 if invalid.
     58      * @param cdmaEcio negative of the CDMA pilot/noise ratio or -1 if invalid.
     59      * @param evdoDbm negative of the EvDO signal strength value or -1 if invalid.
     60      * @param evdoEcio negative of the EvDO pilot/noise ratio or -1 if invalid.
     61      * @param evdoSnr an SNR value 0..8 or -1 if invalid.
     62      * @hide
     63      */
     64     public CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio,
     65             int evdoSnr) {
     66         // The values here were lifted from SignalStrength.validateInput()
     67         // FIXME: Combine all checking and setting logic between this and SignalStrength.
     68         mCdmaDbm = ((cdmaDbm > 0) && (cdmaDbm < 120))  ? -cdmaDbm : Integer.MAX_VALUE;
     69         mCdmaEcio = ((cdmaEcio > 0) && (cdmaEcio < 160)) ? -cdmaEcio : Integer.MAX_VALUE;
     70 
     71         mEvdoDbm = ((evdoDbm > 0) && (evdoDbm < 120)) ? -evdoDbm : Integer.MAX_VALUE;
     72         mEvdoEcio = ((evdoEcio > 0) && (evdoEcio < 160)) ? -evdoEcio : Integer.MAX_VALUE;
     73         mEvdoSnr = ((evdoSnr > 0) && (evdoSnr <= 8)) ? evdoSnr : Integer.MAX_VALUE;
     74     }
     75 
     76     /** @hide */
     77     public CellSignalStrengthCdma(CellSignalStrengthCdma s) {
     78         copyFrom(s);
     79     }
     80 
     81     /** @hide */
     82     protected void copyFrom(CellSignalStrengthCdma s) {
     83         mCdmaDbm = s.mCdmaDbm;
     84         mCdmaEcio = s.mCdmaEcio;
     85         mEvdoDbm = s.mEvdoDbm;
     86         mEvdoEcio = s.mEvdoEcio;
     87         mEvdoSnr = s.mEvdoSnr;
     88     }
     89 
     90     /** @hide */
     91     @Override
     92     public CellSignalStrengthCdma copy() {
     93         return new CellSignalStrengthCdma(this);
     94     }
     95 
     96     /** @hide */
     97     @Override
     98     public void setDefaultValues() {
     99         mCdmaDbm = Integer.MAX_VALUE;
    100         mCdmaEcio = Integer.MAX_VALUE;
    101         mEvdoDbm = Integer.MAX_VALUE;
    102         mEvdoEcio = Integer.MAX_VALUE;
    103         mEvdoSnr = Integer.MAX_VALUE;
    104     }
    105 
    106     /**
    107      * Get signal level as an int from 0..4
    108      */
    109     @Override
    110     public int getLevel() {
    111         int level;
    112 
    113         int cdmaLevel = getCdmaLevel();
    114         int evdoLevel = getEvdoLevel();
    115         if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    116             /* We don't know evdo, use cdma */
    117             level = getCdmaLevel();
    118         } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
    119             /* We don't know cdma, use evdo */
    120             level = getEvdoLevel();
    121         } else {
    122             /* We know both, use the lowest level */
    123             level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
    124         }
    125         if (DBG) log("getLevel=" + level);
    126         return level;
    127     }
    128 
    129     /**
    130      * Get the signal level as an asu value between 0..97, 99 is unknown
    131      */
    132     @Override
    133     public int getAsuLevel() {
    134         final int cdmaDbm = getCdmaDbm();
    135         final int cdmaEcio = getCdmaEcio();
    136         int cdmaAsuLevel;
    137         int ecioAsuLevel;
    138 
    139         if (cdmaDbm == Integer.MAX_VALUE) cdmaAsuLevel = 99;
    140         else if (cdmaDbm >= -75) cdmaAsuLevel = 16;
    141         else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
    142         else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
    143         else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
    144         else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
    145         else cdmaAsuLevel = 99;
    146 
    147         // Ec/Io are in dB*10
    148         if (cdmaEcio == Integer.MAX_VALUE) ecioAsuLevel = 99;
    149         else if (cdmaEcio >= -90) ecioAsuLevel = 16;
    150         else if (cdmaEcio >= -100) ecioAsuLevel = 8;
    151         else if (cdmaEcio >= -115) ecioAsuLevel = 4;
    152         else if (cdmaEcio >= -130) ecioAsuLevel = 2;
    153         else if (cdmaEcio >= -150) ecioAsuLevel = 1;
    154         else ecioAsuLevel = 99;
    155 
    156         int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
    157         if (DBG) log("getAsuLevel=" + level);
    158         return level;
    159     }
    160 
    161     /**
    162      * Get cdma as level 0..4
    163      */
    164     public int getCdmaLevel() {
    165         final int cdmaDbm = getCdmaDbm();
    166         final int cdmaEcio = getCdmaEcio();
    167         int levelDbm;
    168         int levelEcio;
    169 
    170         if (cdmaDbm == Integer.MAX_VALUE) levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    171         else if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
    172         else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
    173         else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
    174         else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
    175         else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    176 
    177         // Ec/Io are in dB*10
    178         if (cdmaEcio == Integer.MAX_VALUE) levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    179         else if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
    180         else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
    181         else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
    182         else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
    183         else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    184 
    185         int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
    186         if (DBG) log("getCdmaLevel=" + level);
    187         return level;
    188     }
    189 
    190     /**
    191      * Get Evdo as level 0..4
    192      */
    193     public int getEvdoLevel() {
    194         int evdoDbm = getEvdoDbm();
    195         int evdoSnr = getEvdoSnr();
    196         int levelEvdoDbm;
    197         int levelEvdoSnr;
    198 
    199         if (evdoDbm == Integer.MAX_VALUE) levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    200         else if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
    201         else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
    202         else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
    203         else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
    204         else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    205 
    206         if (evdoSnr == Integer.MAX_VALUE) levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    207         else if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
    208         else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
    209         else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
    210         else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
    211         else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
    212 
    213         int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
    214         if (DBG) log("getEvdoLevel=" + level);
    215         return level;
    216     }
    217 
    218     /**
    219      * Get the signal strength as dBm
    220      */
    221     @Override
    222     public int getDbm() {
    223         int cdmaDbm = getCdmaDbm();
    224         int evdoDbm = getEvdoDbm();
    225 
    226         // Use the lower value to be conservative
    227         return (cdmaDbm < evdoDbm) ? cdmaDbm : evdoDbm;
    228     }
    229 
    230     /**
    231      * Get the CDMA RSSI value in dBm
    232      */
    233     public int getCdmaDbm() {
    234         return mCdmaDbm;
    235     }
    236     /** @hide */
    237     public void setCdmaDbm(int cdmaDbm) {
    238         mCdmaDbm = cdmaDbm;
    239     }
    240 
    241     /**
    242      * Get the CDMA Ec/Io value in dB*10
    243      */
    244     public int getCdmaEcio() {
    245         return mCdmaEcio;
    246     }
    247     /** @hide */
    248     public void setCdmaEcio(int cdmaEcio) {
    249         mCdmaEcio = cdmaEcio;
    250     }
    251 
    252     /**
    253      * Get the EVDO RSSI value in dBm
    254      */
    255     public int getEvdoDbm() {
    256         return mEvdoDbm;
    257     }
    258     /** @hide */
    259     public void setEvdoDbm(int evdoDbm) {
    260         mEvdoDbm = evdoDbm;
    261     }
    262 
    263     /**
    264      * Get the EVDO Ec/Io value in dB*10
    265      */
    266     public int getEvdoEcio() {
    267         return mEvdoEcio;
    268     }
    269     /** @hide */
    270     public void setEvdoEcio(int evdoEcio) {
    271         mEvdoEcio = evdoEcio;
    272     }
    273 
    274     /**
    275      * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
    276      */
    277     public int getEvdoSnr() {
    278         return mEvdoSnr;
    279     }
    280     /** @hide */
    281     public void setEvdoSnr(int evdoSnr) {
    282         mEvdoSnr = evdoSnr;
    283     }
    284 
    285     @Override
    286     public int hashCode() {
    287         return Objects.hash(mCdmaDbm, mCdmaEcio, mEvdoDbm, mEvdoEcio, mEvdoSnr);
    288     }
    289 
    290     @Override
    291     public boolean equals (Object o) {
    292         CellSignalStrengthCdma s;
    293 
    294         try {
    295             s = (CellSignalStrengthCdma) o;
    296         } catch (ClassCastException ex) {
    297             return false;
    298         }
    299 
    300         if (o == null) {
    301             return false;
    302         }
    303 
    304         return mCdmaDbm == s.mCdmaDbm
    305                 && mCdmaEcio == s.mCdmaEcio
    306                 && mEvdoDbm == s.mEvdoDbm
    307                 && mEvdoEcio == s.mEvdoEcio
    308                 && mEvdoSnr == s.mEvdoSnr;
    309     }
    310 
    311     /**
    312      * @return string representation.
    313      */
    314     @Override
    315     public String toString() {
    316         return "CellSignalStrengthCdma:"
    317                 + " cdmaDbm=" + mCdmaDbm
    318                 + " cdmaEcio=" + mCdmaEcio
    319                 + " evdoDbm=" + mEvdoDbm
    320                 + " evdoEcio=" + mEvdoEcio
    321                 + " evdoSnr=" + mEvdoSnr;
    322     }
    323 
    324     /** Implement the Parcelable interface */
    325     @Override
    326     public void writeToParcel(Parcel dest, int flags) {
    327         if (DBG) log("writeToParcel(Parcel, int): " + toString());
    328         dest.writeInt(mCdmaDbm);
    329         dest.writeInt(mCdmaEcio);
    330         dest.writeInt(mEvdoDbm);
    331         dest.writeInt(mEvdoEcio);
    332         dest.writeInt(mEvdoSnr);
    333     }
    334 
    335     /**
    336      * Construct a SignalStrength object from the given parcel
    337      * where the TYPE_CDMA token is already been processed.
    338      */
    339     private CellSignalStrengthCdma(Parcel in) {
    340         // CdmaDbm, CdmaEcio, EvdoDbm and EvdoEcio are written into
    341         // the parcel as positive values.
    342         // Need to convert into negative values unless the value is invalid
    343         mCdmaDbm = in.readInt();
    344         mCdmaEcio = in.readInt();
    345         mEvdoDbm = in.readInt();
    346         mEvdoEcio = in.readInt();
    347         mEvdoSnr = in.readInt();
    348         if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString());
    349     }
    350 
    351     /** Implement the Parcelable interface */
    352     @Override
    353     public int describeContents() {
    354         return 0;
    355     }
    356 
    357     /** Implement the Parcelable interface */
    358     @SuppressWarnings("hiding")
    359     public static final Parcelable.Creator<CellSignalStrengthCdma> CREATOR =
    360             new Parcelable.Creator<CellSignalStrengthCdma>() {
    361         @Override
    362         public CellSignalStrengthCdma createFromParcel(Parcel in) {
    363             return new CellSignalStrengthCdma(in);
    364         }
    365 
    366         @Override
    367         public CellSignalStrengthCdma[] newArray(int size) {
    368             return new CellSignalStrengthCdma[size];
    369         }
    370     };
    371 
    372     /**
    373      * log
    374      */
    375     private static void log(String s) {
    376         Rlog.w(LOG_TAG, s);
    377     }
    378 }
    379