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