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.Rlog; 23 import android.content.res.Resources; 24 25 /** 26 * Contains phone signal strength related information. 27 */ 28 public class SignalStrength implements Parcelable { 29 30 private static final String LOG_TAG = "SignalStrength"; 31 private static final boolean DBG = false; 32 33 /** @hide */ 34 public static final int SIGNAL_STRENGTH_NONE_OR_UNKNOWN = 0; 35 /** @hide */ 36 public static final int SIGNAL_STRENGTH_POOR = 1; 37 /** @hide */ 38 public static final int SIGNAL_STRENGTH_MODERATE = 2; 39 /** @hide */ 40 public static final int SIGNAL_STRENGTH_GOOD = 3; 41 /** @hide */ 42 public static final int SIGNAL_STRENGTH_GREAT = 4; 43 /** @hide */ 44 public static final int NUM_SIGNAL_STRENGTH_BINS = 5; 45 /** @hide */ 46 public static final String[] SIGNAL_STRENGTH_NAMES = { 47 "none", "poor", "moderate", "good", "great" 48 }; 49 50 /** @hide */ 51 //Use int max, as -1 is a valid value in signal strength 52 public static final int INVALID = 0x7FFFFFFF; 53 54 private static final int RSRP_THRESH_TYPE_STRICT = 0; 55 private static final int[] RSRP_THRESH_STRICT = new int[] {-140, -115, -105, -95, -85, -44}; 56 private static final int[] RSRP_THRESH_LENIENT = new int[] {-140, -128, -118, -108, -98, -44}; 57 58 59 private int mGsmSignalStrength; // Valid values are (0-31, 99) as defined in TS 27.007 8.5 60 private int mGsmBitErrorRate; // bit error rate (0-7, 99) as defined in TS 27.007 8.5 61 private int mCdmaDbm; // This value is the RSSI value 62 private int mCdmaEcio; // This value is the Ec/Io 63 private int mEvdoDbm; // This value is the EVDO RSSI value 64 private int mEvdoEcio; // This value is the EVDO Ec/Io 65 private int mEvdoSnr; // Valid values are 0-8. 8 is the highest signal to noise ratio 66 private int mLteSignalStrength; 67 private int mLteRsrp; 68 private int mLteRsrq; 69 private int mLteRssnr; 70 private int mLteCqi; 71 private int mTdScdmaRscp; 72 73 private boolean isGsm; // This value is set by the ServiceStateTracker onSignalStrengthResult 74 75 /** 76 * Create a new SignalStrength from a intent notifier Bundle 77 * 78 * This method is used by PhoneStateIntentReceiver and maybe by 79 * external applications. 80 * 81 * @param m Bundle from intent notifier 82 * @return newly created SignalStrength 83 * 84 * @hide 85 */ newFromBundle(Bundle m)86 public static SignalStrength newFromBundle(Bundle m) { 87 SignalStrength ret; 88 ret = new SignalStrength(); 89 ret.setFromNotifierBundle(m); 90 return ret; 91 } 92 93 /** 94 * Empty constructor 95 * 96 * @hide 97 */ SignalStrength()98 public SignalStrength() { 99 mGsmSignalStrength = 99; 100 mGsmBitErrorRate = -1; 101 mCdmaDbm = -1; 102 mCdmaEcio = -1; 103 mEvdoDbm = -1; 104 mEvdoEcio = -1; 105 mEvdoSnr = -1; 106 mLteSignalStrength = 99; 107 mLteRsrp = INVALID; 108 mLteRsrq = INVALID; 109 mLteRssnr = INVALID; 110 mLteCqi = INVALID; 111 mTdScdmaRscp = INVALID; 112 isGsm = true; 113 } 114 115 /** 116 * This constructor is used to create SignalStrength with default 117 * values and set the isGsmFlag with the value passed in the input 118 * 119 * @param gsmFlag true if Gsm Phone,false if Cdma phone 120 * @return newly created SignalStrength 121 * @hide 122 */ SignalStrength(boolean gsmFlag)123 public SignalStrength(boolean gsmFlag) { 124 mGsmSignalStrength = 99; 125 mGsmBitErrorRate = -1; 126 mCdmaDbm = -1; 127 mCdmaEcio = -1; 128 mEvdoDbm = -1; 129 mEvdoEcio = -1; 130 mEvdoSnr = -1; 131 mLteSignalStrength = 99; 132 mLteRsrp = INVALID; 133 mLteRsrq = INVALID; 134 mLteRssnr = INVALID; 135 mLteCqi = INVALID; 136 mTdScdmaRscp = INVALID; 137 isGsm = gsmFlag; 138 } 139 140 /** 141 * Constructor 142 * 143 * @hide 144 */ SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, int tdScdmaRscp, boolean gsmFlag)145 public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, 146 int cdmaDbm, int cdmaEcio, 147 int evdoDbm, int evdoEcio, int evdoSnr, 148 int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, 149 int tdScdmaRscp, boolean gsmFlag) { 150 initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, 151 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, 152 lteRsrq, lteRssnr, lteCqi, gsmFlag); 153 mTdScdmaRscp = tdScdmaRscp; 154 } 155 156 /** 157 * Constructor 158 * 159 * @hide 160 */ SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, boolean gsmFlag)161 public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, 162 int cdmaDbm, int cdmaEcio, 163 int evdoDbm, int evdoEcio, int evdoSnr, 164 int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, 165 boolean gsmFlag) { 166 initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, 167 evdoDbm, evdoEcio, evdoSnr, lteSignalStrength, lteRsrp, 168 lteRsrq, lteRssnr, lteCqi, gsmFlag); 169 } 170 171 /** 172 * Constructor 173 * 174 * @hide 175 */ SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, boolean gsmFlag)176 public SignalStrength(int gsmSignalStrength, int gsmBitErrorRate, 177 int cdmaDbm, int cdmaEcio, 178 int evdoDbm, int evdoEcio, int evdoSnr, 179 boolean gsmFlag) { 180 initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, 181 evdoDbm, evdoEcio, evdoSnr, 99, INVALID, 182 INVALID, INVALID, INVALID, gsmFlag); 183 } 184 185 /** 186 * Copy constructors 187 * 188 * @param s Source SignalStrength 189 * 190 * @hide 191 */ SignalStrength(SignalStrength s)192 public SignalStrength(SignalStrength s) { 193 copyFrom(s); 194 } 195 196 /** 197 * Initialize gsm/cdma values, sets lte values to defaults. 198 * 199 * @param gsmSignalStrength 200 * @param gsmBitErrorRate 201 * @param cdmaDbm 202 * @param cdmaEcio 203 * @param evdoDbm 204 * @param evdoEcio 205 * @param evdoSnr 206 * @param gsm 207 * 208 * @hide 209 */ initialize(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, boolean gsm)210 public void initialize(int gsmSignalStrength, int gsmBitErrorRate, 211 int cdmaDbm, int cdmaEcio, 212 int evdoDbm, int evdoEcio, int evdoSnr, 213 boolean gsm) { 214 initialize(gsmSignalStrength, gsmBitErrorRate, cdmaDbm, cdmaEcio, 215 evdoDbm, evdoEcio, evdoSnr, 99, INVALID, 216 INVALID, INVALID, INVALID, gsm); 217 } 218 219 /** 220 * Initialize all the values 221 * 222 * @param gsmSignalStrength 223 * @param gsmBitErrorRate 224 * @param cdmaDbm 225 * @param cdmaEcio 226 * @param evdoDbm 227 * @param evdoEcio 228 * @param evdoSnr 229 * @param lteSignalStrength 230 * @param lteRsrp 231 * @param lteRsrq 232 * @param lteRssnr 233 * @param lteCqi 234 * @param gsm 235 * 236 * @hide 237 */ initialize(int gsmSignalStrength, int gsmBitErrorRate, int cdmaDbm, int cdmaEcio, int evdoDbm, int evdoEcio, int evdoSnr, int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, boolean gsm)238 public void initialize(int gsmSignalStrength, int gsmBitErrorRate, 239 int cdmaDbm, int cdmaEcio, 240 int evdoDbm, int evdoEcio, int evdoSnr, 241 int lteSignalStrength, int lteRsrp, int lteRsrq, int lteRssnr, int lteCqi, 242 boolean gsm) { 243 mGsmSignalStrength = gsmSignalStrength; 244 mGsmBitErrorRate = gsmBitErrorRate; 245 mCdmaDbm = cdmaDbm; 246 mCdmaEcio = cdmaEcio; 247 mEvdoDbm = evdoDbm; 248 mEvdoEcio = evdoEcio; 249 mEvdoSnr = evdoSnr; 250 mLteSignalStrength = lteSignalStrength; 251 mLteRsrp = lteRsrp; 252 mLteRsrq = lteRsrq; 253 mLteRssnr = lteRssnr; 254 mLteCqi = lteCqi; 255 mTdScdmaRscp = INVALID; 256 isGsm = gsm; 257 if (DBG) log("initialize: " + toString()); 258 } 259 260 /** 261 * @hide 262 */ copyFrom(SignalStrength s)263 protected void copyFrom(SignalStrength s) { 264 mGsmSignalStrength = s.mGsmSignalStrength; 265 mGsmBitErrorRate = s.mGsmBitErrorRate; 266 mCdmaDbm = s.mCdmaDbm; 267 mCdmaEcio = s.mCdmaEcio; 268 mEvdoDbm = s.mEvdoDbm; 269 mEvdoEcio = s.mEvdoEcio; 270 mEvdoSnr = s.mEvdoSnr; 271 mLteSignalStrength = s.mLteSignalStrength; 272 mLteRsrp = s.mLteRsrp; 273 mLteRsrq = s.mLteRsrq; 274 mLteRssnr = s.mLteRssnr; 275 mLteCqi = s.mLteCqi; 276 mTdScdmaRscp = s.mTdScdmaRscp; 277 isGsm = s.isGsm; 278 } 279 280 /** 281 * Construct a SignalStrength object from the given parcel. 282 * 283 * @hide 284 */ SignalStrength(Parcel in)285 public SignalStrength(Parcel in) { 286 if (DBG) log("Size of signalstrength parcel:" + in.dataSize()); 287 288 mGsmSignalStrength = in.readInt(); 289 mGsmBitErrorRate = in.readInt(); 290 mCdmaDbm = in.readInt(); 291 mCdmaEcio = in.readInt(); 292 mEvdoDbm = in.readInt(); 293 mEvdoEcio = in.readInt(); 294 mEvdoSnr = in.readInt(); 295 mLteSignalStrength = in.readInt(); 296 mLteRsrp = in.readInt(); 297 mLteRsrq = in.readInt(); 298 mLteRssnr = in.readInt(); 299 mLteCqi = in.readInt(); 300 mTdScdmaRscp = in.readInt(); 301 isGsm = (in.readInt() != 0); 302 } 303 304 /** 305 * Make a SignalStrength object from the given parcel as passed up by 306 * the ril which does not have isGsm. isGsm will be changed by ServiceStateTracker 307 * so the default is a don't care. 308 * 309 * @hide 310 */ makeSignalStrengthFromRilParcel(Parcel in)311 public static SignalStrength makeSignalStrengthFromRilParcel(Parcel in) { 312 if (DBG) log("Size of signalstrength parcel:" + in.dataSize()); 313 314 SignalStrength ss = new SignalStrength(); 315 ss.mGsmSignalStrength = in.readInt(); 316 ss.mGsmBitErrorRate = in.readInt(); 317 ss.mCdmaDbm = in.readInt(); 318 ss.mCdmaEcio = in.readInt(); 319 ss.mEvdoDbm = in.readInt(); 320 ss.mEvdoEcio = in.readInt(); 321 ss.mEvdoSnr = in.readInt(); 322 ss.mLteSignalStrength = in.readInt(); 323 ss.mLteRsrp = in.readInt(); 324 ss.mLteRsrq = in.readInt(); 325 ss.mLteRssnr = in.readInt(); 326 ss.mLteCqi = in.readInt(); 327 ss.mTdScdmaRscp = in.readInt(); 328 return ss; 329 } 330 331 /** 332 * {@link Parcelable#writeToParcel} 333 */ writeToParcel(Parcel out, int flags)334 public void writeToParcel(Parcel out, int flags) { 335 out.writeInt(mGsmSignalStrength); 336 out.writeInt(mGsmBitErrorRate); 337 out.writeInt(mCdmaDbm); 338 out.writeInt(mCdmaEcio); 339 out.writeInt(mEvdoDbm); 340 out.writeInt(mEvdoEcio); 341 out.writeInt(mEvdoSnr); 342 out.writeInt(mLteSignalStrength); 343 out.writeInt(mLteRsrp); 344 out.writeInt(mLteRsrq); 345 out.writeInt(mLteRssnr); 346 out.writeInt(mLteCqi); 347 out.writeInt(mTdScdmaRscp); 348 out.writeInt(isGsm ? 1 : 0); 349 } 350 351 /** 352 * {@link Parcelable#describeContents} 353 */ describeContents()354 public int describeContents() { 355 return 0; 356 } 357 358 /** 359 * {@link Parcelable.Creator} 360 * 361 * @hide 362 */ 363 public static final Parcelable.Creator<SignalStrength> CREATOR = new Parcelable.Creator() { 364 public SignalStrength createFromParcel(Parcel in) { 365 return new SignalStrength(in); 366 } 367 368 public SignalStrength[] newArray(int size) { 369 return new SignalStrength[size]; 370 } 371 }; 372 373 /** 374 * Validate the individual signal strength fields as per the range 375 * specified in ril.h 376 * Set to invalid any field that is not in the valid range 377 * Cdma, evdo, lte rsrp & rsrq values are sign converted 378 * when received from ril interface 379 * 380 * @return 381 * Valid values for all signalstrength fields 382 * @hide 383 */ validateInput()384 public void validateInput() { 385 if (DBG) log("Signal before validate=" + this); 386 // TS 27.007 8.5 387 mGsmSignalStrength = mGsmSignalStrength >= 0 ? mGsmSignalStrength : 99; 388 // BER no change; 389 390 mCdmaDbm = mCdmaDbm > 0 ? -mCdmaDbm : -120; 391 mCdmaEcio = (mCdmaEcio > 0) ? -mCdmaEcio : -160; 392 393 mEvdoDbm = (mEvdoDbm > 0) ? -mEvdoDbm : -120; 394 mEvdoEcio = (mEvdoEcio >= 0) ? -mEvdoEcio : -1; 395 mEvdoSnr = ((mEvdoSnr > 0) && (mEvdoSnr <= 8)) ? mEvdoSnr : -1; 396 397 // TS 36.214 Physical Layer Section 5.1.3, TS 36.331 RRC 398 mLteSignalStrength = (mLteSignalStrength >= 0) ? mLteSignalStrength : 99; 399 mLteRsrp = ((mLteRsrp >= 44) && (mLteRsrp <= 140)) ? -mLteRsrp : SignalStrength.INVALID; 400 mLteRsrq = ((mLteRsrq >= 3) && (mLteRsrq <= 20)) ? -mLteRsrq : SignalStrength.INVALID; 401 mLteRssnr = ((mLteRssnr >= -200) && (mLteRssnr <= 300)) ? mLteRssnr 402 : SignalStrength.INVALID; 403 404 mTdScdmaRscp = ((mTdScdmaRscp >= 25) && (mTdScdmaRscp <= 120)) 405 ? -mTdScdmaRscp : SignalStrength.INVALID; 406 // Cqi no change 407 if (DBG) log("Signal after validate=" + this); 408 } 409 410 /** 411 * @param true - Gsm, Lte phones 412 * false - Cdma phones 413 * 414 * Used by voice phone to set the isGsm 415 * flag 416 * @hide 417 */ setGsm(boolean gsmFlag)418 public void setGsm(boolean gsmFlag) { 419 isGsm = gsmFlag; 420 } 421 422 /** 423 * Get the GSM Signal Strength, valid values are (0-31, 99) as defined in TS 424 * 27.007 8.5 425 */ getGsmSignalStrength()426 public int getGsmSignalStrength() { 427 return this.mGsmSignalStrength; 428 } 429 430 /** 431 * Get the GSM bit error rate (0-7, 99) as defined in TS 27.007 8.5 432 */ getGsmBitErrorRate()433 public int getGsmBitErrorRate() { 434 return this.mGsmBitErrorRate; 435 } 436 437 /** 438 * Get the CDMA RSSI value in dBm 439 */ getCdmaDbm()440 public int getCdmaDbm() { 441 return this.mCdmaDbm; 442 } 443 444 /** 445 * Get the CDMA Ec/Io value in dB*10 446 */ getCdmaEcio()447 public int getCdmaEcio() { 448 return this.mCdmaEcio; 449 } 450 451 /** 452 * Get the EVDO RSSI value in dBm 453 */ getEvdoDbm()454 public int getEvdoDbm() { 455 return this.mEvdoDbm; 456 } 457 458 /** 459 * Get the EVDO Ec/Io value in dB*10 460 */ getEvdoEcio()461 public int getEvdoEcio() { 462 return this.mEvdoEcio; 463 } 464 465 /** 466 * Get the signal to noise ratio. Valid values are 0-8. 8 is the highest. 467 */ getEvdoSnr()468 public int getEvdoSnr() { 469 return this.mEvdoSnr; 470 } 471 472 /** @hide */ getLteSignalStrength()473 public int getLteSignalStrength() { 474 return mLteSignalStrength; 475 } 476 477 /** @hide */ getLteRsrp()478 public int getLteRsrp() { 479 return mLteRsrp; 480 } 481 482 /** @hide */ getLteRsrq()483 public int getLteRsrq() { 484 return mLteRsrq; 485 } 486 487 /** @hide */ getLteRssnr()488 public int getLteRssnr() { 489 return mLteRssnr; 490 } 491 492 /** @hide */ getLteCqi()493 public int getLteCqi() { 494 return mLteCqi; 495 } 496 497 /** 498 * Retrieve an abstract level value for the overall signal strength. 499 * 500 * @return a single integer from 0 to 4 representing the general signal quality. 501 * This may take into account many different radio technology inputs. 502 * 0 represents very poor signal strength 503 * while 4 represents a very strong signal strength. 504 */ getLevel()505 public int getLevel() { 506 int level = 0; 507 508 if (isGsm) { 509 level = getLteLevel(); 510 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 511 level = getTdScdmaLevel(); 512 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 513 level = getGsmLevel(); 514 } 515 } 516 } else { 517 int cdmaLevel = getCdmaLevel(); 518 int evdoLevel = getEvdoLevel(); 519 if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 520 /* We don't know evdo, use cdma */ 521 level = cdmaLevel; 522 } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 523 /* We don't know cdma, use evdo */ 524 level = evdoLevel; 525 } else { 526 /* We know both, use the lowest level */ 527 level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel; 528 } 529 } 530 if (DBG) log("getLevel=" + level); 531 return level; 532 } 533 534 /** 535 * Get the signal level as an asu value between 0..31, 99 is unknown 536 * 537 * @hide 538 */ 539 public int getAsuLevel() { 540 int asuLevel = 0; 541 if (isGsm) { 542 if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 543 if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 544 asuLevel = getGsmAsuLevel(); 545 } else { 546 asuLevel = getTdScdmaAsuLevel(); 547 } 548 } else { 549 asuLevel = getLteAsuLevel(); 550 } 551 } else { 552 int cdmaAsuLevel = getCdmaAsuLevel(); 553 int evdoAsuLevel = getEvdoAsuLevel(); 554 if (evdoAsuLevel == 0) { 555 /* We don't know evdo use, cdma */ 556 asuLevel = cdmaAsuLevel; 557 } else if (cdmaAsuLevel == 0) { 558 /* We don't know cdma use, evdo */ 559 asuLevel = evdoAsuLevel; 560 } else { 561 /* We know both, use the lowest level */ 562 asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel; 563 } 564 } 565 if (DBG) log("getAsuLevel=" + asuLevel); 566 return asuLevel; 567 } 568 569 /** 570 * Get the signal strength as dBm 571 * 572 * @hide 573 */ 574 public int getDbm() { 575 int dBm = INVALID; 576 577 if(isGsm()) { 578 dBm = getLteDbm(); 579 if (dBm == INVALID) { 580 if (getTdScdmaLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 581 dBm = getGsmDbm(); 582 } else { 583 dBm = getTdScdmaDbm(); 584 } 585 } 586 } else { 587 int cdmaDbm = getCdmaDbm(); 588 int evdoDbm = getEvdoDbm(); 589 590 return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm 591 : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm)); 592 } 593 if (DBG) log("getDbm=" + dBm); 594 return dBm; 595 } 596 597 /** 598 * Get Gsm signal strength as dBm 599 * 600 * @hide 601 */ 602 public int getGsmDbm() { 603 int dBm; 604 605 int gsmSignalStrength = getGsmSignalStrength(); 606 int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 607 if (asu != -1) { 608 dBm = -113 + (2 * asu); 609 } else { 610 dBm = -1; 611 } 612 if (DBG) log("getGsmDbm=" + dBm); 613 return dBm; 614 } 615 616 /** 617 * Get gsm as level 0..4 618 * 619 * @hide 620 */ 621 public int getGsmLevel() { 622 int level; 623 624 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 625 // asu = 0 (-113dB or less) is very weak 626 // signal, its better to show 0 bars to the user in such cases. 627 // asu = 99 is a special case, where the signal strength is unknown. 628 int asu = getGsmSignalStrength(); 629 if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 630 else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT; 631 else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD; 632 else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE; 633 else level = SIGNAL_STRENGTH_POOR; 634 if (DBG) log("getGsmLevel=" + level); 635 return level; 636 } 637 638 /** 639 * Get the gsm signal level as an asu value between 0..31, 99 is unknown 640 * 641 * @hide 642 */ 643 public int getGsmAsuLevel() { 644 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 645 // asu = 0 (-113dB or less) is very weak 646 // signal, its better to show 0 bars to the user in such cases. 647 // asu = 99 is a special case, where the signal strength is unknown. 648 int level = getGsmSignalStrength(); 649 if (DBG) log("getGsmAsuLevel=" + level); 650 return level; 651 } 652 653 /** 654 * Get cdma as level 0..4 655 * 656 * @hide 657 */ 658 public int getCdmaLevel() { 659 final int cdmaDbm = getCdmaDbm(); 660 final int cdmaEcio = getCdmaEcio(); 661 int levelDbm; 662 int levelEcio; 663 664 if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT; 665 else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD; 666 else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE; 667 else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR; 668 else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 669 670 // Ec/Io are in dB*10 671 if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT; 672 else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD; 673 else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE; 674 else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR; 675 else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 676 677 int level = (levelDbm < levelEcio) ? levelDbm : levelEcio; 678 if (DBG) log("getCdmaLevel=" + level); 679 return level; 680 } 681 682 /** 683 * Get the cdma signal level as an asu value between 0..31, 99 is unknown 684 * 685 * @hide 686 */ getCdmaAsuLevel()687 public int getCdmaAsuLevel() { 688 final int cdmaDbm = getCdmaDbm(); 689 final int cdmaEcio = getCdmaEcio(); 690 int cdmaAsuLevel; 691 int ecioAsuLevel; 692 693 if (cdmaDbm >= -75) cdmaAsuLevel = 16; 694 else if (cdmaDbm >= -82) cdmaAsuLevel = 8; 695 else if (cdmaDbm >= -90) cdmaAsuLevel = 4; 696 else if (cdmaDbm >= -95) cdmaAsuLevel = 2; 697 else if (cdmaDbm >= -100) cdmaAsuLevel = 1; 698 else cdmaAsuLevel = 99; 699 700 // Ec/Io are in dB*10 701 if (cdmaEcio >= -90) ecioAsuLevel = 16; 702 else if (cdmaEcio >= -100) ecioAsuLevel = 8; 703 else if (cdmaEcio >= -115) ecioAsuLevel = 4; 704 else if (cdmaEcio >= -130) ecioAsuLevel = 2; 705 else if (cdmaEcio >= -150) ecioAsuLevel = 1; 706 else ecioAsuLevel = 99; 707 708 int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel; 709 if (DBG) log("getCdmaAsuLevel=" + level); 710 return level; 711 } 712 713 /** 714 * Get Evdo as level 0..4 715 * 716 * @hide 717 */ getEvdoLevel()718 public int getEvdoLevel() { 719 int evdoDbm = getEvdoDbm(); 720 int evdoSnr = getEvdoSnr(); 721 int levelEvdoDbm; 722 int levelEvdoSnr; 723 724 if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT; 725 else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD; 726 else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE; 727 else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR; 728 else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 729 730 if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT; 731 else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD; 732 else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE; 733 else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR; 734 else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 735 736 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 737 if (DBG) log("getEvdoLevel=" + level); 738 return level; 739 } 740 741 /** 742 * Get the evdo signal level as an asu value between 0..31, 99 is unknown 743 * 744 * @hide 745 */ getEvdoAsuLevel()746 public int getEvdoAsuLevel() { 747 int evdoDbm = getEvdoDbm(); 748 int evdoSnr = getEvdoSnr(); 749 int levelEvdoDbm; 750 int levelEvdoSnr; 751 752 if (evdoDbm >= -65) levelEvdoDbm = 16; 753 else if (evdoDbm >= -75) levelEvdoDbm = 8; 754 else if (evdoDbm >= -85) levelEvdoDbm = 4; 755 else if (evdoDbm >= -95) levelEvdoDbm = 2; 756 else if (evdoDbm >= -105) levelEvdoDbm = 1; 757 else levelEvdoDbm = 99; 758 759 if (evdoSnr >= 7) levelEvdoSnr = 16; 760 else if (evdoSnr >= 6) levelEvdoSnr = 8; 761 else if (evdoSnr >= 5) levelEvdoSnr = 4; 762 else if (evdoSnr >= 3) levelEvdoSnr = 2; 763 else if (evdoSnr >= 1) levelEvdoSnr = 1; 764 else levelEvdoSnr = 99; 765 766 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 767 if (DBG) log("getEvdoAsuLevel=" + level); 768 return level; 769 } 770 771 /** 772 * Get LTE as dBm 773 * 774 * @hide 775 */ getLteDbm()776 public int getLteDbm() { 777 return mLteRsrp; 778 } 779 780 /** 781 * Get LTE as level 0..4 782 * 783 * @hide 784 */ getLteLevel()785 public int getLteLevel() { 786 /* 787 * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received 788 * signal + noise RSRP = reference signal dBm RSRQ = quality of signal 789 * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio 790 * = -10log P1/P2 dB 791 */ 792 int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1; 793 794 int rsrpThreshType = Resources.getSystem().getInteger(com.android.internal.R.integer. 795 config_LTE_RSRP_threshold_type); 796 int[] threshRsrp; 797 if (rsrpThreshType == RSRP_THRESH_TYPE_STRICT) { 798 threshRsrp = RSRP_THRESH_STRICT; 799 } else { 800 threshRsrp = RSRP_THRESH_LENIENT; 801 } 802 803 if (mLteRsrp > threshRsrp[5]) rsrpIconLevel = -1; 804 else if (mLteRsrp >= threshRsrp[4]) rsrpIconLevel = SIGNAL_STRENGTH_GREAT; 805 else if (mLteRsrp >= threshRsrp[3]) rsrpIconLevel = SIGNAL_STRENGTH_GOOD; 806 else if (mLteRsrp >= threshRsrp[2]) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE; 807 else if (mLteRsrp >= threshRsrp[1]) rsrpIconLevel = SIGNAL_STRENGTH_POOR; 808 else if (mLteRsrp >= threshRsrp[0]) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 809 810 /* 811 * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5 812 * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars 813 * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna 814 * Icon Only 815 */ 816 if (mLteRssnr > 300) snrIconLevel = -1; 817 else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT; 818 else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD; 819 else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE; 820 else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR; 821 else if (mLteRssnr >= -200) 822 snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 823 824 if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:" 825 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel); 826 827 /* Choose a measurement type to use for notification */ 828 if (snrIconLevel != -1 && rsrpIconLevel != -1) { 829 /* 830 * The number of bars displayed shall be the smaller of the bars 831 * associated with LTE RSRP and the bars associated with the LTE 832 * RS_SNR 833 */ 834 return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel); 835 } 836 837 if (snrIconLevel != -1) return snrIconLevel; 838 839 if (rsrpIconLevel != -1) return rsrpIconLevel; 840 841 /* Valid values are (0-63, 99) as defined in TS 36.331 */ 842 if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 843 else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT; 844 else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD; 845 else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE; 846 else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR; 847 848 if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:" 849 + rssiIconLevel); 850 return rssiIconLevel; 851 852 } 853 /** 854 * Get the LTE signal level as an asu value between 0..97, 99 is unknown 855 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 856 * 857 * @hide 858 */ getLteAsuLevel()859 public int getLteAsuLevel() { 860 int lteAsuLevel = 99; 861 int lteDbm = getLteDbm(); 862 /* 863 * 3GPP 27.007 (Ver 10.3.0) Sec 8.69 864 * 0 -140 dBm or less 865 * 1 -139 dBm 866 * 2...96 -138... -44 dBm 867 * 97 -43 dBm or greater 868 * 255 not known or not detectable 869 */ 870 /* 871 * validateInput will always give a valid range between -140 t0 -44 as 872 * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255 873 * and not 97 or 0 874 */ 875 if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255; 876 else lteAsuLevel = lteDbm + 140; 877 if (DBG) log("Lte Asu level: "+lteAsuLevel); 878 return lteAsuLevel; 879 } 880 881 /** 882 * @return true if this is for GSM 883 */ isGsm()884 public boolean isGsm() { 885 return this.isGsm; 886 } 887 888 /** 889 * @return get TD_SCDMA dbm 890 * 891 * @hide 892 */ getTdScdmaDbm()893 public int getTdScdmaDbm() { 894 return this.mTdScdmaRscp; 895 } 896 897 /** 898 * Get TD-SCDMA as level 0..4 899 * Range : 25 to 120 900 * INT_MAX: 0x7FFFFFFF denotes invalid value 901 * Reference: 3GPP TS 25.123, section 9.1.1.1 902 * 903 * @hide 904 */ getTdScdmaLevel()905 public int getTdScdmaLevel() { 906 final int tdScdmaDbm = getTdScdmaDbm(); 907 int level; 908 909 if ((tdScdmaDbm > -25) || (tdScdmaDbm == SignalStrength.INVALID)) 910 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 911 else if (tdScdmaDbm >= -49) level = SIGNAL_STRENGTH_GREAT; 912 else if (tdScdmaDbm >= -73) level = SIGNAL_STRENGTH_GOOD; 913 else if (tdScdmaDbm >= -97) level = SIGNAL_STRENGTH_MODERATE; 914 else if (tdScdmaDbm >= -110) level = SIGNAL_STRENGTH_POOR; 915 else level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 916 917 if (DBG) log("getTdScdmaLevel = " + level); 918 return level; 919 } 920 921 /** 922 * Get the TD-SCDMA signal level as an asu value. 923 * 924 * @hide 925 */ getTdScdmaAsuLevel()926 public int getTdScdmaAsuLevel() { 927 final int tdScdmaDbm = getTdScdmaDbm(); 928 int tdScdmaAsuLevel; 929 930 if (tdScdmaDbm == INVALID) tdScdmaAsuLevel = 255; 931 else tdScdmaAsuLevel = tdScdmaDbm + 120; 932 if (DBG) log("TD-SCDMA Asu level: " + tdScdmaAsuLevel); 933 return tdScdmaAsuLevel; 934 } 935 936 /** 937 * @return hash code 938 */ 939 @Override hashCode()940 public int hashCode() { 941 int primeNum = 31; 942 return ((mGsmSignalStrength * primeNum) 943 + (mGsmBitErrorRate * primeNum) 944 + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum) 945 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum) 946 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum) 947 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum) 948 + (mTdScdmaRscp * primeNum) + (isGsm ? 1 : 0)); 949 } 950 951 /** 952 * @return true if the signal strengths are the same 953 */ 954 @Override equals(Object o)955 public boolean equals (Object o) { 956 SignalStrength s; 957 958 try { 959 s = (SignalStrength) o; 960 } catch (ClassCastException ex) { 961 return false; 962 } 963 964 if (o == null) { 965 return false; 966 } 967 968 return (mGsmSignalStrength == s.mGsmSignalStrength 969 && mGsmBitErrorRate == s.mGsmBitErrorRate 970 && mCdmaDbm == s.mCdmaDbm 971 && mCdmaEcio == s.mCdmaEcio 972 && mEvdoDbm == s.mEvdoDbm 973 && mEvdoEcio == s.mEvdoEcio 974 && mEvdoSnr == s.mEvdoSnr 975 && mLteSignalStrength == s.mLteSignalStrength 976 && mLteRsrp == s.mLteRsrp 977 && mLteRsrq == s.mLteRsrq 978 && mLteRssnr == s.mLteRssnr 979 && mLteCqi == s.mLteCqi 980 && mTdScdmaRscp == s.mTdScdmaRscp 981 && isGsm == s.isGsm); 982 } 983 984 /** 985 * @return string representation. 986 */ 987 @Override toString()988 public String toString() { 989 return ("SignalStrength:" 990 + " " + mGsmSignalStrength 991 + " " + mGsmBitErrorRate 992 + " " + mCdmaDbm 993 + " " + mCdmaEcio 994 + " " + mEvdoDbm 995 + " " + mEvdoEcio 996 + " " + mEvdoSnr 997 + " " + mLteSignalStrength 998 + " " + mLteRsrp 999 + " " + mLteRsrq 1000 + " " + mLteRssnr 1001 + " " + mLteCqi 1002 + " " + mTdScdmaRscp 1003 + " " + (isGsm ? "gsm|lte" : "cdma")); 1004 } 1005 1006 /** 1007 * Set SignalStrength based on intent notifier map 1008 * 1009 * @param m intent notifier map 1010 * @hide 1011 */ setFromNotifierBundle(Bundle m)1012 private void setFromNotifierBundle(Bundle m) { 1013 mGsmSignalStrength = m.getInt("GsmSignalStrength"); 1014 mGsmBitErrorRate = m.getInt("GsmBitErrorRate"); 1015 mCdmaDbm = m.getInt("CdmaDbm"); 1016 mCdmaEcio = m.getInt("CdmaEcio"); 1017 mEvdoDbm = m.getInt("EvdoDbm"); 1018 mEvdoEcio = m.getInt("EvdoEcio"); 1019 mEvdoSnr = m.getInt("EvdoSnr"); 1020 mLteSignalStrength = m.getInt("LteSignalStrength"); 1021 mLteRsrp = m.getInt("LteRsrp"); 1022 mLteRsrq = m.getInt("LteRsrq"); 1023 mLteRssnr = m.getInt("LteRssnr"); 1024 mLteCqi = m.getInt("LteCqi"); 1025 mTdScdmaRscp = m.getInt("TdScdma"); 1026 isGsm = m.getBoolean("isGsm"); 1027 } 1028 1029 /** 1030 * Set intent notifier Bundle based on SignalStrength 1031 * 1032 * @param m intent notifier Bundle 1033 * @hide 1034 */ fillInNotifierBundle(Bundle m)1035 public void fillInNotifierBundle(Bundle m) { 1036 m.putInt("GsmSignalStrength", mGsmSignalStrength); 1037 m.putInt("GsmBitErrorRate", mGsmBitErrorRate); 1038 m.putInt("CdmaDbm", mCdmaDbm); 1039 m.putInt("CdmaEcio", mCdmaEcio); 1040 m.putInt("EvdoDbm", mEvdoDbm); 1041 m.putInt("EvdoEcio", mEvdoEcio); 1042 m.putInt("EvdoSnr", mEvdoSnr); 1043 m.putInt("LteSignalStrength", mLteSignalStrength); 1044 m.putInt("LteRsrp", mLteRsrp); 1045 m.putInt("LteRsrq", mLteRsrq); 1046 m.putInt("LteRssnr", mLteRssnr); 1047 m.putInt("LteCqi", mLteCqi); 1048 m.putInt("TdScdma", mTdScdmaRscp); 1049 m.putBoolean("isGsm", Boolean.valueOf(isGsm)); 1050 } 1051 1052 /** 1053 * log 1054 */ log(String s)1055 private static void log(String s) { 1056 Rlog.w(LOG_TAG, s); 1057 } 1058 } 1059