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: [-140 dB, -44 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 /** @hide */ CellSignalStrengthNr()159 public CellSignalStrengthNr() { 160 setDefaultValues(); 161 } 162 163 /** 164 * @param csiRsrp CSI reference signal received power. 165 * @param csiRsrq CSI reference signal received quality. 166 * @param csiSinr CSI signal-to-noise and interference ratio. 167 * @param csiCqiTableIndex CSI CSI channel quality indicator (CQI) table index. 168 * @param csiCqiReport CSI channel quality indicators (CQI) for all subbands. 169 * @param ssRsrp SS reference signal received power. 170 * @param ssRsrq SS reference signal received quality. 171 * @param ssSinr SS signal-to-noise and interference ratio. 172 * @hide 173 */ CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex, List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr)174 public CellSignalStrengthNr(int csiRsrp, int csiRsrq, int csiSinr, int csiCqiTableIndex, 175 List<Byte> csiCqiReport, int ssRsrp, int ssRsrq, int ssSinr) { 176 mCsiRsrp = inRangeOrUnavailable(csiRsrp, -140, -44); 177 mCsiRsrq = inRangeOrUnavailable(csiRsrq, -20, -3); 178 mCsiSinr = inRangeOrUnavailable(csiSinr, -23, 23); 179 mCsiCqiTableIndex = inRangeOrUnavailable(csiCqiTableIndex, 1, 3); 180 mCsiCqiReport = csiCqiReport.stream() 181 .map(cqi -> new Integer(inRangeOrUnavailable(Byte.toUnsignedInt(cqi), 0, 15))) 182 .collect(Collectors.toList()); 183 mSsRsrp = inRangeOrUnavailable(ssRsrp, -140, -44); 184 mSsRsrq = inRangeOrUnavailable(ssRsrq, -43, 20); 185 mSsSinr = inRangeOrUnavailable(ssSinr, -23, 40); 186 updateLevel(null, null); 187 } 188 189 /** 190 * @param csiRsrp CSI reference signal received power. 191 * @param csiRsrq CSI reference signal received quality. 192 * @param csiSinr CSI signal-to-noise and interference ratio. 193 * @param ssRsrp SS reference signal received power. 194 * @param ssRsrq SS reference signal received quality. 195 * @param ssSinr SS signal-to-noise and interference ratio. 196 * @hide 197 */ CellSignalStrengthNr( int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr)198 public CellSignalStrengthNr( 199 int csiRsrp, int csiRsrq, int csiSinr, int ssRsrp, int ssRsrq, int ssSinr) { 200 this(csiRsrp, csiRsrq, csiSinr, CellInfo.UNAVAILABLE, Collections.emptyList(), 201 ssRsrp, ssRsrq, ssSinr); 202 } 203 204 /** 205 * @hide 206 * @param ss signal strength from modem. 207 */ CellSignalStrengthNr(android.hardware.radio.V1_4.NrSignalStrength ss)208 public CellSignalStrengthNr(android.hardware.radio.V1_4.NrSignalStrength ss) { 209 this(flip(ss.csiRsrp), flip(ss.csiRsrq), ss.csiSinr, flip(ss.ssRsrp), flip(ss.ssRsrq), 210 ss.ssSinr); 211 } 212 213 /** 214 * @hide 215 * @param ss signal strength from modem. 216 */ CellSignalStrengthNr(android.hardware.radio.V1_6.NrSignalStrength ss)217 public CellSignalStrengthNr(android.hardware.radio.V1_6.NrSignalStrength ss) { 218 this(flip(ss.base.csiRsrp), flip(ss.base.csiRsrq), ss.base.csiSinr, ss.csiCqiTableIndex, 219 ss.csiCqiReport, flip(ss.base.ssRsrp), flip(ss.base.ssRsrq), ss.base.ssSinr); 220 } 221 222 /** 223 * Flip sign cell strength value when taking in the value from hal 224 * @param val cell strength value 225 * @return flipped value 226 */ flip(int val)227 private static int flip(int val) { 228 return val != CellInfo.UNAVAILABLE ? -val : val; 229 } 230 231 /** 232 * Reference: 3GPP TS 38.215. 233 * Range: -140 dBm to -44 dBm. 234 * @return SS reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported 235 * value. 236 */ getSsRsrp()237 public int getSsRsrp() { 238 return mSsRsrp; 239 } 240 241 /** 242 * Reference: 3GPP TS 38.215; 3GPP TS 38.133 section 10 243 * Range: -43 dB to 20 dB. 244 * @return SS reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported 245 * value. 246 */ getSsRsrq()247 public int getSsRsrq() { 248 return mSsRsrq; 249 } 250 251 /** 252 * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1 253 * Range: -23 dB to 40 dB 254 * @return SS signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means 255 * unreported value. 256 */ getSsSinr()257 public int getSsSinr() { 258 return mSsSinr; 259 } 260 261 /** 262 * Reference: 3GPP TS 38.215. 263 * Range: -140 dBm to -44 dBm. 264 * @return CSI reference signal received power, {@link CellInfo#UNAVAILABLE} means unreported 265 * value. 266 */ getCsiRsrp()267 public int getCsiRsrp() { 268 return mCsiRsrp; 269 } 270 271 /** 272 * Reference: 3GPP TS 38.215. 273 * Range: -20 dB to -3 dB. 274 * @return CSI reference signal received quality, {@link CellInfo#UNAVAILABLE} means unreported 275 * value. 276 */ getCsiRsrq()277 public int getCsiRsrq() { 278 return mCsiRsrq; 279 } 280 281 /** 282 * Reference: 3GPP TS 38.215 Sec 5.1.*, 3GPP TS 38.133 10.1.16.1 283 * Range: -23 dB to 23 dB 284 * @return CSI signal-to-noise and interference ratio, {@link CellInfo#UNAVAILABLE} means 285 * unreported value. 286 */ getCsiSinr()287 public int getCsiSinr() { 288 return mCsiSinr; 289 } 290 291 /** 292 * Return CSI channel quality indicator (CQI) table index. There are multiple CQI tables. 293 * The definition of CQI in each table is different. 294 * 295 * Reference: 3GPP TS 138.214 section 5.2.2.1. 296 * 297 * @return the CQI table index if available or 298 * {@link android.telephony.CellInfo#UNAVAILABLE UNAVAILABLE} if unavailable. 299 */ 300 @IntRange(from = 1, to = 3) getCsiCqiTableIndex()301 public int getCsiCqiTableIndex() { 302 return mCsiCqiTableIndex; 303 } 304 /** 305 * Return a list of CSI channel quality indicators (CQI) for all subbands. 306 * 307 * If the CQI report is for the entire wideband, a single CQI index is provided. 308 * If the CQI report is for all subbands, one CQI index is provided for each subband, 309 * in ascending order of subband index. 310 * If CQI is not available, the CQI report is empty. 311 * 312 * Reference: 3GPP TS 138.214 section 5.2.2.1. 313 * 314 * @return the CQIs for all subbands if available or empty list if unavailable. 315 */ 316 @NonNull 317 @IntRange(from = 0, to = 15) getCsiCqiReport()318 public List<Integer> getCsiCqiReport() { 319 return mCsiCqiReport; 320 } 321 322 @Override describeContents()323 public int describeContents() { 324 return 0; 325 } 326 327 /** @hide */ 328 @Override writeToParcel(Parcel dest, int flags)329 public void writeToParcel(Parcel dest, int flags) { 330 dest.writeInt(mCsiRsrp); 331 dest.writeInt(mCsiRsrq); 332 dest.writeInt(mCsiSinr); 333 dest.writeInt(mCsiCqiTableIndex); 334 dest.writeList(mCsiCqiReport); 335 dest.writeInt(mSsRsrp); 336 dest.writeInt(mSsRsrq); 337 dest.writeInt(mSsSinr); 338 dest.writeInt(mLevel); 339 } 340 CellSignalStrengthNr(Parcel in)341 private CellSignalStrengthNr(Parcel in) { 342 mCsiRsrp = in.readInt(); 343 mCsiRsrq = in.readInt(); 344 mCsiSinr = in.readInt(); 345 mCsiCqiTableIndex = in.readInt(); 346 mCsiCqiReport = in.readArrayList(Integer.class.getClassLoader()); 347 mSsRsrp = in.readInt(); 348 mSsRsrq = in.readInt(); 349 mSsSinr = in.readInt(); 350 mLevel = in.readInt(); 351 } 352 353 /** @hide */ 354 @Override setDefaultValues()355 public void setDefaultValues() { 356 mCsiRsrp = CellInfo.UNAVAILABLE; 357 mCsiRsrq = CellInfo.UNAVAILABLE; 358 mCsiSinr = CellInfo.UNAVAILABLE; 359 mCsiCqiTableIndex = CellInfo.UNAVAILABLE; 360 mCsiCqiReport = Collections.emptyList(); 361 mSsRsrp = CellInfo.UNAVAILABLE; 362 mSsRsrq = CellInfo.UNAVAILABLE; 363 mSsSinr = CellInfo.UNAVAILABLE; 364 mLevel = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 365 mParametersUseForLevel = USE_SSRSRP; 366 } 367 368 /** {@inheritDoc} */ 369 @Override 370 @IntRange(from = SIGNAL_STRENGTH_NONE_OR_UNKNOWN, to = SIGNAL_STRENGTH_GREAT) getLevel()371 public int getLevel() { 372 return mLevel; 373 } 374 375 /** 376 * Checks if the given parameter type is considered to use for {@link #getLevel()}. 377 * 378 * Note: if multiple parameter types are considered, the smaller level for one of the 379 * parameters would be returned by {@link #getLevel()} 380 * 381 * @param parameterType bitwise OR of {@link #USE_SSRSRP}, {@link #USE_SSRSRQ}, 382 * {@link #USE_SSSINR} 383 * @return {@code true} if the level is calculated based on the given parameter type; 384 * {@code false} otherwise. 385 * 386 */ isLevelForParameter(@ignalLevelAndReportCriteriaSource int parameterType)387 private boolean isLevelForParameter(@SignalLevelAndReportCriteriaSource int parameterType) { 388 return (parameterType & mParametersUseForLevel) == parameterType; 389 } 390 391 /** @hide */ 392 @Override updateLevel(PersistableBundle cc, ServiceState ss)393 public void updateLevel(PersistableBundle cc, ServiceState ss) { 394 if (cc == null) { 395 mParametersUseForLevel = USE_SSRSRP; 396 } else { 397 mParametersUseForLevel = cc.getInt( 398 CarrierConfigManager.KEY_PARAMETERS_USE_FOR_5G_NR_SIGNAL_BAR_INT, USE_SSRSRP); 399 mSsRsrpThresholds = cc.getIntArray( 400 CarrierConfigManager.KEY_5G_NR_SSRSRP_THRESHOLDS_INT_ARRAY); 401 if (VDBG) { 402 Rlog.i(TAG, "Applying 5G NR SSRSRP Thresholds: " 403 + Arrays.toString(mSsRsrpThresholds)); 404 } 405 mSsRsrqThresholds = cc.getIntArray( 406 CarrierConfigManager.KEY_5G_NR_SSRSRQ_THRESHOLDS_INT_ARRAY); 407 if (VDBG) { 408 Rlog.i(TAG, "Applying 5G NR SSRSRQ Thresholds: " 409 + Arrays.toString(mSsRsrqThresholds)); 410 } 411 mSsSinrThresholds = cc.getIntArray( 412 CarrierConfigManager.KEY_5G_NR_SSSINR_THRESHOLDS_INT_ARRAY); 413 if (VDBG) { 414 Rlog.i(TAG, "Applying 5G NR SSSINR Thresholds: " 415 + Arrays.toString(mSsSinrThresholds)); 416 } 417 } 418 int ssRsrpLevel = SignalStrength.INVALID; 419 int ssRsrqLevel = SignalStrength.INVALID; 420 int ssSinrLevel = SignalStrength.INVALID; 421 if (isLevelForParameter(USE_SSRSRP)) { 422 int rsrpBoost = 0; 423 if (ss != null) { 424 rsrpBoost = ss.getArfcnRsrpBoost(); 425 } 426 ssRsrpLevel = updateLevelWithMeasure(mSsRsrp + rsrpBoost, mSsRsrpThresholds); 427 if (VDBG) { 428 Rlog.i(TAG, "Updated 5G NR SSRSRP Level: " + ssRsrpLevel); 429 } 430 } 431 if (isLevelForParameter(USE_SSRSRQ)) { 432 ssRsrqLevel = updateLevelWithMeasure(mSsRsrq, mSsRsrqThresholds); 433 if (VDBG) { 434 Rlog.i(TAG, "Updated 5G NR SSRSRQ Level: " + ssRsrqLevel); 435 } 436 } 437 if (isLevelForParameter(USE_SSSINR)) { 438 ssSinrLevel = updateLevelWithMeasure(mSsSinr, mSsSinrThresholds); 439 if (VDBG) { 440 Rlog.i(TAG, "Updated 5G NR SSSINR Level: " + ssSinrLevel); 441 } 442 } 443 // Apply the smaller value among three levels of three measures. 444 mLevel = Math.min(Math.min(ssRsrpLevel, ssRsrqLevel), ssSinrLevel); 445 } 446 447 /** 448 * Update level with corresponding measure and thresholds. 449 * 450 * @param measure corresponding signal measure 451 * @param thresholds corresponding signal thresholds 452 * @return level of the signal strength 453 */ updateLevelWithMeasure(int measure, int[] thresholds)454 private int updateLevelWithMeasure(int measure, int[] thresholds) { 455 int level; 456 if (measure == CellInfo.UNAVAILABLE) { 457 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 458 } else if (measure > thresholds[3]) { 459 level = SIGNAL_STRENGTH_GREAT; 460 } else if (measure > thresholds[2]) { 461 level = SIGNAL_STRENGTH_GOOD; 462 } else if (measure > thresholds[1]) { 463 level = SIGNAL_STRENGTH_MODERATE; 464 } else if (measure > thresholds[0]) { 465 level = SIGNAL_STRENGTH_POOR; 466 } else { 467 level = SIGNAL_STRENGTH_NONE_OR_UNKNOWN; 468 } 469 return level; 470 } 471 472 /** 473 * Get the RSRP in ASU. 474 * 475 * Asu is calculated based on 3GPP RSRP. Refer to 3GPP 27.007 (Ver 10.3.0) Sec 8.69 476 * 477 * @return RSRP in ASU 0..97, 255, or UNAVAILABLE 478 */ 479 @Override getAsuLevel()480 public int getAsuLevel() { 481 int asuLevel; 482 int nrDbm = getDbm(); 483 if (nrDbm == CellInfo.UNAVAILABLE) { 484 asuLevel = UNKNOWN_ASU_LEVEL; 485 } else if (nrDbm <= -140) { 486 asuLevel = 0; 487 } else if (nrDbm >= -43) { 488 asuLevel = 97; 489 } else { 490 asuLevel = nrDbm + 140; 491 } 492 return asuLevel; 493 } 494 495 /** 496 * Get the SS-RSRP as dBm value -140..-44dBm or {@link CellInfo#UNAVAILABLE UNAVAILABLE}. 497 */ 498 @Override getDbm()499 public int getDbm() { 500 return mSsRsrp; 501 } 502 503 /** @hide */ CellSignalStrengthNr(CellSignalStrengthNr s)504 public CellSignalStrengthNr(CellSignalStrengthNr s) { 505 mCsiRsrp = s.mCsiRsrp; 506 mCsiRsrq = s.mCsiRsrq; 507 mCsiSinr = s.mCsiSinr; 508 mCsiCqiTableIndex = s.mCsiCqiTableIndex; 509 mCsiCqiReport = s.mCsiCqiReport; 510 mSsRsrp = s.mSsRsrp; 511 mSsRsrq = s.mSsRsrq; 512 mSsSinr = s.mSsSinr; 513 mLevel = s.mLevel; 514 mParametersUseForLevel = s.mParametersUseForLevel; 515 } 516 517 /** @hide */ 518 @Override copy()519 public CellSignalStrengthNr copy() { 520 return new CellSignalStrengthNr(this); 521 } 522 523 @Override hashCode()524 public int hashCode() { 525 return Objects.hash(mCsiRsrp, mCsiRsrq, mCsiSinr, mCsiCqiTableIndex, 526 mCsiCqiReport, mSsRsrp, mSsRsrq, mSsSinr, mLevel); 527 } 528 529 private static final CellSignalStrengthNr sInvalid = new CellSignalStrengthNr(); 530 531 /** @hide */ 532 @Override isValid()533 public boolean isValid() { 534 return !this.equals(sInvalid); 535 } 536 537 @Override equals(Object obj)538 public boolean equals(Object obj) { 539 if (obj instanceof CellSignalStrengthNr) { 540 CellSignalStrengthNr o = (CellSignalStrengthNr) obj; 541 return mCsiRsrp == o.mCsiRsrp && mCsiRsrq == o.mCsiRsrq && mCsiSinr == o.mCsiSinr 542 && mCsiCqiTableIndex == o.mCsiCqiTableIndex 543 && mCsiCqiReport.equals(o.mCsiCqiReport) 544 && mSsRsrp == o.mSsRsrp && mSsRsrq == o.mSsRsrq && mSsSinr == o.mSsSinr 545 && mLevel == o.mLevel; 546 } 547 return false; 548 } 549 550 @Override toString()551 public String toString() { 552 return new StringBuilder() 553 .append(TAG + ":{") 554 .append(" csiRsrp = " + mCsiRsrp) 555 .append(" csiRsrq = " + mCsiRsrq) 556 .append(" csiCqiTableIndex = " + mCsiCqiTableIndex) 557 .append(" csiCqiReport = " + mCsiCqiReport) 558 .append(" ssRsrp = " + mSsRsrp) 559 .append(" ssRsrq = " + mSsRsrq) 560 .append(" ssSinr = " + mSsSinr) 561 .append(" level = " + mLevel) 562 .append(" parametersUseForLevel = " + mParametersUseForLevel) 563 .append(" }") 564 .toString(); 565 } 566 567 /** Implement the Parcelable interface */ 568 public static final @android.annotation.NonNull Parcelable.Creator<CellSignalStrengthNr> CREATOR = 569 new Parcelable.Creator<CellSignalStrengthNr>() { 570 @Override 571 public CellSignalStrengthNr createFromParcel(Parcel in) { 572 return new CellSignalStrengthNr(in); 573 } 574 575 @Override 576 public CellSignalStrengthNr[] newArray(int size) { 577 return new CellSignalStrengthNr[size]; 578 } 579 }; 580 } 581