• 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.annotation.IntRange;
20 import android.os.Parcel;
21 import android.os.Parcelable;
22 import android.os.PersistableBundle;
23 import android.telephony.Rlog;
24 
25 import java.util.Objects;
26 
27 /**
28  * Signal strength related information.
29  */
30 public final class CellSignalStrengthCdma extends CellSignalStrength implements Parcelable {
31 
32     private static final String LOG_TAG = "CellSignalStrengthCdma";
33     private static final boolean DBG = false;
34 
35     private int mCdmaDbm;   // This value is the RSSI value
36     private int mCdmaEcio;  // This value is the Ec/Io
37     private int mEvdoDbm;   // This value is the EVDO RSSI value
38     private int mEvdoEcio;  // This value is the EVDO Ec/Io
39     private int mEvdoSnr;   // Valid values are 0-8.  8 is the highest signal to noise ratio
40     private int mLevel;
41 
42     /** @hide */
CellSignalStrengthCdma()43     public CellSignalStrengthCdma() {
44         setDefaultValues();
45     }
46 
47     /**
48      * SignalStrength constructor for input from the HAL.
49      *
50      * Note that values received from the HAL require coersion to be compatible here. All values
51      * reported through IRadio are the negative of the actual values (which results in a positive
52      * input to this method.
53      *
54      * <p>Note that this HAL is inconsistent with UMTS-based radio techs as the value indicating
55      * that a field is unreported is negative, rather than a large(r) positive number.
56      * <p>Also note that to keep the public-facing methods of this class consistent with others,
57      * unreported values are coerced to {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE}
58      * rather than left as -1, which is a departure from SignalStrength, which is stuck with the
59      * values it currently reports.
60      *
61      * @param cdmaDbm CDMA signal strength value or CellInfo.UNAVAILABLE if invalid.
62      * @param cdmaEcio CDMA pilot/noise ratio or CellInfo.UNAVAILABLE  if invalid.
63      * @param evdoDbm negative of the EvDO signal strength value or CellInfo.UNAVAILABLE if invalid.
64      * @param evdoEcio negative of the EvDO pilot/noise ratio or CellInfo.UNAVAILABLE if invalid.
65      * @param evdoSnr an SNR value 0..8 or CellInfo.UNVAILABLE if invalid.
66      * @hide
67      */
CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr)68     public CellSignalStrengthCdma(int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio,
69             int evdoSnr) {
70         mCdmaDbm = inRangeOrUnavailable(cdmaDbm, -120, 0);
71         mCdmaEcio = inRangeOrUnavailable(cdmaEcio, -160, 0);
72         mEvdoDbm = inRangeOrUnavailable(evdoDbm, -120, 0);
73         mEvdoEcio = inRangeOrUnavailable(evdoEcio, -160, 0);
74         mEvdoSnr = inRangeOrUnavailable(evdoSnr, 0, 8);
75 
76         updateLevel(null, null);
77     }
78 
79     /** @hide */
CellSignalStrengthCdma(android.hardware.radio.V1_0.CdmaSignalStrength cdma, android.hardware.radio.V1_0.EvdoSignalStrength evdo)80     public CellSignalStrengthCdma(android.hardware.radio.V1_0.CdmaSignalStrength cdma,
81             android.hardware.radio.V1_0.EvdoSignalStrength evdo) {
82         // Convert from HAL values as part of construction.
83         this(-cdma.dbm, -cdma.ecio, -evdo.dbm, -evdo.ecio, evdo.signalNoiseRatio);
84     }
85 
86     /** @hide */
CellSignalStrengthCdma(CellSignalStrengthCdma s)87     public CellSignalStrengthCdma(CellSignalStrengthCdma s) {
88         copyFrom(s);
89     }
90 
91     /** @hide */
copyFrom(CellSignalStrengthCdma s)92     protected void copyFrom(CellSignalStrengthCdma s) {
93         mCdmaDbm = s.mCdmaDbm;
94         mCdmaEcio = s.mCdmaEcio;
95         mEvdoDbm = s.mEvdoDbm;
96         mEvdoEcio = s.mEvdoEcio;
97         mEvdoSnr = s.mEvdoSnr;
98         mLevel = s.mLevel;
99     }
100 
101     /** @hide */
102     @Override
copy()103     public CellSignalStrengthCdma copy() {
104         return new CellSignalStrengthCdma(this);
105     }
106 
107     /** @hide */
108     @Override
setDefaultValues()109     public void setDefaultValues() {
110         mCdmaDbm = CellInfo.UNAVAILABLE;
111         mCdmaEcio = CellInfo.UNAVAILABLE;
112         mEvdoDbm = CellInfo.UNAVAILABLE;
113         mEvdoEcio = CellInfo.UNAVAILABLE;
114         mEvdoSnr = CellInfo.UNAVAILABLE;
115         mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
116     }
117 
118     /** {@inheritDoc} */
119     @Override
120     @IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT)
getLevel()121     public int getLevel() {
122         return mLevel;
123     }
124 
125     /** @hide */
126     @Override
updateLevel(PersistableBundle cc, ServiceState ss)127     public void updateLevel(PersistableBundle cc, ServiceState ss) {
128         int cdmaLevel = getCdmaLevel();
129         int evdoLevel = getEvdoLevel();
130         if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
131             /* We don't know evdo, use cdma */
132             mLevel = getCdmaLevel();
133         } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) {
134             /* We don't know cdma, use evdo */
135             mLevel = getEvdoLevel();
136         } else {
137             /* We know both, use the lowest level */
138             mLevel = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel;
139         }
140     }
141 
142     /**
143      * Get the 1xRTT Level in (Android) ASU.
144      *
145      * There is no standard definition of ASU for CDMA; however, Android defines it as the
146      * the lesser of the following two results (for 1xRTT):
147      * <table>
148      *     <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead>
149      *     <tbody>
150      *         <tr><td>-75..</td><td>16</td></tr>
151      *         <tr><td>-82..-76</td><td>8</td></tr>
152      *         <tr><td>-90..-83</td><td>4</td></tr>
153      *         <tr><td>-95..-91</td><td>2</td></tr>
154      *         <tr><td>-100..-96</td><td>1</td></tr>
155      *         <tr><td>..-101</td><td>99</td></tr>
156      *     </tbody>
157      * </table>
158      * <table>
159      *     <thead><tr><th>Ec/Io Range (dB)</th><th>ASU Value</th></tr><thead>
160      *     <tbody>
161      *         <tr><td>-90..</td><td>16</td></tr>
162      *         <tr><td>-100..-91</td><td>8</td></tr>
163      *         <tr><td>-115..-101</td><td>4</td></tr>
164      *         <tr><td>-130..-116</td><td>2</td></tr>
165      *         <tr><td>--150..-131</td><td>1</td></tr>
166      *         <tr><td>..-151</td><td>99</td></tr>
167      *     </tbody>
168      * </table>
169      * @return 1xRTT Level in Android ASU {1,2,4,8,16,99}
170      */
171     @Override
172     public int getAsuLevel() {
173         final int cdmaDbm = getCdmaDbm();
174         final int cdmaEcio = getCdmaEcio();
175         int cdmaAsuLevel;
176         int ecioAsuLevel;
177 
178         if (cdmaDbm == CellInfo.UNAVAILABLE) cdmaAsuLevel = 99;
179         else if (cdmaDbm >= -75) cdmaAsuLevel = 16;
180         else if (cdmaDbm >= -82) cdmaAsuLevel = 8;
181         else if (cdmaDbm >= -90) cdmaAsuLevel = 4;
182         else if (cdmaDbm >= -95) cdmaAsuLevel = 2;
183         else if (cdmaDbm >= -100) cdmaAsuLevel = 1;
184         else cdmaAsuLevel = 99;
185 
186         // Ec/Io are in dB*10
187         if (cdmaEcio == CellInfo.UNAVAILABLE) ecioAsuLevel = 99;
188         else if (cdmaEcio >= -90) ecioAsuLevel = 16;
189         else if (cdmaEcio >= -100) ecioAsuLevel = 8;
190         else if (cdmaEcio >= -115) ecioAsuLevel = 4;
191         else if (cdmaEcio >= -130) ecioAsuLevel = 2;
192         else if (cdmaEcio >= -150) ecioAsuLevel = 1;
193         else ecioAsuLevel = 99;
194 
195         int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel;
196         if (DBG) log("getAsuLevel=" + level);
197         return level;
198     }
199 
200     /**
201      * Get cdma as level 0..4
202      */
getCdmaLevel()203     public int getCdmaLevel() {
204         final int cdmaDbm = getCdmaDbm();
205         final int cdmaEcio = getCdmaEcio();
206         int levelDbm;
207         int levelEcio;
208 
209         if (cdmaDbm == CellInfo.UNAVAILABLE) levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
210         else if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT;
211         else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD;
212         else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE;
213         else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR;
214         else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
215 
216         // Ec/Io are in dB*10
217         if (cdmaEcio == CellInfo.UNAVAILABLE) levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
218         else if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT;
219         else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD;
220         else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE;
221         else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR;
222         else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
223 
224         int level = (levelDbm < levelEcio) ? levelDbm : levelEcio;
225         if (DBG) log("getCdmaLevel=" + level);
226         return level;
227     }
228 
229     /**
230      * Get Evdo as level 0..4
231      */
getEvdoLevel()232     public int getEvdoLevel() {
233         int evdoDbm = getEvdoDbm();
234         int evdoSnr = getEvdoSnr();
235         int levelEvdoDbm;
236         int levelEvdoSnr;
237 
238         if (evdoDbm == CellInfo.UNAVAILABLE) levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
239         else if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT;
240         else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD;
241         else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE;
242         else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR;
243         else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
244 
245         if (evdoSnr == CellInfo.UNAVAILABLE) levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
246         else if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT;
247         else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD;
248         else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE;
249         else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR;
250         else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
251 
252         int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
253         if (DBG) log("getEvdoLevel=" + level);
254         return level;
255     }
256 
257     /**
258      * Get the EVDO Level in (Android) ASU.
259      *
260      * There is no standard definition of ASU for CDMA; however, Android defines it as the
261      * the lesser of the following two results (for EVDO):
262      * <table>
263      *     <thead><tr><th>RSSI Range (dBm)</th><th>ASU Value</th></tr><thead>
264      *     <tbody>
265      *         <tr><td>-65..</td><td>16</td></tr>
266      *         <tr><td>-75..-66</td><td>8</td></tr>
267      *         <tr><td>-85..-76</td><td>4</td></tr>
268      *         <tr><td>-95..-86</td><td>2</td></tr>
269      *         <tr><td>-105..-96</td><td>1</td></tr>
270      *         <tr><td>..-106</td><td>99</td></tr>
271      *     </tbody>
272      * </table>
273      * <table>
274      *     <thead><tr><th>SNR Range (unitless)</th><th>ASU Value</th></tr><thead>
275      *     <tbody>
276      *         <tr><td>7..</td><td>16</td></tr>
277      *         <tr><td>6</td><td>8</td></tr>
278      *         <tr><td>5</td><td>4</td></tr>
279      *         <tr><td>3..4</td><td>2</td></tr>
280      *         <tr><td>1..2</td><td>1</td></tr>
281      *         <tr><td>0</td><td>99</td></tr>
282      *     </tbody>
283      * </table>
284      *
285      * @return EVDO Level in Android ASU {1,2,4,8,16,99}
286      *
287      * @hide
288      */
getEvdoAsuLevel()289     public int getEvdoAsuLevel() {
290         int evdoDbm = getEvdoDbm();
291         int evdoSnr = getEvdoSnr();
292         int levelEvdoDbm;
293         int levelEvdoSnr;
294 
295         if (evdoDbm >= -65) levelEvdoDbm = 16;
296         else if (evdoDbm >= -75) levelEvdoDbm = 8;
297         else if (evdoDbm >= -85) levelEvdoDbm = 4;
298         else if (evdoDbm >= -95) levelEvdoDbm = 2;
299         else if (evdoDbm >= -105) levelEvdoDbm = 1;
300         else levelEvdoDbm = 99;
301 
302         if (evdoSnr >= 7) levelEvdoSnr = 16;
303         else if (evdoSnr >= 6) levelEvdoSnr = 8;
304         else if (evdoSnr >= 5) levelEvdoSnr = 4;
305         else if (evdoSnr >= 3) levelEvdoSnr = 2;
306         else if (evdoSnr >= 1) levelEvdoSnr = 1;
307         else levelEvdoSnr = 99;
308 
309         int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr;
310         if (DBG) log("getEvdoAsuLevel=" + level);
311         return level;
312     }
313 
314     /**
315      * Get the signal strength as dBm
316      */
317     @Override
getDbm()318     public int getDbm() {
319         int cdmaDbm = getCdmaDbm();
320         int evdoDbm = getEvdoDbm();
321 
322         // Use the lower value to be conservative
323         return (cdmaDbm < evdoDbm) ? cdmaDbm : evdoDbm;
324     }
325 
326     /**
327      * Get the CDMA RSSI value in dBm
328      */
getCdmaDbm()329     public int getCdmaDbm() {
330         return mCdmaDbm;
331     }
332 
333     /** @hide */
setCdmaDbm(int cdmaDbm)334     public void setCdmaDbm(int cdmaDbm) {
335         mCdmaDbm = cdmaDbm;
336     }
337 
338     /**
339      * Get the CDMA Ec/Io value in dB*10
340      */
getCdmaEcio()341     public int getCdmaEcio() {
342         return mCdmaEcio;
343     }
344 
345     /** @hide */
setCdmaEcio(int cdmaEcio)346     public void setCdmaEcio(int cdmaEcio) {
347         mCdmaEcio = cdmaEcio;
348     }
349 
350     /**
351      * Get the EVDO RSSI value in dBm
352      */
getEvdoDbm()353     public int getEvdoDbm() {
354         return mEvdoDbm;
355     }
356 
357     /** @hide */
setEvdoDbm(int evdoDbm)358     public void setEvdoDbm(int evdoDbm) {
359         mEvdoDbm = evdoDbm;
360     }
361 
362     /**
363      * Get the EVDO Ec/Io value in dB*10
364      */
getEvdoEcio()365     public int getEvdoEcio() {
366         return mEvdoEcio;
367     }
368 
369     /** @hide */
setEvdoEcio(int evdoEcio)370     public void setEvdoEcio(int evdoEcio) {
371         mEvdoEcio = evdoEcio;
372     }
373 
374     /**
375      * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest.
376      */
getEvdoSnr()377     public int getEvdoSnr() {
378         return mEvdoSnr;
379     }
380 
381     /** @hide */
setEvdoSnr(int evdoSnr)382     public void setEvdoSnr(int evdoSnr) {
383         mEvdoSnr = evdoSnr;
384     }
385 
386     @Override
hashCode()387     public int hashCode() {
388         return Objects.hash(mCdmaDbm, mCdmaEcio, mEvdoDbm, mEvdoEcio, mEvdoSnr, mLevel);
389     }
390 
391     private static final CellSignalStrengthCdma sInvalid = new CellSignalStrengthCdma();
392 
393     /** @hide */
394     @Override
isValid()395     public boolean isValid() {
396         return !this.equals(sInvalid);
397     }
398 
399     @Override
equals(Object o)400     public boolean equals (Object o) {
401         CellSignalStrengthCdma s;
402         if (!(o instanceof CellSignalStrengthCdma)) return false;
403         s = (CellSignalStrengthCdma) o;
404 
405         return mCdmaDbm == s.mCdmaDbm
406                 && mCdmaEcio == s.mCdmaEcio
407                 && mEvdoDbm == s.mEvdoDbm
408                 && mEvdoEcio == s.mEvdoEcio
409                 && mEvdoSnr == s.mEvdoSnr
410                 && mLevel == s.mLevel;
411     }
412 
413     /**
414      * @return string representation.
415      */
416     @Override
toString()417     public String toString() {
418         return "CellSignalStrengthCdma:"
419                 + " cdmaDbm=" + mCdmaDbm
420                 + " cdmaEcio=" + mCdmaEcio
421                 + " evdoDbm=" + mEvdoDbm
422                 + " evdoEcio=" + mEvdoEcio
423                 + " evdoSnr=" + mEvdoSnr
424                 + " level=" + mLevel;
425     }
426 
427     /** Implement the Parcelable interface */
428     @Override
writeToParcel(Parcel dest, int flags)429     public void writeToParcel(Parcel dest, int flags) {
430         if (DBG) log("writeToParcel(Parcel, int): " + toString());
431         dest.writeInt(mCdmaDbm);
432         dest.writeInt(mCdmaEcio);
433         dest.writeInt(mEvdoDbm);
434         dest.writeInt(mEvdoEcio);
435         dest.writeInt(mEvdoSnr);
436         dest.writeInt(mLevel);
437     }
438 
439     /**
440      * Construct a SignalStrength object from the given parcel
441      * where the TYPE_CDMA token is already been processed.
442      */
CellSignalStrengthCdma(Parcel in)443     private CellSignalStrengthCdma(Parcel in) {
444         // CdmaDbm, CdmaEcio, EvdoDbm and EvdoEcio are written into
445         // the parcel as positive values.
446         // Need to convert into negative values unless the value is invalid
447         mCdmaDbm = in.readInt();
448         mCdmaEcio = in.readInt();
449         mEvdoDbm = in.readInt();
450         mEvdoEcio = in.readInt();
451         mEvdoSnr = in.readInt();
452         mLevel = in.readInt();
453         if (DBG) log("CellSignalStrengthCdma(Parcel): " + toString());
454     }
455 
456     /** Implement the Parcelable interface */
457     @Override
describeContents()458     public int describeContents() {
459         return 0;
460     }
461 
462     /** Implement the Parcelable interface */
463     @SuppressWarnings("hiding")
464     public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthCdma> CREATOR =
465             new Parcelable.Creator<CellSignalStrengthCdma>() {
466         @Override
467         public CellSignalStrengthCdma createFromParcel(Parcel in) {
468             return new CellSignalStrengthCdma(in);
469         }
470 
471         @Override
472         public CellSignalStrengthCdma[] newArray(int size) {
473             return new CellSignalStrengthCdma[size];
474         }
475     };
476 
477     /**
478      * log
479      */
log(String s)480     private static void log(String s) {
481         Rlog.w(LOG_TAG, s);
482     }
483 }
484