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 /**
24  * Wcdma signal strength related information.
25  */
26 public final class CellSignalStrengthWcdma extends CellSignalStrength implements Parcelable {
27 
28     private static final String LOG_TAG = "CellSignalStrengthWcdma";
29     private static final boolean DBG = false;
30 
31     private static final int WCDMA_SIGNAL_STRENGTH_GREAT = 12;
32     private static final int WCDMA_SIGNAL_STRENGTH_GOOD = 8;
33     private static final int WCDMA_SIGNAL_STRENGTH_MODERATE = 5;
34 
35     private int mSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5
36     private int mBitErrorRate;   // bit error rate (0-7, 99) as defined in TS 27.007 8.5
37 
38     /**
39      * Empty constructor
40      *
41      * @hide
42      */
CellSignalStrengthWcdma()43     public CellSignalStrengthWcdma() {
44         setDefaultValues();
45     }
46 
47     /**
48      * Constructor
49      *
50      * @hide
51      */
CellSignalStrengthWcdma(int ss, int ber)52     public CellSignalStrengthWcdma(int ss, int ber) {
53         initialize(ss, ber);
54     }
55 
56     /**
57      * Copy constructors
58      *
59      * @param s Source SignalStrength
60      *
61      * @hide
62      */
CellSignalStrengthWcdma(CellSignalStrengthWcdma s)63     public CellSignalStrengthWcdma(CellSignalStrengthWcdma s) {
64         copyFrom(s);
65     }
66 
67     /**
68      * Initialize all the values
69      *
70      * @param ss SignalStrength as ASU value
71      * @param ber is Bit Error Rate
72      *
73      * @hide
74      */
initialize(int ss, int ber)75     public void initialize(int ss, int ber) {
76         mSignalStrength = ss;
77         mBitErrorRate = ber;
78     }
79 
80     /**
81      * @hide
82      */
copyFrom(CellSignalStrengthWcdma s)83     protected void copyFrom(CellSignalStrengthWcdma s) {
84         mSignalStrength = s.mSignalStrength;
85         mBitErrorRate = s.mBitErrorRate;
86     }
87 
88     /**
89      * @hide
90      */
91     @Override
copy()92     public CellSignalStrengthWcdma copy() {
93         return new CellSignalStrengthWcdma(this);
94     }
95 
96     /** @hide */
97     @Override
setDefaultValues()98     public void setDefaultValues() {
99         mSignalStrength = Integer.MAX_VALUE;
100         mBitErrorRate = Integer.MAX_VALUE;
101     }
102 
103     /**
104      * Get signal level as an int from 0..4
105      */
106     @Override
getLevel()107     public int getLevel() {
108         int level;
109 
110         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
111         // asu = 0 (-113dB or less) is very weak
112         // signal, its better to show 0 bars to the user in such cases.
113         // asu = 99 is a special case, where the signal strength is unknown.
114         int asu = mSignalStrength;
115         if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
116         else if (asu >= WCDMA_SIGNAL_STRENGTH_GREAT) level = SIGNAL_STRENGTH_GREAT;
117         else if (asu >= WCDMA_SIGNAL_STRENGTH_GOOD)  level = SIGNAL_STRENGTH_GOOD;
118         else if (asu >= WCDMA_SIGNAL_STRENGTH_MODERATE)  level = SIGNAL_STRENGTH_MODERATE;
119         else level = SIGNAL_STRENGTH_POOR;
120         if (DBG) log("getLevel=" + level);
121         return level;
122     }
123 
124     /**
125      * Get the signal strength as dBm
126      */
127     @Override
getDbm()128     public int getDbm() {
129         int dBm;
130 
131         int level = mSignalStrength;
132         int asu = (level == 99 ? Integer.MAX_VALUE : level);
133         if (asu != Integer.MAX_VALUE) {
134             dBm = -113 + (2 * asu);
135         } else {
136             dBm = Integer.MAX_VALUE;
137         }
138         if (DBG) log("getDbm=" + dBm);
139         return dBm;
140     }
141 
142     /**
143      * Get the signal level as an asu value between 0..31, 99 is unknown
144      * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69
145      */
146     @Override
getAsuLevel()147     public int getAsuLevel() {
148         // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5
149         // asu = 0 (-113dB or less) is very weak
150         // signal, its better to show 0 bars to the user in such cases.
151         // asu = 99 is a special case, where the signal strength is unknown.
152         int level = mSignalStrength;
153         if (DBG) log("getAsuLevel=" + level);
154         return level;
155     }
156 
157     @Override
hashCode()158     public int hashCode() {
159         int primeNum = 31;
160         return (mSignalStrength * primeNum) + (mBitErrorRate * primeNum);
161     }
162 
163     @Override
equals(Object o)164     public boolean equals (Object o) {
165         CellSignalStrengthWcdma s;
166 
167         try {
168             s = (CellSignalStrengthWcdma) o;
169         } catch (ClassCastException ex) {
170             return false;
171         }
172 
173         if (o == null) {
174             return false;
175         }
176 
177         return mSignalStrength == s.mSignalStrength && mBitErrorRate == s.mBitErrorRate;
178     }
179 
180     /**
181      * @return string representation.
182      */
183     @Override
toString()184     public String toString() {
185         return "CellSignalStrengthWcdma:"
186                 + " ss=" + mSignalStrength
187                 + " ber=" + mBitErrorRate;
188     }
189 
190     /** Implement the Parcelable interface */
191     @Override
writeToParcel(Parcel dest, int flags)192     public void writeToParcel(Parcel dest, int flags) {
193         if (DBG) log("writeToParcel(Parcel, int): " + toString());
194         dest.writeInt(mSignalStrength);
195         dest.writeInt(mBitErrorRate);
196     }
197 
198     /**
199      * Construct a SignalStrength object from the given parcel
200      * where the token is already been processed.
201      */
CellSignalStrengthWcdma(Parcel in)202     private CellSignalStrengthWcdma(Parcel in) {
203         mSignalStrength = in.readInt();
204         mBitErrorRate = in.readInt();
205         if (DBG) log("CellSignalStrengthWcdma(Parcel): " + toString());
206     }
207 
208     /** Implement the Parcelable interface */
209     @Override
describeContents()210     public int describeContents() {
211         return 0;
212     }
213 
214     /** Implement the Parcelable interface */
215     @SuppressWarnings("hiding")
216     public static final Parcelable.Creator<CellSignalStrengthWcdma> CREATOR =
217             new Parcelable.Creator<CellSignalStrengthWcdma>() {
218         @Override
219         public CellSignalStrengthWcdma createFromParcel(Parcel in) {
220             return new CellSignalStrengthWcdma(in);
221         }
222 
223         @Override
224         public CellSignalStrengthWcdma[] newArray(int size) {
225             return new CellSignalStrengthWcdma[size];
226         }
227     };
228 
229     /**
230      * log
231      */
log(String s)232     private static void log(String s) {
233         Rlog.w(LOG_TAG, s);
234     }
235 }
236