• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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