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