• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.annotation.ElapsedRealtimeLong;
20 import android.annotation.IntDef;
21 import android.annotation.NonNull;
22 import android.compat.annotation.UnsupportedAppUsage;
23 import android.hardware.radio.V1_4.CellInfo.Info;
24 import android.os.Parcel;
25 import android.os.Parcelable;
26 
27 import com.android.internal.annotations.VisibleForTesting;
28 
29 import java.lang.annotation.Retention;
30 import java.lang.annotation.RetentionPolicy;
31 import java.util.Objects;
32 
33 /**
34  * Immutable cell information from a point in time.
35  */
36 public abstract class CellInfo implements Parcelable {
37 
38     /**
39      * This value indicates that the integer field is unreported.
40      */
41     public static final int UNAVAILABLE = Integer.MAX_VALUE;
42 
43     /**
44      * This value indicates that the long field is unreported.
45      */
46     public static final long UNAVAILABLE_LONG = Long.MAX_VALUE;
47 
48     /**
49      * Cell identity type
50      * @hide
51      */
52     @Retention(RetentionPolicy.SOURCE)
53     @IntDef(prefix = "TYPE_",
54             value = {TYPE_GSM, TYPE_CDMA, TYPE_LTE, TYPE_WCDMA, TYPE_TDSCDMA, TYPE_NR})
55     public @interface Type {}
56 
57     /**
58      * Unknown cell identity type
59      * @hide
60      */
61     public static final int TYPE_UNKNOWN = 0;
62 
63     /**
64      * GSM cell identity type
65      * @hide
66      */
67     public static final int TYPE_GSM = 1;
68 
69     /**
70      * CDMA cell identity type
71      * @hide
72      */
73     public static final int TYPE_CDMA = 2;
74 
75     /**
76      * LTE cell identity type
77      * @hide
78      */
79     public static final int TYPE_LTE = 3;
80 
81     /**
82      * WCDMA cell identity type
83      * @hide
84      */
85     public static final int TYPE_WCDMA = 4;
86 
87     /**
88      * TD-SCDMA cell identity type
89      * @hide
90      */
91     public static final int TYPE_TDSCDMA = 5;
92 
93     /**
94      * 5G cell identity type
95      * @hide
96      */
97     public static final int TYPE_NR = 6;
98 
99     // Type to distinguish where time stamp gets recorded.
100 
101     /** @hide */
102     @UnsupportedAppUsage
103     public static final int TIMESTAMP_TYPE_UNKNOWN = 0;
104     /** @hide */
105     @UnsupportedAppUsage
106     public static final int TIMESTAMP_TYPE_ANTENNA = 1;
107     /** @hide */
108     @UnsupportedAppUsage
109     public static final int TIMESTAMP_TYPE_MODEM = 2;
110     /** @hide */
111     @UnsupportedAppUsage
112     public static final int TIMESTAMP_TYPE_OEM_RIL = 3;
113     /** @hide */
114     @UnsupportedAppUsage
115     public static final int TIMESTAMP_TYPE_JAVA_RIL = 4;
116 
117     /** @hide */
118     @Retention(RetentionPolicy.SOURCE)
119     @IntDef({
120         CONNECTION_NONE,
121         CONNECTION_PRIMARY_SERVING,
122         CONNECTION_SECONDARY_SERVING,
123         CONNECTION_UNKNOWN
124     })
125     public @interface CellConnectionStatus {}
126 
127     /**
128      * Cell is not a serving cell.
129      *
130      * <p>The cell has been measured but is neither a camped nor serving cell (3GPP 36.304).
131      */
132     public static final int CONNECTION_NONE = 0;
133 
134     /** UE is connected to cell for signalling and possibly data (3GPP 36.331, 25.331). */
135     public static final int CONNECTION_PRIMARY_SERVING = 1;
136 
137     /** UE is connected to cell for data (3GPP 36.331, 25.331). */
138     public static final int CONNECTION_SECONDARY_SERVING = 2;
139 
140     /** Connection status is unknown. */
141     public static final int CONNECTION_UNKNOWN = Integer.MAX_VALUE;
142 
143     /** A cell connection status */
144     private int mCellConnectionStatus;
145 
146     // True if device is mRegistered to the mobile network
147     private boolean mRegistered;
148 
149     // Observation time stamped as type in nanoseconds since boot
150     private long mTimeStamp;
151 
152     /** @hide */
CellInfo()153     protected CellInfo() {
154         this.mRegistered = false;
155         this.mTimeStamp = Long.MAX_VALUE;
156         this.mCellConnectionStatus = CONNECTION_NONE;
157     }
158 
159     /** @hide */
CellInfo(CellInfo ci)160     protected CellInfo(CellInfo ci) {
161         this.mRegistered = ci.mRegistered;
162         this.mTimeStamp = ci.mTimeStamp;
163         this.mCellConnectionStatus = ci.mCellConnectionStatus;
164     }
165 
166     /**
167      * True if the phone is registered to a mobile network that provides service on this cell
168      * and this cell is being used or would be used for network signaling.
169      */
isRegistered()170     public boolean isRegistered() {
171         return mRegistered;
172     }
173 
174     /** @hide */
setRegistered(boolean registered)175     public void setRegistered(boolean registered) {
176         mRegistered = registered;
177     }
178 
179     /**
180      * Approximate time this cell information was received from the modem.
181      *
182      * @return a time stamp in millis since boot.
183      */
184     @ElapsedRealtimeLong
getTimestampMillis()185     public long getTimestampMillis() {
186         return mTimeStamp / 1000000;
187     }
188 
189     /**
190      * Approximate time this cell information was received from the modem.
191      *
192      * @return a time stamp in nanos since boot.
193      * @deprecated Use {@link #getTimestampMillis} instead.
194      */
195     @Deprecated
getTimeStamp()196     public long getTimeStamp() {
197         return mTimeStamp;
198     }
199 
200     /** @hide */
201     @VisibleForTesting
setTimeStamp(long ts)202     public void setTimeStamp(long ts) {
203         mTimeStamp = ts;
204     }
205 
206     /**
207      * @return a {@link CellIdentity} instance.
208      */
209     @NonNull
getCellIdentity()210     public abstract CellIdentity getCellIdentity();
211 
212     /**
213      * @return a {@link CellSignalStrength} instance.
214      */
215     @NonNull
getCellSignalStrength()216     public abstract CellSignalStrength getCellSignalStrength();
217 
218     /** @hide */
sanitizeLocationInfo()219     public CellInfo sanitizeLocationInfo() {
220         return null;
221     }
222 
223     /**
224      * Gets the connection status of this cell.
225      *
226      * @see #CONNECTION_NONE
227      * @see #CONNECTION_PRIMARY_SERVING
228      * @see #CONNECTION_SECONDARY_SERVING
229      * @see #CONNECTION_UNKNOWN
230      *
231      * @return The connection status of the cell.
232      */
233     @CellConnectionStatus
getCellConnectionStatus()234     public int getCellConnectionStatus() {
235         return mCellConnectionStatus;
236     }
237     /** @hide */
setCellConnectionStatus(@ellConnectionStatus int cellConnectionStatus)238     public void setCellConnectionStatus(@CellConnectionStatus int cellConnectionStatus) {
239         mCellConnectionStatus = cellConnectionStatus;
240     }
241 
242     @Override
hashCode()243     public int hashCode() {
244         return Objects.hash(mCellConnectionStatus, mRegistered, mTimeStamp);
245     }
246 
247     @Override
equals(Object o)248     public boolean equals(Object o) {
249         if (this == o) return true;
250         if (!(o instanceof CellInfo)) return false;
251         CellInfo cellInfo = (CellInfo) o;
252         return mCellConnectionStatus == cellInfo.mCellConnectionStatus
253                 && mRegistered == cellInfo.mRegistered
254                 && mTimeStamp == cellInfo.mTimeStamp;
255     }
256 
257     @Override
toString()258     public String toString() {
259         StringBuffer sb = new StringBuffer();
260 
261         sb.append("mRegistered=").append(mRegistered ? "YES" : "NO");
262         sb.append(" mTimeStamp=").append(mTimeStamp).append("ns");
263         sb.append(" mCellConnectionStatus=").append(mCellConnectionStatus);
264 
265         return sb.toString();
266     }
267 
268     /**
269      * Implement the Parcelable interface
270      */
271     @Override
describeContents()272     public int describeContents() {
273         return 0;
274     }
275 
276     /** Implement the Parcelable interface */
277     @Override
writeToParcel(Parcel dest, int flags)278     public abstract void writeToParcel(Parcel dest, int flags);
279 
280     /**
281      * Used by child classes for parceling.
282      *
283      * @hide
284      */
writeToParcel(Parcel dest, int flags, int type)285     protected void writeToParcel(Parcel dest, int flags, int type) {
286         dest.writeInt(type);
287         dest.writeInt(mRegistered ? 1 : 0);
288         dest.writeLong(mTimeStamp);
289         dest.writeInt(mCellConnectionStatus);
290     }
291 
292     /**
293      * Used by child classes for parceling
294      *
295      * @hide
296      */
CellInfo(Parcel in)297     protected CellInfo(Parcel in) {
298         mRegistered = (in.readInt() == 1) ? true : false;
299         mTimeStamp = in.readLong();
300         mCellConnectionStatus = in.readInt();
301     }
302 
303     /** Implement the Parcelable interface */
304     public static final @android.annotation.NonNull Creator<CellInfo> CREATOR = new Creator<CellInfo>() {
305         @Override
306         public CellInfo createFromParcel(Parcel in) {
307                 int type = in.readInt();
308                 switch (type) {
309                     case TYPE_GSM: return CellInfoGsm.createFromParcelBody(in);
310                     case TYPE_CDMA: return CellInfoCdma.createFromParcelBody(in);
311                     case TYPE_LTE: return CellInfoLte.createFromParcelBody(in);
312                     case TYPE_WCDMA: return CellInfoWcdma.createFromParcelBody(in);
313                     case TYPE_TDSCDMA: return CellInfoTdscdma.createFromParcelBody(in);
314                     case TYPE_NR: return CellInfoNr.createFromParcelBody(in);
315                     default: throw new RuntimeException("Bad CellInfo Parcel");
316                 }
317         }
318 
319         @Override
320         public CellInfo[] newArray(int size) {
321             return new CellInfo[size];
322         }
323     };
324 
325     /** @hide */
CellInfo(android.hardware.radio.V1_0.CellInfo ci)326     protected CellInfo(android.hardware.radio.V1_0.CellInfo ci) {
327         this.mRegistered = ci.registered;
328         this.mTimeStamp = ci.timeStamp;
329         this.mCellConnectionStatus = CONNECTION_UNKNOWN;
330     }
331 
332     /** @hide */
CellInfo(android.hardware.radio.V1_2.CellInfo ci)333     protected CellInfo(android.hardware.radio.V1_2.CellInfo ci) {
334         this.mRegistered = ci.registered;
335         this.mTimeStamp = ci.timeStamp;
336         this.mCellConnectionStatus = ci.connectionStatus;
337     }
338 
339     /** @hide */
CellInfo(android.hardware.radio.V1_4.CellInfo ci, long timeStamp)340     protected CellInfo(android.hardware.radio.V1_4.CellInfo ci, long timeStamp) {
341         this.mRegistered = ci.isRegistered;
342         this.mTimeStamp = timeStamp;
343         this.mCellConnectionStatus = ci.connectionStatus;
344     }
345 
346     /** @hide */
CellInfo(android.hardware.radio.V1_5.CellInfo ci, long timeStamp)347     protected CellInfo(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
348         this.mRegistered = ci.registered;
349         this.mTimeStamp = timeStamp;
350         this.mCellConnectionStatus = ci.connectionStatus;
351     }
352 
353     /** @hide */
CellInfo(android.hardware.radio.V1_6.CellInfo ci, long timeStamp)354     protected CellInfo(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
355         this.mRegistered = ci.registered;
356         this.mTimeStamp = timeStamp;
357         this.mCellConnectionStatus = ci.connectionStatus;
358     }
359 
360     /** @hide */
create(android.hardware.radio.V1_0.CellInfo ci)361     public static CellInfo create(android.hardware.radio.V1_0.CellInfo ci) {
362         if (ci == null) return null;
363         switch(ci.cellInfoType) {
364             case android.hardware.radio.V1_0.CellInfoType.GSM: return new CellInfoGsm(ci);
365             case android.hardware.radio.V1_0.CellInfoType.CDMA: return new CellInfoCdma(ci);
366             case android.hardware.radio.V1_0.CellInfoType.LTE: return new CellInfoLte(ci);
367             case android.hardware.radio.V1_0.CellInfoType.WCDMA: return new CellInfoWcdma(ci);
368             case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA: return new CellInfoTdscdma(ci);
369             default: return null;
370         }
371     }
372 
373     /** @hide */
create(android.hardware.radio.V1_2.CellInfo ci)374     public static CellInfo create(android.hardware.radio.V1_2.CellInfo ci) {
375         if (ci == null) return null;
376         switch(ci.cellInfoType) {
377             case android.hardware.radio.V1_0.CellInfoType.GSM: return new CellInfoGsm(ci);
378             case android.hardware.radio.V1_0.CellInfoType.CDMA: return new CellInfoCdma(ci);
379             case android.hardware.radio.V1_0.CellInfoType.LTE: return new CellInfoLte(ci);
380             case android.hardware.radio.V1_0.CellInfoType.WCDMA: return new CellInfoWcdma(ci);
381             case android.hardware.radio.V1_0.CellInfoType.TD_SCDMA: return new CellInfoTdscdma(ci);
382             default: return null;
383         }
384     }
385 
386     /** @hide */
create(android.hardware.radio.V1_4.CellInfo ci, long timeStamp)387     public static CellInfo create(android.hardware.radio.V1_4.CellInfo ci, long timeStamp) {
388         if (ci == null) return null;
389         switch (ci.info.getDiscriminator()) {
390             case Info.hidl_discriminator.gsm: return new CellInfoGsm(ci, timeStamp);
391             case Info.hidl_discriminator.cdma: return new CellInfoCdma(ci, timeStamp);
392             case Info.hidl_discriminator.lte: return new CellInfoLte(ci, timeStamp);
393             case Info.hidl_discriminator.wcdma: return new CellInfoWcdma(ci, timeStamp);
394             case Info.hidl_discriminator.tdscdma: return new CellInfoTdscdma(ci, timeStamp);
395             case Info.hidl_discriminator.nr: return new CellInfoNr(ci, timeStamp);
396             default: return null;
397         }
398     }
399 
400     /** @hide */
create(android.hardware.radio.V1_5.CellInfo ci, long timeStamp)401     public static CellInfo create(android.hardware.radio.V1_5.CellInfo ci, long timeStamp) {
402         if (ci == null) return null;
403         switch (ci.ratSpecificInfo.getDiscriminator()) {
404             case android.hardware.radio.V1_5.CellInfo
405                     .CellInfoRatSpecificInfo.hidl_discriminator.gsm:
406                 return new CellInfoGsm(ci, timeStamp);
407             case android.hardware.radio.V1_5.CellInfo
408                     .CellInfoRatSpecificInfo.hidl_discriminator.cdma:
409                 return new CellInfoCdma(ci, timeStamp);
410             case android.hardware.radio.V1_5.CellInfo
411                     .CellInfoRatSpecificInfo.hidl_discriminator.lte:
412                 return new CellInfoLte(ci, timeStamp);
413             case android.hardware.radio.V1_5.CellInfo
414                     .CellInfoRatSpecificInfo.hidl_discriminator.wcdma:
415                 return new CellInfoWcdma(ci, timeStamp);
416             case android.hardware.radio.V1_5.CellInfo
417                     .CellInfoRatSpecificInfo.hidl_discriminator.tdscdma:
418                 return new CellInfoTdscdma(ci, timeStamp);
419             case android.hardware.radio.V1_5.CellInfo
420                     .CellInfoRatSpecificInfo.hidl_discriminator.nr:
421                 return new CellInfoNr(ci, timeStamp);
422             default: return null;
423         }
424     }
425 
426     /** @hide */
create(android.hardware.radio.V1_6.CellInfo ci, long timeStamp)427     public static CellInfo create(android.hardware.radio.V1_6.CellInfo ci, long timeStamp) {
428         if (ci == null) return null;
429         switch (ci.ratSpecificInfo.getDiscriminator()) {
430             case android.hardware.radio.V1_6.CellInfo
431                     .CellInfoRatSpecificInfo.hidl_discriminator.gsm:
432                 return new CellInfoGsm(ci, timeStamp);
433             case android.hardware.radio.V1_6.CellInfo
434                     .CellInfoRatSpecificInfo.hidl_discriminator.cdma:
435                 return new CellInfoCdma(ci, timeStamp);
436             case android.hardware.radio.V1_6.CellInfo
437                     .CellInfoRatSpecificInfo.hidl_discriminator.lte:
438                 return new CellInfoLte(ci, timeStamp);
439             case android.hardware.radio.V1_6.CellInfo
440                     .CellInfoRatSpecificInfo.hidl_discriminator.wcdma:
441                 return new CellInfoWcdma(ci, timeStamp);
442             case android.hardware.radio.V1_6.CellInfo
443                     .CellInfoRatSpecificInfo.hidl_discriminator.tdscdma:
444                 return new CellInfoTdscdma(ci, timeStamp);
445             case android.hardware.radio.V1_6.CellInfo
446                     .CellInfoRatSpecificInfo.hidl_discriminator.nr:
447                 return new CellInfoNr(ci, timeStamp);
448             default: return null;
449         }
450     }
451 }
452