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 * Get signal level as an int from 0..4 473 * 474 * @hide 475 */ getLevel()476 public int getLevel() { 477 int level; 478 479 if (isGsm) { 480 level = getLteLevel(); 481 if (level == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 482 level = getGsmLevel(); 483 } 484 } else { 485 int cdmaLevel = getCdmaLevel(); 486 int evdoLevel = getEvdoLevel(); 487 if (evdoLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 488 /* We don't know evdo, use cdma */ 489 level = cdmaLevel; 490 } else if (cdmaLevel == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 491 /* We don't know cdma, use evdo */ 492 level = evdoLevel; 493 } else { 494 /* We know both, use the lowest level */ 495 level = cdmaLevel < evdoLevel ? cdmaLevel : evdoLevel; 496 } 497 } 498 if (DBG) log("getLevel=" + level); 499 return level; 500 } 501 502 /** 503 * Get the signal level as an asu value between 0..31, 99 is unknown 504 * 505 * @hide 506 */ 507 public int getAsuLevel() { 508 int asuLevel; 509 if (isGsm) { 510 if (getLteLevel() == SIGNAL_STRENGTH_NONE_OR_UNKNOWN) { 511 asuLevel = getGsmAsuLevel(); 512 } else { 513 asuLevel = getLteAsuLevel(); 514 } 515 } else { 516 int cdmaAsuLevel = getCdmaAsuLevel(); 517 int evdoAsuLevel = getEvdoAsuLevel(); 518 if (evdoAsuLevel == 0) { 519 /* We don't know evdo use, cdma */ 520 asuLevel = cdmaAsuLevel; 521 } else if (cdmaAsuLevel == 0) { 522 /* We don't know cdma use, evdo */ 523 asuLevel = evdoAsuLevel; 524 } else { 525 /* We know both, use the lowest level */ 526 asuLevel = cdmaAsuLevel < evdoAsuLevel ? cdmaAsuLevel : evdoAsuLevel; 527 } 528 } 529 if (DBG) log("getAsuLevel=" + asuLevel); 530 return asuLevel; 531 } 532 533 /** 534 * Get the signal strength as dBm 535 * 536 * @hide 537 */ 538 public int getDbm() { 539 int dBm; 540 541 if(isGsm()) { 542 dBm = getLteDbm(); 543 if (dBm == INVALID) { 544 dBm = getGsmDbm(); 545 } 546 } else { 547 int cdmaDbm = getCdmaDbm(); 548 int evdoDbm = getEvdoDbm(); 549 550 return (evdoDbm == -120) ? cdmaDbm : ((cdmaDbm == -120) ? evdoDbm 551 : (cdmaDbm < evdoDbm ? cdmaDbm : evdoDbm)); 552 } 553 if (DBG) log("getDbm=" + dBm); 554 return dBm; 555 } 556 557 /** 558 * Get Gsm signal strength as dBm 559 * 560 * @hide 561 */ 562 public int getGsmDbm() { 563 int dBm; 564 565 int gsmSignalStrength = getGsmSignalStrength(); 566 int asu = (gsmSignalStrength == 99 ? -1 : gsmSignalStrength); 567 if (asu != -1) { 568 dBm = -113 + (2 * asu); 569 } else { 570 dBm = -1; 571 } 572 if (DBG) log("getGsmDbm=" + dBm); 573 return dBm; 574 } 575 576 /** 577 * Get gsm as level 0..4 578 * 579 * @hide 580 */ 581 public int getGsmLevel() { 582 int level; 583 584 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 585 // asu = 0 (-113dB or less) is very weak 586 // signal, its better to show 0 bars to the user in such cases. 587 // asu = 99 is a special case, where the signal strength is unknown. 588 int asu = getGsmSignalStrength(); 589 if (asu <= 2 || asu == 99) level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 590 else if (asu >= 12) level = SIGNAL_STRENGTH_GREAT; 591 else if (asu >= 8) level = SIGNAL_STRENGTH_GOOD; 592 else if (asu >= 5) level = SIGNAL_STRENGTH_MODERATE; 593 else level = SIGNAL_STRENGTH_POOR; 594 if (DBG) log("getGsmLevel=" + level); 595 return level; 596 } 597 598 /** 599 * Get the gsm signal level as an asu value between 0..31, 99 is unknown 600 * 601 * @hide 602 */ 603 public int getGsmAsuLevel() { 604 // ASU ranges from 0 to 31 - TS 27.007 Sec 8.5 605 // asu = 0 (-113dB or less) is very weak 606 // signal, its better to show 0 bars to the user in such cases. 607 // asu = 99 is a special case, where the signal strength is unknown. 608 int level = getGsmSignalStrength(); 609 if (DBG) log("getGsmAsuLevel=" + level); 610 return level; 611 } 612 613 /** 614 * Get cdma as level 0..4 615 * 616 * @hide 617 */ 618 public int getCdmaLevel() { 619 final int cdmaDbm = getCdmaDbm(); 620 final int cdmaEcio = getCdmaEcio(); 621 int levelDbm; 622 int levelEcio; 623 624 if (cdmaDbm >= -75) levelDbm = SIGNAL_STRENGTH_GREAT; 625 else if (cdmaDbm >= -85) levelDbm = SIGNAL_STRENGTH_GOOD; 626 else if (cdmaDbm >= -95) levelDbm = SIGNAL_STRENGTH_MODERATE; 627 else if (cdmaDbm >= -100) levelDbm = SIGNAL_STRENGTH_POOR; 628 else levelDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 629 630 // Ec/Io are in dB*10 631 if (cdmaEcio >= -90) levelEcio = SIGNAL_STRENGTH_GREAT; 632 else if (cdmaEcio >= -110) levelEcio = SIGNAL_STRENGTH_GOOD; 633 else if (cdmaEcio >= -130) levelEcio = SIGNAL_STRENGTH_MODERATE; 634 else if (cdmaEcio >= -150) levelEcio = SIGNAL_STRENGTH_POOR; 635 else levelEcio = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 636 637 int level = (levelDbm < levelEcio) ? levelDbm : levelEcio; 638 if (DBG) log("getCdmaLevel=" + level); 639 return level; 640 } 641 642 /** 643 * Get the cdma signal level as an asu value between 0..31, 99 is unknown 644 * 645 * @hide 646 */ getCdmaAsuLevel()647 public int getCdmaAsuLevel() { 648 final int cdmaDbm = getCdmaDbm(); 649 final int cdmaEcio = getCdmaEcio(); 650 int cdmaAsuLevel; 651 int ecioAsuLevel; 652 653 if (cdmaDbm >= -75) cdmaAsuLevel = 16; 654 else if (cdmaDbm >= -82) cdmaAsuLevel = 8; 655 else if (cdmaDbm >= -90) cdmaAsuLevel = 4; 656 else if (cdmaDbm >= -95) cdmaAsuLevel = 2; 657 else if (cdmaDbm >= -100) cdmaAsuLevel = 1; 658 else cdmaAsuLevel = 99; 659 660 // Ec/Io are in dB*10 661 if (cdmaEcio >= -90) ecioAsuLevel = 16; 662 else if (cdmaEcio >= -100) ecioAsuLevel = 8; 663 else if (cdmaEcio >= -115) ecioAsuLevel = 4; 664 else if (cdmaEcio >= -130) ecioAsuLevel = 2; 665 else if (cdmaEcio >= -150) ecioAsuLevel = 1; 666 else ecioAsuLevel = 99; 667 668 int level = (cdmaAsuLevel < ecioAsuLevel) ? cdmaAsuLevel : ecioAsuLevel; 669 if (DBG) log("getCdmaAsuLevel=" + level); 670 return level; 671 } 672 673 /** 674 * Get Evdo as level 0..4 675 * 676 * @hide 677 */ getEvdoLevel()678 public int getEvdoLevel() { 679 int evdoDbm = getEvdoDbm(); 680 int evdoSnr = getEvdoSnr(); 681 int levelEvdoDbm; 682 int levelEvdoSnr; 683 684 if (evdoDbm >= -65) levelEvdoDbm = SIGNAL_STRENGTH_GREAT; 685 else if (evdoDbm >= -75) levelEvdoDbm = SIGNAL_STRENGTH_GOOD; 686 else if (evdoDbm >= -90) levelEvdoDbm = SIGNAL_STRENGTH_MODERATE; 687 else if (evdoDbm >= -105) levelEvdoDbm = SIGNAL_STRENGTH_POOR; 688 else levelEvdoDbm = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 689 690 if (evdoSnr >= 7) levelEvdoSnr = SIGNAL_STRENGTH_GREAT; 691 else if (evdoSnr >= 5) levelEvdoSnr = SIGNAL_STRENGTH_GOOD; 692 else if (evdoSnr >= 3) levelEvdoSnr = SIGNAL_STRENGTH_MODERATE; 693 else if (evdoSnr >= 1) levelEvdoSnr = SIGNAL_STRENGTH_POOR; 694 else levelEvdoSnr = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 695 696 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 697 if (DBG) log("getEvdoLevel=" + level); 698 return level; 699 } 700 701 /** 702 * Get the evdo signal level as an asu value between 0..31, 99 is unknown 703 * 704 * @hide 705 */ getEvdoAsuLevel()706 public int getEvdoAsuLevel() { 707 int evdoDbm = getEvdoDbm(); 708 int evdoSnr = getEvdoSnr(); 709 int levelEvdoDbm; 710 int levelEvdoSnr; 711 712 if (evdoDbm >= -65) levelEvdoDbm = 16; 713 else if (evdoDbm >= -75) levelEvdoDbm = 8; 714 else if (evdoDbm >= -85) levelEvdoDbm = 4; 715 else if (evdoDbm >= -95) levelEvdoDbm = 2; 716 else if (evdoDbm >= -105) levelEvdoDbm = 1; 717 else levelEvdoDbm = 99; 718 719 if (evdoSnr >= 7) levelEvdoSnr = 16; 720 else if (evdoSnr >= 6) levelEvdoSnr = 8; 721 else if (evdoSnr >= 5) levelEvdoSnr = 4; 722 else if (evdoSnr >= 3) levelEvdoSnr = 2; 723 else if (evdoSnr >= 1) levelEvdoSnr = 1; 724 else levelEvdoSnr = 99; 725 726 int level = (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; 727 if (DBG) log("getEvdoAsuLevel=" + level); 728 return level; 729 } 730 731 /** 732 * Get LTE as dBm 733 * 734 * @hide 735 */ getLteDbm()736 public int getLteDbm() { 737 return mLteRsrp; 738 } 739 740 /** 741 * Get LTE as level 0..4 742 * 743 * @hide 744 */ getLteLevel()745 public int getLteLevel() { 746 /* 747 * TS 36.214 Physical Layer Section 5.1.3 TS 36.331 RRC RSSI = received 748 * signal + noise RSRP = reference signal dBm RSRQ = quality of signal 749 * dB= Number of Resource blocksxRSRP/RSSI SNR = gain=signal/noise ratio 750 * = -10log P1/P2 dB 751 */ 752 int rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, rsrpIconLevel = -1, snrIconLevel = -1; 753 754 int rsrpThreshType = Resources.getSystem().getInteger(com.android.internal.R.integer. 755 config_LTE_RSRP_threshold_type); 756 int[] threshRsrp; 757 if (rsrpThreshType == RSRP_THRESH_TYPE_STRICT) { 758 threshRsrp = RSRP_THRESH_STRICT; 759 } else { 760 threshRsrp = RSRP_THRESH_LENIENT; 761 } 762 763 if (mLteRsrp > threshRsrp[5]) rsrpIconLevel = -1; 764 else if (mLteRsrp >= threshRsrp[4]) rsrpIconLevel = SIGNAL_STRENGTH_GREAT; 765 else if (mLteRsrp >= threshRsrp[3]) rsrpIconLevel = SIGNAL_STRENGTH_GOOD; 766 else if (mLteRsrp >= threshRsrp[2]) rsrpIconLevel = SIGNAL_STRENGTH_MODERATE; 767 else if (mLteRsrp >= threshRsrp[1]) rsrpIconLevel = SIGNAL_STRENGTH_POOR; 768 else if (mLteRsrp >= threshRsrp[0]) rsrpIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 769 770 /* 771 * Values are -200 dB to +300 (SNR*10dB) RS_SNR >= 13.0 dB =>4 bars 4.5 772 * dB <= RS_SNR < 13.0 dB => 3 bars 1.0 dB <= RS_SNR < 4.5 dB => 2 bars 773 * -3.0 dB <= RS_SNR < 1.0 dB 1 bar RS_SNR < -3.0 dB/No Service Antenna 774 * Icon Only 775 */ 776 if (mLteRssnr > 300) snrIconLevel = -1; 777 else if (mLteRssnr >= 130) snrIconLevel = SIGNAL_STRENGTH_GREAT; 778 else if (mLteRssnr >= 45) snrIconLevel = SIGNAL_STRENGTH_GOOD; 779 else if (mLteRssnr >= 10) snrIconLevel = SIGNAL_STRENGTH_MODERATE; 780 else if (mLteRssnr >= -30) snrIconLevel = SIGNAL_STRENGTH_POOR; 781 else if (mLteRssnr >= -200) 782 snrIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 783 784 if (DBG) log("getLTELevel - rsrp:" + mLteRsrp + " snr:" + mLteRssnr + " rsrpIconLevel:" 785 + rsrpIconLevel + " snrIconLevel:" + snrIconLevel); 786 787 /* Choose a measurement type to use for notification */ 788 if (snrIconLevel != -1 && rsrpIconLevel != -1) { 789 /* 790 * The number of bars displayed shall be the smaller of the bars 791 * associated with LTE RSRP and the bars associated with the LTE 792 * RS_SNR 793 */ 794 return (rsrpIconLevel < snrIconLevel ? rsrpIconLevel : snrIconLevel); 795 } 796 797 if (snrIconLevel != -1) return snrIconLevel; 798 799 if (rsrpIconLevel != -1) return rsrpIconLevel; 800 801 /* Valid values are (0-63, 99) as defined in TS 36.331 */ 802 if (mLteSignalStrength > 63) rssiIconLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 803 else if (mLteSignalStrength >= 12) rssiIconLevel = SIGNAL_STRENGTH_GREAT; 804 else if (mLteSignalStrength >= 8) rssiIconLevel = SIGNAL_STRENGTH_GOOD; 805 else if (mLteSignalStrength >= 5) rssiIconLevel = SIGNAL_STRENGTH_MODERATE; 806 else if (mLteSignalStrength >= 0) rssiIconLevel = SIGNAL_STRENGTH_POOR; 807 808 if (DBG) log("getLTELevel - rssi:" + mLteSignalStrength + " rssiIconLevel:" 809 + rssiIconLevel); 810 return rssiIconLevel; 811 812 } 813 /** 814 * Get the LTE signal level as an asu value between 0..97, 99 is unknown 815 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 816 * 817 * @hide 818 */ getLteAsuLevel()819 public int getLteAsuLevel() { 820 int lteAsuLevel = 99; 821 int lteDbm = getLteDbm(); 822 /* 823 * 3GPP 27.007 (Ver 10.3.0) Sec 8.69 824 * 0 -140 dBm or less 825 * 1 -139 dBm 826 * 2...96 -138... -44 dBm 827 * 97 -43 dBm or greater 828 * 255 not known or not detectable 829 */ 830 /* 831 * validateInput will always give a valid range between -140 t0 -44 as 832 * per ril.h. so RSRP >= -43 & <-140 will fall under asu level 255 833 * and not 97 or 0 834 */ 835 if (lteDbm == SignalStrength.INVALID) lteAsuLevel = 255; 836 else lteAsuLevel = lteDbm + 140; 837 if (DBG) log("Lte Asu level: "+lteAsuLevel); 838 return lteAsuLevel; 839 } 840 841 /** 842 * @return true if this is for GSM 843 */ isGsm()844 public boolean isGsm() { 845 return this.isGsm; 846 } 847 848 /** 849 * @return hash code 850 */ 851 @Override hashCode()852 public int hashCode() { 853 int primeNum = 31; 854 return ((mGsmSignalStrength * primeNum) 855 + (mGsmBitErrorRate * primeNum) 856 + (mCdmaDbm * primeNum) + (mCdmaEcio * primeNum) 857 + (mEvdoDbm * primeNum) + (mEvdoEcio * primeNum) + (mEvdoSnr * primeNum) 858 + (mLteSignalStrength * primeNum) + (mLteRsrp * primeNum) 859 + (mLteRsrq * primeNum) + (mLteRssnr * primeNum) + (mLteCqi * primeNum) 860 + (isGsm ? 1 : 0)); 861 } 862 863 /** 864 * @return true if the signal strengths are the same 865 */ 866 @Override equals(Object o)867 public boolean equals (Object o) { 868 SignalStrength s; 869 870 try { 871 s = (SignalStrength) o; 872 } catch (ClassCastException ex) { 873 return false; 874 } 875 876 if (o == null) { 877 return false; 878 } 879 880 return (mGsmSignalStrength == s.mGsmSignalStrength 881 && mGsmBitErrorRate == s.mGsmBitErrorRate 882 && mCdmaDbm == s.mCdmaDbm 883 && mCdmaEcio == s.mCdmaEcio 884 && mEvdoDbm == s.mEvdoDbm 885 && mEvdoEcio == s.mEvdoEcio 886 && mEvdoSnr == s.mEvdoSnr 887 && mLteSignalStrength == s.mLteSignalStrength 888 && mLteRsrp == s.mLteRsrp 889 && mLteRsrq == s.mLteRsrq 890 && mLteRssnr == s.mLteRssnr 891 && mLteCqi == s.mLteCqi 892 && isGsm == s.isGsm); 893 } 894 895 /** 896 * @return string representation. 897 */ 898 @Override toString()899 public String toString() { 900 return ("SignalStrength:" 901 + " " + mGsmSignalStrength 902 + " " + mGsmBitErrorRate 903 + " " + mCdmaDbm 904 + " " + mCdmaEcio 905 + " " + mEvdoDbm 906 + " " + mEvdoEcio 907 + " " + mEvdoSnr 908 + " " + mLteSignalStrength 909 + " " + mLteRsrp 910 + " " + mLteRsrq 911 + " " + mLteRssnr 912 + " " + mLteCqi 913 + " " + (isGsm ? "gsm|lte" : "cdma")); 914 } 915 916 /** 917 * Set SignalStrength based on intent notifier map 918 * 919 * @param m intent notifier map 920 * @hide 921 */ setFromNotifierBundle(Bundle m)922 private void setFromNotifierBundle(Bundle m) { 923 mGsmSignalStrength = m.getInt("GsmSignalStrength"); 924 mGsmBitErrorRate = m.getInt("GsmBitErrorRate"); 925 mCdmaDbm = m.getInt("CdmaDbm"); 926 mCdmaEcio = m.getInt("CdmaEcio"); 927 mEvdoDbm = m.getInt("EvdoDbm"); 928 mEvdoEcio = m.getInt("EvdoEcio"); 929 mEvdoSnr = m.getInt("EvdoSnr"); 930 mLteSignalStrength = m.getInt("LteSignalStrength"); 931 mLteRsrp = m.getInt("LteRsrp"); 932 mLteRsrq = m.getInt("LteRsrq"); 933 mLteRssnr = m.getInt("LteRssnr"); 934 mLteCqi = m.getInt("LteCqi"); 935 isGsm = m.getBoolean("isGsm"); 936 } 937 938 /** 939 * Set intent notifier Bundle based on SignalStrength 940 * 941 * @param m intent notifier Bundle 942 * @hide 943 */ fillInNotifierBundle(Bundle m)944 public void fillInNotifierBundle(Bundle m) { 945 m.putInt("GsmSignalStrength", mGsmSignalStrength); 946 m.putInt("GsmBitErrorRate", mGsmBitErrorRate); 947 m.putInt("CdmaDbm", mCdmaDbm); 948 m.putInt("CdmaEcio", mCdmaEcio); 949 m.putInt("EvdoDbm", mEvdoDbm); 950 m.putInt("EvdoEcio", mEvdoEcio); 951 m.putInt("EvdoSnr", mEvdoSnr); 952 m.putInt("LteSignalStrength", mLteSignalStrength); 953 m.putInt("LteRsrp", mLteRsrp); 954 m.putInt("LteRsrq", mLteRsrq); 955 m.putInt("LteRssnr", mLteRssnr); 956 m.putInt("LteCqi", mLteCqi); 957 m.putBoolean("isGsm", Boolean.valueOf(isGsm)); 958 } 959 960 /** 961 * log 962 */ log(String s)963 private static void log(String s) { 964 Rlog.w(LOG_TAG, s); 965 } 966 } 967