1 /* 2 * Copyright (C) 2018 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.annotation.IntDef; 20 import android.annotation.IntRange; 21 import android.annotation.NonNull; 22 import android.os.Parcel; 23 import android.os.Parcelable; 24 import android.os.PersistableBundle; 25 26 import com.android.telephony.Rlog; 27 28 import java.lang.annotation.Retention; 29 import java.lang.annotation.RetentionPolicy; 30 import java.util.Arrays; 31 import java.util.Collections; 32 import java.util.List; 33 import java.util.Objects; 34 import java.util.stream.Collectors; 35 36 /** 37 * 5G NR signal strength related information. 38 */ 39 public final class CellSignalStrengthNr extends CellSignalStrength implements Parcelable { 40 /** 41 * The value is used to indicate that the asu level is unknown. 42 * Reference: 3GPP TS 27.007 section 8.69. 43 * @hide 44 */ 45 public static final int UNKNOWN_ASU_LEVEL = 99; 46 47 private static final boolean VDBG = false; 48 49 private static final String TAG = "CellSignalStrengthNr"; 50 51 // Lifted from Default carrier configs and max range of SSRSRP 52 // Boundaries: [-156 dB, -31 dB] 53 private int[] mSsRsrpThresholds = new int[] { 54 -110, /* SIGNAL_STRENGTH_POOR */ 55 -90, /* SIGNAL_STRENGTH_MODERATE */ 56 -80, /* SIGNAL_STRENGTH_GOOD */ 57 -65, /* SIGNAL_STRENGTH_GREAT */ 58 }; 59 60 // Lifted from Default carrier configs and max range of SSRSRQ 61 // Boundaries: [-43 dB, 20 dB] 62 private int[] mSsRsrqThresholds = new int[] { 63 -31, /* SIGNAL_STRENGTH_POOR */ 64 -19, /* SIGNAL_STRENGTH_MODERATE */ 65 -7, /* SIGNAL_STRENGTH_GOOD */ 66 6 /* SIGNAL_STRENGTH_GREAT */ 67 }; 68 69 // Lifted from Default carrier configs and max range of SSSINR 70 // Boundaries: [-23 dB, 40 dB] 71 private int[] mSsSinrThresholds = new int[] { 72 -5, /* SIGNAL_STRENGTH_POOR */ 73 5, /* SIGNAL_STRENGTH_MODERATE */ 74 15, /* SIGNAL_STRENGTH_GOOD */ 75 30 /* SIGNAL_STRENGTH_GREAT */ 76 }; 77 78 /** 79 * Indicates SSRSRP is considered for {@link #getLevel()} and reporting from modem. 80 * 81 * @hide 82 */ 83 public static final int USE_SSRSRP = 1 << 0; 84 /** 85 * Indicates SSRSRQ is considered for {@link #getLevel()} and reporting from modem. 86 * 87 * @hide 88 */ 89 public static final int USE_SSRSRQ = 1 << 1; 90 /** 91 * Indicates SSSINR is considered for {@link #getLevel()} and reporting from modem. 92 * 93 * @hide 94 */ 95 public static final int USE_SSSINR = 1 << 2; 96 97 /** 98 * Bit-field integer to determine whether to use SS reference signal received power (SSRSRP), 99 * SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference 100 * ratio (SSSINR) for the number of 5G NR signal bars. If multiple measures are set bit, the 101 * parameter whose value is smallest is used to indicate the signal bar. 102 * 103 * @hide 104 */ 105 @IntDef(flag = true, prefix = { "USE_" }, value = { 106 USE_SSRSRP, 107 USE_SSRSRQ, 108 USE_SSSINR 109 }) 110 @Retention(RetentionPolicy.SOURCE) 111 public @interface SignalLevelAndReportCriteriaSource {} 112 113 private int mCsiRsrp; 114 private int mCsiRsrq; 115 private int mCsiSinr; 116 /** 117 * CSI channel quality indicator (CQI) table index. There are multiple CQI tables. 118 * The definition of CQI in each table is different. 119 * 120 * Reference: 3GPP TS 138.214 section 5.2.2.1. 121 * 122 * Range [1, 3]. 123 */ 124 private int mCsiCqiTableIndex; 125 /** 126 * CSI channel quality indicators (CQI) for all subbands. 127 * 128 * If the CQI report is for the entire wideband, a single CQI index is provided. 129 * If the CQI report is for all subbands, one CQI index is provided for each subband, 130 * in ascending order of subband index. 131 * If CQI is not available, the CQI report is empty. 132 * 133 * Reference: 3GPP TS 138.214 section 5.2.2.1. 134 * 135 * Range [0, 15] for each CQI. 136 */ 137 private List<Integer> mCsiCqiReport; 138 private int mSsRsrp; 139 private int mSsRsrq; 140 private int mSsSinr; 141 private int mLevel; 142 143 /** 144 * Bit-field integer to determine whether to use SS reference signal received power (SSRSRP), 145 * SS reference signal received quality (SSRSRQ), or/and SS signal-to-noise and interference 146 * ratio (SSSINR) for the number of 5G NR signal bars. If multiple measures are set bit, the 147 * parameter whose value is smallest is used to indicate the signal bar. 148 * 149 * SSRSRP = 1 << 0, 150 * SSRSRQ = 1 << 1, 151 * SSSINR = 1 << 2, 152 * 153 * For example, if both SSRSRP and SSSINR are used, the value of key is 5 (1 << 0 | 1 << 2). 154 * If the key is invalid or not configured, a default value (SSRSRP = 1 << 0) will apply. 155 */ 156 private int mParametersUseForLevel; 157 158 /** 159 * Timing advance value for a one way trip from cell to device in microseconds. 160 * Approximate distance is calculated using 300m/us * timingAdvance. 161 * 162 * Reference: 3GPP TS 36.213 section 4.2.3. 163 * 164 * Range: [0, 1282] 165 */ 166 private int mTimingAdvance; 167 168 /** @hide */ CellSignalStrengthNr()169 public CellSignalStrengthNr() { 170 setDefaultValues(); 171 } 172 173 /** 174 * @param csiRsrp CSI reference signal received power. 175 * @param csiRsrq CSI reference signal received quality. 176 * @param csiSinr CSI signal-to-noise and interference ratio. 177 * @param csiCqiTableIndex CSI CSI channel quality indicator (CQI) table index. 178 * @param csiCqiReport CSI channel quality indicators (CQI) for all subbands. 179 * @param ssRsrp SS reference signal received power. 180 * @param ssRsrq SS reference signal received quality. 181 * @param ssSinr SS signal-to-noise and interference ratio. 182 * @param timingAdvance Timing advance. 183 * @hide 184 */ CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex, List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr, int timingAdvance)185 public CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex, 186 List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr, int timingAdvance) { 187 mCsiRsrp = inRangeOrUnavailable(csiRsrp, -156, -31); 188 mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3); 189 mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23); 190 mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3); 191 mCsiCqiReport = csiCqiReport.stream() 192 .map(cqi -> inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15)) 193 .collect(Collectors.toList()); 194 mSsRsrp = inRangeOrUnavailable(ssRsrp, -156, -31); 195 mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20); 196 mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40); 197 mTimingAdvance = inRangeOrUnavailable(timingAdvance, 0, 1282); 198 updateLevel(null, null); 199 } 200 201 /** 202 * @param csiRsrp CSI reference signal received power. 203 * @param csiRsrq CSI reference signal received quality. 204 * @param csiSinr CSI signal-to-noise and interference ratio. 205 * @param ssRsrp SS reference signal received power. 206 * @param ssRsrq SS reference signal received quality. 207 * @param ssSinr SS signal-to-noise and interference ratio. 208 * @hide 209 */ CellSignalStrengthNr( int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr)210 public CellSignalStrengthNr( 211 int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) { 212 this(csiRsrp, csiRsrq, csiSinr, CellInfo.UNAVAILABLE, Collections.emptyList(), 213 ssRsrp, ssRsrq, ssSinr, CellInfo.UNAVAILABLE); 214 } 215 216 /** 217 * Flip sign cell strength value when taking in the value from hal 218 * @param val cell strength value 219 * @return flipped value 220 * @hide 221 */ flip(int val)222 public static int flip(int val) { 223 return val != CellInfo.UNAVAILABLE ? -val : val; 224 } 225 226 /** 227 * Reference: 3GPP TS 38.133 10.1.6.1. 228 * Range: -156 dBm to -31 dBm. 229 * @return SS reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported 230 * value. 231 */ getSsRsrp()232 public int getSsRsrp() { 233 return mSsRsrp; 234 } 235 236 /** 237 * Reference: 3GPP TS 38.215; 3GPP TS 38.133 section 10 238 * Range: -43 dB to 20 dB. 239 * @return SS reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported 240 * value. 241 */ getSsRsrq()242 public int getSsRsrq() { 243 return mSsRsrq; 244 } 245 246 /** 247 * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1 248 * Range: -23 dB to 40 dB 249 * @return SS signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means 250 * unreported value. 251 */ getSsSinr()252 public int getSsSinr() { 253 return mSsSinr; 254 } 255 256 /** 257 * Reference: 3GPP TS 38.133 10.1.6.1. 258 * Range: -156 dBm to -31 dBm. 259 * @return CSI reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported 260 * value. 261 */ getCsiRsrp()262 public int getCsiRsrp() { 263 return mCsiRsrp; 264 } 265 266 /** 267 * Reference: 3GPP TS 38.215. 268 * Range: -20 dB to -3 dB. 269 * @return CSI reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported 270 * value. 271 */ getCsiRsrq()272 public int getCsiRsrq() { 273 return mCsiRsrq; 274 } 275 276 /** 277 * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1 278 * Range: -23 dB to 23 dB 279 * @return CSI signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means 280 * unreported value. 281 */ getCsiSinr()282 public int getCsiSinr() { 283 return mCsiSinr; 284 } 285 286 /** 287 * Return CSI channel quality indicator (CQI) table index. There are multiple CQI tables. 288 * The definition of CQI in each table is different. 289 * 290 * Reference: 3GPP TS 138.214 section 5.2.2.1. 291 * 292 * @return the CQI table index if available or 293 * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable. 294 */ 295 @IntRange(from = 1, to = 3) getCsiCqiTableIndex()296 public int getCsiCqiTableIndex() { 297 return mCsiCqiTableIndex; 298 } 299 /** 300 * Return a list of CSI channel quality indicators (CQI) for all subbands. 301 * 302 * If the CQI report is for the entire wideband, a single CQI index is provided. 303 * If the CQI report is for all subbands, one CQI index is provided for each subband, 304 * in ascending order of subband index. 305 * If CQI is not available, the CQI report is empty. 306 * 307 * Reference: 3GPP TS 138.214 section 5.2.2.1. 308 * 309 * @return the CQIs for all subbands if available or empty list if unavailable. 310 */ 311 @NonNull 312 @IntRange(from = 0, to = 15) getCsiCqiReport()313 public List<Integer> getCsiCqiReport() { 314 return mCsiCqiReport; 315 } 316 317 /** 318 * Get the timing advance value for a one way trip from cell to device for NR in microseconds. 319 * {@link android.telephony.CellInfo#UNAVAILABLE} is reported when there is no 320 * active RRC connection. 321 * 322 * Reference: 3GPP TS 36.213 section 4.2.3. 323 * Range: 0 us to 1282 us. 324 * 325 * @return the NR timing advance if available or 326 * {@link android.telephony.CellInfo#UNAVAILABLE} if unavailable. 327 */ 328 @IntRange(from = 0, to = 1282) getTimingAdvanceMicros()329 public int getTimingAdvanceMicros() { 330 return mTimingAdvance; 331 } 332 333 @Override describeContents()334 public int describeContents() { 335 return 0; 336 } 337 338 /** @hide */ 339 @Override writeToParcel(Parcel dest, int flags)340 public void writeToParcel(Parcel dest, int flags) { 341 dest.writeInt(mCsiRsrp); 342 dest.writeInt(mCsiRsrq); 343 dest.writeInt(mCsiSinr); 344 dest.writeInt(mCsiCqiTableIndex); 345 dest.writeList(mCsiCqiReport); 346 dest.writeInt(mSsRsrp); 347 dest.writeInt(mSsRsrq); 348 dest.writeInt(mSsSinr); 349 dest.writeInt(mLevel); 350 dest.writeInt(mTimingAdvance); 351 } 352 CellSignalStrengthNr(Parcel in)353 private CellSignalStrengthNr(Parcel in) { 354 mCsiRsrp = in.readInt(); 355 mCsiRsrq = in.readInt(); 356 mCsiSinr = in.readInt(); 357 mCsiCqiTableIndex = in.readInt(); 358 mCsiCqiReport = in.readArrayList(Integer.class.getClassLoader(), java.lang.Integer.class); 359 mSsRsrp = in.readInt(); 360 mSsRsrq = in.readInt(); 361 mSsSinr = in.readInt(); 362 mLevel = in.readInt(); 363 mTimingAdvance = in.readInt(); 364 } 365 366 /** @hide */ 367 @Override setDefaultValues()368 public void setDefaultValues() { 369 mCsiRsrp = CellInfo.UNAVAILABLE; 370 mCsiRsrq = CellInfo.UNAVAILABLE; 371 mCsiSinr = CellInfo.UNAVAILABLE; 372 mCsiCqiTableIndex = CellInfo.UNAVAILABLE; 373 mCsiCqiReport = Collections.emptyList(); 374 mSsRsrp = CellInfo.UNAVAILABLE; 375 mSsRsrq = CellInfo.UNAVAILABLE; 376 mSsSinr = CellInfo.UNAVAILABLE; 377 mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 378 mParametersUseForLevel = USE_SSRSRP; 379 mTimingAdvance = CellInfo.UNAVAILABLE; 380 } 381 382 /** {@inheritDoc} */ 383 @Override 384 @IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT) getLevel()385 public int getLevel() { 386 return mLevel; 387 } 388 389 /** 390 * Checks if the given parameter type is considered to use for {@link #getLevel()}. 391 * 392 * Note: if multiple parameter types are considered, the smaller level for one of the 393 * parameters would be returned by {@link #getLevel()} 394 * 395 * @param parameterType bitwise OR of {@link #USE_SSRSRP}, {@link #USE_SSRSRQ}, 396 * {@link #USE_SSSINR} 397 * @return {@code true} if the level is calculated based on the given parameter type; 398 * {@code false} otherwise. 399 * 400 */ isLevelForParameter(@ignalLevelAndReportCriteriaSource int parameterType)401 private boolean isLevelForParameter(@SignalLevelAndReportCriteriaSource int parameterType) { 402 return (parameterType & mParametersUseForLevel) == parameterType; 403 } 404 405 /** @hide */ 406 @Override updateLevel(PersistableBundle cc, ServiceState ss)407 public void updateLevel(PersistableBundle cc, ServiceState ss) { 408 if (cc == null) { 409 mParametersUseForLevel = USE_SSRSRP; 410 } else { 411 mParametersUseForLevel = cc.getInt( 412 CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, USE_SSRSRP); 413 mSsRsrpThresholds = cc.getIntArray( 414 CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY); 415 if (VDBG) { 416 Rlog.i(TAG, "Applying 5G NR SSRSRP Thresholds: " 417 + Arrays.toString(mSsRsrpThresholds)); 418 } 419 mSsRsrqThresholds = cc.getIntArray( 420 CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY); 421 if (VDBG) { 422 Rlog.i(TAG, "Applying 5G NR SSRSRQ Thresholds: " 423 + Arrays.toString(mSsRsrqThresholds)); 424 } 425 mSsSinrThresholds = cc.getIntArray( 426 CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY); 427 if (VDBG) { 428 Rlog.i(TAG, "Applying 5G NR SSSINR Thresholds: " 429 + Arrays.toString(mSsSinrThresholds)); 430 } 431 } 432 int ssRsrpLevel = SignalStrength.INVALID; 433 int ssRsrqLevel = SignalStrength.INVALID; 434 int ssSinrLevel = SignalStrength.INVALID; 435 if (isLevelForParameter(USE_SSRSRP)) { 436 int rsrpBoost = 0; 437 if (ss != null) { 438 rsrpBoost = ss.getArfcnRsrpBoost(); 439 } 440 ssRsrpLevel = updateLevelWithMeasure(mSsRsrp + rsrpBoost, mSsRsrpThresholds); 441 if (VDBG) { 442 Rlog.i(TAG, "Updated 5G NR SSRSRP Level: " + ssRsrpLevel); 443 } 444 } 445 if (isLevelForParameter(USE_SSRSRQ)) { 446 ssRsrqLevel = updateLevelWithMeasure(mSsRsrq, mSsRsrqThresholds); 447 if (VDBG) { 448 Rlog.i(TAG, "Updated 5G NR SSRSRQ Level: " + ssRsrqLevel); 449 } 450 } 451 if (isLevelForParameter(USE_SSSINR)) { 452 ssSinrLevel = updateLevelWithMeasure(mSsSinr, mSsSinrThresholds); 453 if (VDBG) { 454 Rlog.i(TAG, "Updated 5G NR SSSINR Level: " + ssSinrLevel); 455 } 456 } 457 // Apply the smaller value among three levels of three measures. 458 mLevel = Math.min(Math.min(ssRsrpLevel, ssRsrqLevel), ssSinrLevel); 459 } 460 461 /** 462 * Update level with corresponding measure and thresholds. 463 * 464 * @param measure corresponding signal measure 465 * @param thresholds corresponding signal thresholds 466 * @return level of the signal strength 467 */ updateLevelWithMeasure(int measure, int[] thresholds)468 private int updateLevelWithMeasure(int measure, int[] thresholds) { 469 int level; 470 if (measure == CellInfo.UNAVAILABLE) { 471 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 472 } else if (measure >= thresholds[3]) { 473 level = SIGNAL_STRENGTH_GREAT; 474 } else if (measure >= thresholds[2]) { 475 level = SIGNAL_STRENGTH_GOOD; 476 } else if (measure >= thresholds[1]) { 477 level = SIGNAL_STRENGTH_MODERATE; 478 } else if (measure >= thresholds[0]) { 479 level = SIGNAL_STRENGTH_POOR; 480 } else { 481 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 482 } 483 return level; 484 } 485 486 /** 487 * Get the RSRP in ASU. 488 * 489 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 490 * 491 * @return RSRP in ASU 0..97, 255, or UNAVAILABLE 492 */ 493 @Override getAsuLevel()494 public int getAsuLevel() { 495 int asuLevel; 496 int nrDbm = getDbm(); 497 if (nrDbm == CellInfo.UNAVAILABLE) { 498 asuLevel = UNKNOWN_ASU_LEVEL; 499 } else if (nrDbm <= -140) { 500 asuLevel = 0; 501 } else if (nrDbm >= -43) { 502 asuLevel = 97; 503 } else { 504 asuLevel = nrDbm + 140; 505 } 506 return asuLevel; 507 } 508 509 /** 510 * Get the SS-RSRP as dBm value -140..-44dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 511 */ 512 @Override getDbm()513 public int getDbm() { 514 return mSsRsrp; 515 } 516 517 /** @hide */ CellSignalStrengthNr(CellSignalStrengthNr s)518 public CellSignalStrengthNr(CellSignalStrengthNr s) { 519 mCsiRsrp = s.mCsiRsrp; 520 mCsiRsrq = s.mCsiRsrq; 521 mCsiSinr = s.mCsiSinr; 522 mCsiCqiTableIndex = s.mCsiCqiTableIndex; 523 mCsiCqiReport = s.mCsiCqiReport; 524 mSsRsrp = s.mSsRsrp; 525 mSsRsrq = s.mSsRsrq; 526 mSsSinr = s.mSsSinr; 527 mLevel = s.mLevel; 528 mParametersUseForLevel = s.mParametersUseForLevel; 529 mTimingAdvance = s.mTimingAdvance; 530 } 531 532 /** @hide */ 533 @Override copy()534 public CellSignalStrengthNr copy() { 535 return new CellSignalStrengthNr(this); 536 } 537 538 @Override hashCode()539 public int hashCode() { 540 return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mCsiCqiTableIndex, 541 mCsiCqiReport, mSsRsrp, mSsRsrq, mSsSinr, mLevel, mTimingAdvance); 542 } 543 544 private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr(); 545 546 /** @hide */ 547 @Override isValid()548 public boolean isValid() { 549 return !this.equals(sInvalid); 550 } 551 552 @Override equals(Object obj)553 public boolean equals(Object obj) { 554 if (obj instanceof CellSignalStrengthNr) { 555 CellSignalStrengthNr o = (CellSignalStrengthNr) obj; 556 return mCsiRsrp == o.mCsiRsrp && mCsiRsrq == o.mCsiRsrq && mCsiSinr == o.mCsiSinr 557 && mCsiCqiTableIndex == o.mCsiCqiTableIndex 558 && mCsiCqiReport.equals(o.mCsiCqiReport) 559 && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr 560 && mLevel == o.mLevel && mTimingAdvance == o.mTimingAdvance; 561 } 562 return false; 563 } 564 565 @Override toString()566 public String toString() { 567 return new StringBuilder() 568 .append(TAG + ":{") 569 .append(" csiRsrp = " + mCsiRsrp) 570 .append(" csiRsrq = " + mCsiRsrq) 571 .append(" csiCqiTableIndex = " + mCsiCqiTableIndex) 572 .append(" csiCqiReport = " + mCsiCqiReport) 573 .append(" ssRsrp = " + mSsRsrp) 574 .append(" ssRsrq = " + mSsRsrq) 575 .append(" ssSinr = " + mSsSinr) 576 .append(" level = " + mLevel) 577 .append(" parametersUseForLevel = " + mParametersUseForLevel) 578 .append(" timingAdvance = " + mTimingAdvance) 579 .append(" }") 580 .toString(); 581 } 582 583 /** Implement the Parcelable interface */ 584 public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthNr> CREATOR = 585 new Parcelable.Creator<CellSignalStrengthNr>() { 586 @Override 587 public CellSignalStrengthNr createFromParcel(Parcel in) { 588 return new CellSignalStrengthNr(in); 589 } 590 591 @Override 592 public CellSignalStrengthNr[] newArray(int size) { 593 return new CellSignalStrengthNr[size]; 594 } 595 }; 596 } 597