• 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.telephony.Annotation.NetworkType;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 import java.util.Arrays;
29 import java.util.Objects;
30 
31 public final class PhysicalChannelConfig implements Parcelable {
32     // TODO(b/72993578) consolidate these enums in a central location.
33     /** @hide */
34     @Retention(RetentionPolicy.SOURCE)
35     @IntDef({CONNECTION_PRIMARY_SERVING, CONNECTION_SECONDARY_SERVING, CONNECTION_UNKNOWN})
36     public @interface ConnectionStatus {}
37 
38     /**
39      * UE has connection to cell for signalling and possibly data (3GPP 36.331, 25.331).
40      */
41     public static final int CONNECTION_PRIMARY_SERVING = 1;
42 
43     /**
44      * UE has connection to cell for data (3GPP 36.331, 25.331).
45      */
46     public static final int CONNECTION_SECONDARY_SERVING = 2;
47 
48     /** Connection status is unknown. */
49     public static final int CONNECTION_UNKNOWN = -1;
50 
51     /** Channel number is unknown. */
52     public static final int CHANNEL_NUMBER_UNKNOWN = Integer.MAX_VALUE;
53 
54     /** Physical Cell Id is unknown. */
55     public static final int PHYSICAL_CELL_ID_UNKNOWN = -1;
56 
57     /** Physical Cell Id's maximum value is 1007. */
58     public static final int PHYSICAL_CELL_ID_MAXIMUM_VALUE = 1007;
59 
60     /** Cell bandwidth is unknown. */
61     public static final int CELL_BANDWIDTH_UNKNOWN = 0;
62 
63     /** The frequency is unknown. */
64     public static final int FREQUENCY_UNKNOWN = -1;
65 
66     /** The band is unknown. */
67     public static final int BAND_UNKNOWN = 0;
68 
69     /**
70      * Connection status of the cell.
71      *
72      * <p>One of {@link #CONNECTION_PRIMARY_SERVING}, {@link #CONNECTION_SECONDARY_SERVING}.
73      */
74     @ConnectionStatus
75     private int mCellConnectionStatus;
76 
77     /**
78      * Downlink cell bandwidth, in kHz.
79      */
80     private int mCellBandwidthDownlinkKhz;
81 
82     /**
83      * Uplink cell bandwidth, in kHz.
84      */
85     private int mCellBandwidthUplinkKhz;
86 
87     /**
88      * The radio technology for this physical channel.
89      */
90     @NetworkType
91     private int mNetworkType;
92 
93     /**
94      * The rough frequency range for this physical channel.
95      */
96     @ServiceState.FrequencyRange
97     private int mFrequencyRange;
98 
99     /**
100      * The frequency of Downlink.
101      */
102     private int mDownlinkFrequency;
103 
104     /**
105      * The frequency of Uplink.
106      */
107     private int mUplinkFrequency;
108 
109     /**
110      * Downlink Absolute Radio Frequency Channel Number
111      */
112     private int mDownlinkChannelNumber;
113 
114     /**
115      * Uplink Absolute Radio Frequency Channel Number
116      */
117     private int mUplinkChannelNumber;
118 
119     /**
120      * A list of data calls mapped to this physical channel. An empty list means the physical
121      * channel has no data call mapped to it.
122      */
123     private int[] mContextIds;
124 
125     /**
126      * The physical cell identifier for this cell - PCI, PSC, {@link #PHYSICAL_CELL_ID_UNKNOWN}
127      * if unknown.
128      */
129     private int mPhysicalCellId;
130 
131     /**
132      * This is the band which is being used.
133      */
134     private int mBand;
135 
136     @Override
describeContents()137     public int describeContents() {
138         return 0;
139     }
140 
141     @Override
writeToParcel(@onNull Parcel dest, int flags)142     public void writeToParcel(@NonNull Parcel dest, int flags) {
143         dest.writeInt(mCellConnectionStatus);
144         dest.writeInt(mCellBandwidthDownlinkKhz);
145         dest.writeInt(mCellBandwidthUplinkKhz);
146         dest.writeInt(mNetworkType);
147         dest.writeInt(mDownlinkChannelNumber);
148         dest.writeInt(mUplinkChannelNumber);
149         dest.writeInt(mFrequencyRange);
150         dest.writeIntArray(mContextIds);
151         dest.writeInt(mPhysicalCellId);
152         dest.writeInt(mBand);
153     }
154 
155     /**
156      * @return Downlink cell bandwidth in kHz, {@link #CELL_BANDWIDTH_UNKNOWN} if unknown.
157      */
158     @IntRange(from = 1)
getCellBandwidthDownlinkKhz()159     public int getCellBandwidthDownlinkKhz() {
160         return mCellBandwidthDownlinkKhz;
161     }
162 
163     /**
164      * @return Uplink cell bandwidth in kHz, {@link #CELL_BANDWIDTH_UNKNOWN} if unknown.
165      */
166     @IntRange(from = 1)
getCellBandwidthUplinkKhz()167     public int getCellBandwidthUplinkKhz() {
168         return mCellBandwidthUplinkKhz;
169     }
170 
171     /**
172      * Get the list of data call ids mapped to this physical channel. This list is sorted into
173      * ascending numerical order. Each id in this list must match the id in
174      * {@link com.android.internal.telephony.dataconnection.DataConnection}. An empty list means the
175      * physical channel has no data call mapped to it.
176      *
177      * @return an integer list indicates the data call ids,
178      * @hide
179      */
getContextIds()180     public int[] getContextIds() {
181         return mContextIds;
182     }
183 
184     /**
185      * @return the rough frequency range for this physical channel,
186      * {@link ServiceState#FREQUENCY_RANGE_UNKNOWN} if unknown.
187      * @see {@link ServiceState#FREQUENCY_RANGE_LOW}
188      * @see {@link ServiceState#FREQUENCY_RANGE_MID}
189      * @see {@link ServiceState#FREQUENCY_RANGE_HIGH}
190      * @see {@link ServiceState#FREQUENCY_RANGE_MMWAVE}
191      * @hide
192      */
193     @ServiceState.FrequencyRange
getFrequencyRange()194     public int getFrequencyRange() {
195         return mFrequencyRange;
196     }
197 
198     /**
199      * @return Downlink Absolute Radio Frequency Channel Number,
200      * {@link #CHANNEL_NUMBER_UNKNOWN} if unknown.
201      */
202     @IntRange(from = 0)
getDownlinkChannelNumber()203     public int getDownlinkChannelNumber() {
204         return mDownlinkChannelNumber;
205     }
206 
207     /**
208      * @return Uplink Absolute Radio Frequency Channel Number,
209      * {@link #CHANNEL_NUMBER_UNKNOWN} if unknown.
210      */
211     @IntRange(from = 0)
getUplinkChannelNumber()212     public int getUplinkChannelNumber() {
213         return mUplinkChannelNumber;
214     }
215 
216     /**
217      * The valid bands are {@link AccessNetworkConstants.GeranBand},
218      * {@link AccessNetworkConstants.UtranBand}, {@link AccessNetworkConstants.EutranBand} and
219      * {@link AccessNetworkConstants.NgranBands}.
220      *
221      * @return the frequency band, {@link #BAND_UNKNOWN} if unknown. */
222     @IntRange(from = 1, to = 261)
getBand()223     public int getBand() {
224         return mBand;
225     }
226 
227     /**
228      * @return The downlink frequency in kHz, {@link #FREQUENCY_UNKNOWN} if unknown.
229      */
230     @IntRange(from = 0)
getDownlinkFrequencyKhz()231     public int getDownlinkFrequencyKhz() {
232         return mDownlinkFrequency;
233     }
234 
235     /**
236      * @return The uplink frequency in kHz, {@link #FREQUENCY_UNKNOWN} if unknown.
237      */
238     @IntRange(from = 0)
getUplinkFrequencyKhz()239     public int getUplinkFrequencyKhz() {
240         return mUplinkFrequency;
241     }
242 
243     /**
244      * The physical cell ID which differentiates cells using the same radio channel.
245      *
246      * In GERAN, this value is the BSIC. The range is [0-63].
247      * Reference: 3GPP TS 3.03 section 4.2.2.
248      *
249      * In UTRAN, this value is primary scrambling code. The range is [0, 511].
250      * Reference: 3GPP TS 25.213 section 5.2.2.
251      *
252      * In EUTRAN, this value is physical layer cell identity. The range is [0, 503].
253      * Reference: 3GPP TS 36.211 section 6.11.
254      *
255      * In 5G RAN, this value is physical layer cell identity. The range is [0, 1007].
256      * Reference: 3GPP TS 38.211 section 7.4.2.1.
257      *
258      * @return the physical cell identifier for this cell, {@link #PHYSICAL_CELL_ID_UNKNOWN}
259      * if {@link android.telephony.CellInfo#UNAVAILABLE}.
260      */
261     @IntRange(from = 0, to = 1007)
getPhysicalCellId()262     public int getPhysicalCellId() {
263         return mPhysicalCellId;
264     }
265 
266     /**
267      * @return The network type for this physical channel,
268      * {@link TelephonyManager#NETWORK_TYPE_UNKNOWN} if unknown.
269      */
270     @NetworkType
getNetworkType()271     public int getNetworkType() {
272         return mNetworkType;
273     }
274 
275     /**
276      * Gets the connection status of the cell.
277      *
278      * @see #CONNECTION_PRIMARY_SERVING
279      * @see #CONNECTION_SECONDARY_SERVING
280      * @see #CONNECTION_UNKNOWN
281      *
282      * @return Connection status of the cell, {@link #CONNECTION_UNKNOWN} if unknown.
283      */
284     @ConnectionStatus
getConnectionStatus()285     public int getConnectionStatus() {
286         return mCellConnectionStatus;
287     }
288 
289     /**
290      * Return a copy of this PhysicalChannelConfig object but redact all the location info.
291      * @hide
292      */
createLocationInfoSanitizedCopy()293     public PhysicalChannelConfig createLocationInfoSanitizedCopy() {
294         return new Builder(this).setPhysicalCellId(PHYSICAL_CELL_ID_UNKNOWN).build();
295     }
296 
297     /**
298      * @return String representation of the connection status
299      * @hide
300      */
getConnectionStatusString()301     private String getConnectionStatusString() {
302         switch(mCellConnectionStatus) {
303             case CONNECTION_PRIMARY_SERVING:
304                 return "PrimaryServing";
305             case CONNECTION_SECONDARY_SERVING:
306                 return "SecondaryServing";
307             case CONNECTION_UNKNOWN:
308                 return "Unknown";
309             default:
310                 return "Invalid(" + mCellConnectionStatus + ")";
311         }
312     }
313 
setDownlinkFrequency()314     private void setDownlinkFrequency() {
315         switch (mNetworkType) {
316             case TelephonyManager.NETWORK_TYPE_NR:
317                 mDownlinkFrequency = AccessNetworkUtils.getFrequencyFromNrArfcn(
318                         mDownlinkChannelNumber);
319                 break;
320             case TelephonyManager.NETWORK_TYPE_LTE:
321                 mDownlinkFrequency = AccessNetworkUtils.getFrequencyFromEarfcn(
322                         mBand, mDownlinkChannelNumber, false);
323                 break;
324             case TelephonyManager.NETWORK_TYPE_HSPAP:
325             case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
326             case TelephonyManager.NETWORK_TYPE_UMTS:
327             case TelephonyManager.NETWORK_TYPE_HSDPA:
328             case TelephonyManager.NETWORK_TYPE_HSUPA:
329             case TelephonyManager.NETWORK_TYPE_HSPA:
330                 mDownlinkFrequency = AccessNetworkUtils.getFrequencyFromUarfcn(
331                         mBand, mDownlinkChannelNumber, false);
332                 break;
333             case TelephonyManager.NETWORK_TYPE_GPRS:
334             case TelephonyManager.NETWORK_TYPE_EDGE:
335             case TelephonyManager.NETWORK_TYPE_GSM:
336                 mDownlinkFrequency = AccessNetworkUtils.getFrequencyFromArfcn(
337                         mBand, mDownlinkChannelNumber, false);
338                 break;
339         }
340     }
341 
setUplinkFrequency()342     private void setUplinkFrequency() {
343         switch (mNetworkType){
344             case TelephonyManager.NETWORK_TYPE_NR:
345                 mUplinkFrequency = AccessNetworkUtils.getFrequencyFromNrArfcn(
346                         mUplinkChannelNumber);
347                 break;
348             case TelephonyManager.NETWORK_TYPE_LTE:
349                 mUplinkFrequency = AccessNetworkUtils.getFrequencyFromEarfcn(
350                         mBand, mUplinkChannelNumber, true);
351                 break;
352             case TelephonyManager.NETWORK_TYPE_HSPAP:
353             case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
354             case TelephonyManager.NETWORK_TYPE_UMTS:
355             case TelephonyManager.NETWORK_TYPE_HSDPA:
356             case TelephonyManager.NETWORK_TYPE_HSUPA:
357             case TelephonyManager.NETWORK_TYPE_HSPA:
358                 mUplinkFrequency = AccessNetworkUtils.getFrequencyFromUarfcn(
359                         mBand, mUplinkChannelNumber, true);
360                 break;
361             case TelephonyManager.NETWORK_TYPE_GPRS:
362             case TelephonyManager.NETWORK_TYPE_EDGE:
363             case TelephonyManager.NETWORK_TYPE_GSM:
364                 mUplinkFrequency = AccessNetworkUtils.getFrequencyFromArfcn(
365                         mBand, mUplinkChannelNumber, true);
366                 break;
367         }
368     }
369 
setFrequencyRange()370     private void setFrequencyRange() {
371         if (mFrequencyRange != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
372             return;
373         }
374 
375         switch (mNetworkType) {
376             case TelephonyManager.NETWORK_TYPE_NR:
377                 mFrequencyRange = AccessNetworkUtils.getFrequencyRangeGroupFromNrBand(mBand);
378                 break;
379             case TelephonyManager.NETWORK_TYPE_LTE:
380                 mFrequencyRange = AccessNetworkUtils.getFrequencyRangeGroupFromEutranBand(mBand);
381                 break;
382             case TelephonyManager.NETWORK_TYPE_HSPAP:
383             case TelephonyManager.NETWORK_TYPE_TD_SCDMA:
384             case TelephonyManager.NETWORK_TYPE_UMTS:
385             case TelephonyManager.NETWORK_TYPE_HSDPA:
386             case TelephonyManager.NETWORK_TYPE_HSUPA:
387             case TelephonyManager.NETWORK_TYPE_HSPA:
388                 mFrequencyRange = AccessNetworkUtils.getFrequencyRangeGroupFromUtranBand(mBand);
389                 break;
390             case TelephonyManager.NETWORK_TYPE_GPRS:
391             case TelephonyManager.NETWORK_TYPE_EDGE:
392             case TelephonyManager.NETWORK_TYPE_GSM:
393                 mFrequencyRange = AccessNetworkUtils.getFrequencyRangeGroupFromGeranBand(mBand);
394                 break;
395             default:
396                 mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
397                 break;
398         }
399 
400         if (mFrequencyRange == ServiceState.FREQUENCY_RANGE_UNKNOWN) {
401             mFrequencyRange = AccessNetworkUtils.getFrequencyRangeFromArfcn(
402                     mDownlinkFrequency);
403         }
404     }
405 
406     @Override
equals(Object o)407     public boolean equals(Object o) {
408         if (this == o) {
409             return true;
410         }
411 
412         if (!(o instanceof PhysicalChannelConfig)) {
413             return false;
414         }
415 
416         PhysicalChannelConfig config = (PhysicalChannelConfig) o;
417         return mCellConnectionStatus == config.mCellConnectionStatus
418                 && mCellBandwidthDownlinkKhz == config.mCellBandwidthDownlinkKhz
419                 && mCellBandwidthUplinkKhz == config.mCellBandwidthUplinkKhz
420                 && mNetworkType == config.mNetworkType
421                 && mFrequencyRange == config.mFrequencyRange
422                 && mDownlinkChannelNumber == config.mDownlinkChannelNumber
423                 && mUplinkChannelNumber == config.mUplinkChannelNumber
424                 && mPhysicalCellId == config.mPhysicalCellId
425                 && Arrays.equals(mContextIds, config.mContextIds)
426                 && mBand == config.mBand
427                 && mDownlinkFrequency == config.mDownlinkFrequency
428                 && mUplinkFrequency == config.mUplinkFrequency;
429     }
430 
431     @Override
hashCode()432     public int hashCode() {
433         return Objects.hash(
434                 mCellConnectionStatus, mCellBandwidthDownlinkKhz, mCellBandwidthUplinkKhz,
435                 mNetworkType, mFrequencyRange, mDownlinkChannelNumber, mUplinkChannelNumber,
436                 mContextIds, mPhysicalCellId, mBand, mDownlinkFrequency, mUplinkFrequency);
437     }
438 
439     public static final
440     @android.annotation.NonNull Parcelable.Creator<PhysicalChannelConfig> CREATOR =
441             new Parcelable.Creator<PhysicalChannelConfig>() {
442                 public PhysicalChannelConfig createFromParcel(Parcel in) {
443                     return new PhysicalChannelConfig(in);
444                 }
445 
446                 public PhysicalChannelConfig[] newArray(int size) {
447                     return new PhysicalChannelConfig[size];
448                 }
449             };
450 
451     @Override
toString()452     public String toString() {
453         return new StringBuilder()
454                 .append("{mConnectionStatus=")
455                 .append(getConnectionStatusString())
456                 .append(",mCellBandwidthDownlinkKhz=")
457                 .append(mCellBandwidthDownlinkKhz)
458                 .append(",mCellBandwidthUplinkKhz=")
459                 .append(mCellBandwidthUplinkKhz)
460                 .append(",mNetworkType=")
461                 .append(TelephonyManager.getNetworkTypeName(mNetworkType))
462                 .append(",mFrequencyRange=")
463                 .append(ServiceState.frequencyRangeToString(mFrequencyRange))
464                 .append(",mDownlinkChannelNumber=")
465                 .append(mDownlinkChannelNumber)
466                 .append(",mUplinkChannelNumber=")
467                 .append(mUplinkChannelNumber)
468                 .append(",mContextIds=")
469                 .append(Arrays.toString(mContextIds))
470                 .append(",mPhysicalCellId=")
471                 .append(mPhysicalCellId)
472                 .append(",mBand=")
473                 .append(mBand)
474                 .append(",mDownlinkFrequency=")
475                 .append(mDownlinkFrequency)
476                 .append(",mUplinkFrequency=")
477                 .append(mUplinkFrequency)
478                 .append("}")
479                 .toString();
480     }
481 
PhysicalChannelConfig(Parcel in)482     private PhysicalChannelConfig(Parcel in) {
483         mCellConnectionStatus = in.readInt();
484         mCellBandwidthDownlinkKhz = in.readInt();
485         mCellBandwidthUplinkKhz = in.readInt();
486         mNetworkType = in.readInt();
487         mDownlinkChannelNumber = in.readInt();
488         mUplinkChannelNumber = in.readInt();
489         mFrequencyRange = in.readInt();
490         mContextIds = in.createIntArray();
491         mPhysicalCellId = in.readInt();
492         mBand = in.readInt();
493         if (mBand > BAND_UNKNOWN) {
494             setDownlinkFrequency();
495             setUplinkFrequency();
496             setFrequencyRange();
497         }
498     }
499 
PhysicalChannelConfig(Builder builder)500     private PhysicalChannelConfig(Builder builder) {
501         mCellConnectionStatus = builder.mCellConnectionStatus;
502         mCellBandwidthDownlinkKhz = builder.mCellBandwidthDownlinkKhz;
503         mCellBandwidthUplinkKhz = builder.mCellBandwidthUplinkKhz;
504         mNetworkType = builder.mNetworkType;
505         mDownlinkChannelNumber = builder.mDownlinkChannelNumber;
506         mUplinkChannelNumber = builder.mUplinkChannelNumber;
507         mFrequencyRange = builder.mFrequencyRange;
508         mContextIds = builder.mContextIds;
509         mPhysicalCellId = builder.mPhysicalCellId;
510         mBand = builder.mBand;
511         if (mBand > BAND_UNKNOWN) {
512             setDownlinkFrequency();
513             setUplinkFrequency();
514             setFrequencyRange();
515         }
516     }
517 
518     /**
519      * The builder of {@code PhysicalChannelConfig}.
520      * @hide
521      */
522     public static final class Builder {
523         private int mNetworkType;
524         private int mFrequencyRange;
525         private int mDownlinkChannelNumber;
526         private int mUplinkChannelNumber;
527         private int mCellBandwidthDownlinkKhz;
528         private int mCellBandwidthUplinkKhz;
529         private int mCellConnectionStatus;
530         private int[] mContextIds;
531         private int mPhysicalCellId;
532         private int mBand;
533 
Builder()534         public Builder() {
535             mNetworkType = TelephonyManager.NETWORK_TYPE_UNKNOWN;
536             mFrequencyRange = ServiceState.FREQUENCY_RANGE_UNKNOWN;
537             mDownlinkChannelNumber = CHANNEL_NUMBER_UNKNOWN;
538             mUplinkChannelNumber = CHANNEL_NUMBER_UNKNOWN;
539             mCellBandwidthDownlinkKhz = CELL_BANDWIDTH_UNKNOWN;
540             mCellBandwidthUplinkKhz = CELL_BANDWIDTH_UNKNOWN;
541             mCellConnectionStatus = CONNECTION_UNKNOWN;
542             mContextIds = new int[0];
543             mPhysicalCellId = PHYSICAL_CELL_ID_UNKNOWN;
544             mBand = BAND_UNKNOWN;
545         }
546 
547         /**
548          * Builder object constructed from existing PhysicalChannelConfig object.
549          * @hide
550          */
Builder(PhysicalChannelConfig config)551         public Builder(PhysicalChannelConfig config) {
552             mNetworkType = config.getNetworkType();
553             mFrequencyRange = config.getFrequencyRange();
554             mDownlinkChannelNumber = config.getDownlinkChannelNumber();
555             mUplinkChannelNumber = config.getUplinkChannelNumber();
556             mCellBandwidthDownlinkKhz = config.getCellBandwidthDownlinkKhz();
557             mCellBandwidthUplinkKhz = config.getCellBandwidthUplinkKhz();
558             mCellConnectionStatus = config.getConnectionStatus();
559             mContextIds = Arrays.copyOf(config.getContextIds(), config.getContextIds().length);
560             mPhysicalCellId = config.getPhysicalCellId();
561             mBand = config.getBand();
562         }
563 
build()564         public PhysicalChannelConfig build() {
565             return new PhysicalChannelConfig(this);
566         }
567 
setNetworkType(@etworkType int networkType)568         public @NonNull Builder setNetworkType(@NetworkType int networkType) {
569             if (!TelephonyManager.isNetworkTypeValid(networkType)) {
570                 throw new IllegalArgumentException("Network type " + networkType + " is invalid.");
571             }
572             mNetworkType = networkType;
573             return this;
574         }
575 
setFrequencyRange(int frequencyRange)576         public @NonNull Builder setFrequencyRange(int frequencyRange) {
577             if (!ServiceState.isFrequencyRangeValid(frequencyRange)
578                     && frequencyRange != ServiceState.FREQUENCY_RANGE_UNKNOWN) {
579                 throw new IllegalArgumentException("Frequency range " + frequencyRange
580                         + " is invalid.");
581             }
582             mFrequencyRange = frequencyRange;
583             return this;
584         }
585 
setDownlinkChannelNumber(int downlinkChannelNumber)586         public @NonNull Builder setDownlinkChannelNumber(int downlinkChannelNumber) {
587             mDownlinkChannelNumber = downlinkChannelNumber;
588             return this;
589         }
590 
setUplinkChannelNumber(int uplinkChannelNumber)591         public @NonNull Builder setUplinkChannelNumber(int uplinkChannelNumber) {
592             mUplinkChannelNumber = uplinkChannelNumber;
593             return this;
594         }
595 
setCellBandwidthDownlinkKhz(int cellBandwidthDownlinkKhz)596         public @NonNull Builder setCellBandwidthDownlinkKhz(int cellBandwidthDownlinkKhz) {
597             if (cellBandwidthDownlinkKhz < CELL_BANDWIDTH_UNKNOWN) {
598                 throw new IllegalArgumentException("Cell downlink bandwidth(kHz) "
599                         + cellBandwidthDownlinkKhz + " is invalid.");
600             }
601             mCellBandwidthDownlinkKhz = cellBandwidthDownlinkKhz;
602             return this;
603         }
604 
setCellBandwidthUplinkKhz(int cellBandwidthUplinkKhz)605         public @NonNull Builder setCellBandwidthUplinkKhz(int cellBandwidthUplinkKhz) {
606             if (cellBandwidthUplinkKhz < CELL_BANDWIDTH_UNKNOWN) {
607                 throw new IllegalArgumentException("Cell uplink bandwidth(kHz) "
608                         + cellBandwidthUplinkKhz + " is invalid.");
609             }
610             mCellBandwidthUplinkKhz = cellBandwidthUplinkKhz;
611             return this;
612         }
613 
setCellConnectionStatus(int connectionStatus)614         public @NonNull Builder setCellConnectionStatus(int connectionStatus) {
615             mCellConnectionStatus = connectionStatus;
616             return this;
617         }
618 
setContextIds(int[] contextIds)619         public @NonNull Builder setContextIds(int[] contextIds) {
620             if (contextIds != null) Arrays.sort(contextIds);
621             mContextIds = contextIds;
622             return this;
623         }
624 
setPhysicalCellId(int physicalCellId)625         public @NonNull Builder setPhysicalCellId(int physicalCellId) {
626             if (physicalCellId > PHYSICAL_CELL_ID_MAXIMUM_VALUE) {
627                 throw new IllegalArgumentException("Physical cell ID " + physicalCellId
628                         + " is over limit.");
629             }
630             mPhysicalCellId = physicalCellId;
631             return this;
632         }
633 
setBand(int band)634         public @NonNull Builder setBand(int band) {
635             if (band <= BAND_UNKNOWN) {
636                 throw new IllegalArgumentException("Band " + band + " is invalid.");
637             }
638             mBand = band;
639             return this;
640         }
641     }
642 }
643