• 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.os.Parcel;
24 import android.os.Parcelable;
25 
26 import com.android.internal.annotations.VisibleForTesting;
27 
28 import java.lang.annotation.Retention;
29 import java.lang.annotation.RetentionPolicy;
30 import java.util.Objects;
31 
32 /**
33  * Immutable cell information from a point in time.
34  */
35 public abstract class CellInfo implements Parcelable {
36 
37     /**
38      * This value indicates that the integer field is unreported.
39      */
40     public static final int UNAVAILABLE = Integer.MAX_VALUE;
41 
42     /**
43      * This value indicates that the long field is unreported.
44      */
45     public static final long UNAVAILABLE_LONG = Long.MAX_VALUE;
46 
47     /**
48      * Cell identity type
49      * @hide
50      */
51     @Retention(RetentionPolicy.SOURCE)
52     @IntDef(prefix = "TYPE_",
53             value = {TYPE_GSM, TYPE_CDMA, TYPE_LTE, TYPE_WCDMA, TYPE_TDSCDMA, TYPE_NR})
54     public @interface Type {}
55 
56     /**
57      * Unknown cell identity type
58      * @hide
59      */
60     public static final int TYPE_UNKNOWN = 0;
61 
62     /**
63      * GSM cell identity type
64      * @hide
65      */
66     public static final int TYPE_GSM = 1;
67 
68     /**
69      * CDMA cell identity type
70      * @hide
71      */
72     public static final int TYPE_CDMA = 2;
73 
74     /**
75      * LTE cell identity type
76      * @hide
77      */
78     public static final int TYPE_LTE = 3;
79 
80     /**
81      * WCDMA cell identity type
82      * @hide
83      */
84     public static final int TYPE_WCDMA = 4;
85 
86     /**
87      * TD-SCDMA cell identity type
88      * @hide
89      */
90     public static final int TYPE_TDSCDMA = 5;
91 
92     /**
93      * 5G cell identity type
94      * @hide
95      */
96     public static final int TYPE_NR = 6;
97 
98     // Type to distinguish where time stamp gets recorded.
99 
100     /** @hide */
101     @UnsupportedAppUsage
102     public static final int TIMESTAMP_TYPE_UNKNOWN = 0;
103     /** @hide */
104     @UnsupportedAppUsage
105     public static final int TIMESTAMP_TYPE_ANTENNA = 1;
106     /** @hide */
107     @UnsupportedAppUsage
108     public static final int TIMESTAMP_TYPE_MODEM = 2;
109     /** @hide */
110     @UnsupportedAppUsage
111     public static final int TIMESTAMP_TYPE_OEM_RIL = 3;
112     /** @hide */
113     @UnsupportedAppUsage
114     public static final int TIMESTAMP_TYPE_JAVA_RIL = 4;
115 
116     /** @hide */
117     @Retention(RetentionPolicy.SOURCE)
118     @IntDef({
119         CONNECTION_NONE,
120         CONNECTION_PRIMARY_SERVING,
121         CONNECTION_SECONDARY_SERVING,
122         CONNECTION_UNKNOWN
123     })
124     public @interface CellConnectionStatus {}
125 
126     /**
127      * Cell is not a serving cell.
128      *
129      * <p>The cell has been measured but is neither a camped nor serving cell (3GPP 36.304).
130      */
131     public static final int CONNECTION_NONE = 0;
132 
133     /** UE is connected to cell for signalling and possibly data (3GPP 36.331, 25.331). */
134     public static final int CONNECTION_PRIMARY_SERVING = 1;
135 
136     /** UE is connected to cell for data (3GPP 36.331, 25.331). */
137     public static final int CONNECTION_SECONDARY_SERVING = 2;
138 
139     /** Connection status is unknown. */
140     public static final int CONNECTION_UNKNOWN = Integer.MAX_VALUE;
141 
142     /** A cell connection status */
143     private int mCellConnectionStatus;
144 
145     // True if device is mRegistered to the mobile network
146     private boolean mRegistered;
147 
148     // Observation time stamped as type in nanoseconds since boot
149     private long mTimeStamp;
150 
151     /** @hide */
CellInfo(int cellConnectionStatus, boolean registered, long timestamp)152     protected CellInfo(int cellConnectionStatus, boolean registered, long timestamp) {
153         mCellConnectionStatus = cellConnectionStatus;
154         mRegistered = registered;
155         mTimeStamp = timestamp;
156     }
157 
158     /** @hide */
CellInfo()159     protected CellInfo() {
160         this.mRegistered = false;
161         this.mTimeStamp = Long.MAX_VALUE;
162         this.mCellConnectionStatus = CONNECTION_NONE;
163     }
164 
165     /** @hide */
CellInfo(CellInfo ci)166     protected CellInfo(CellInfo ci) {
167         this.mRegistered = ci.mRegistered;
168         this.mTimeStamp = ci.mTimeStamp;
169         this.mCellConnectionStatus = ci.mCellConnectionStatus;
170     }
171 
172     /**
173      * True if the phone is registered to a mobile network that provides service on this cell
174      * and this cell is being used or would be used for network signaling.
175      */
isRegistered()176     public boolean isRegistered() {
177         return mRegistered;
178     }
179 
180     /** @hide */
setRegistered(boolean registered)181     public void setRegistered(boolean registered) {
182         mRegistered = registered;
183     }
184 
185     /**
186      * Approximate time this cell information was received from the modem.
187      *
188      * @return a time stamp in millis since boot.
189      */
190     @ElapsedRealtimeLong
getTimestampMillis()191     public long getTimestampMillis() {
192         return mTimeStamp / 1000000;
193     }
194 
195     /**
196      * Approximate time this cell information was received from the modem.
197      *
198      * @return a time stamp in nanos since boot.
199      * @deprecated Use {@link #getTimestampMillis} instead.
200      */
201     @Deprecated
getTimeStamp()202     public long getTimeStamp() {
203         return mTimeStamp;
204     }
205 
206     /** @hide */
207     @VisibleForTesting
setTimeStamp(long ts)208     public void setTimeStamp(long ts) {
209         mTimeStamp = ts;
210     }
211 
212     /**
213      * @return a {@link CellIdentity} instance.
214      */
215     @NonNull
getCellIdentity()216     public abstract CellIdentity getCellIdentity();
217 
218     /**
219      * @return a {@link CellSignalStrength} instance.
220      */
221     @NonNull
getCellSignalStrength()222     public abstract CellSignalStrength getCellSignalStrength();
223 
224     /** @hide */
sanitizeLocationInfo()225     public CellInfo sanitizeLocationInfo() {
226         return null;
227     }
228 
229     /**
230      * Gets the connection status of this cell.
231      *
232      * @see #CONNECTION_NONE
233      * @see #CONNECTION_PRIMARY_SERVING
234      * @see #CONNECTION_SECONDARY_SERVING
235      * @see #CONNECTION_UNKNOWN
236      *
237      * @return The connection status of the cell.
238      */
239     @CellConnectionStatus
getCellConnectionStatus()240     public int getCellConnectionStatus() {
241         return mCellConnectionStatus;
242     }
243     /** @hide */
setCellConnectionStatus(@ellConnectionStatus int cellConnectionStatus)244     public void setCellConnectionStatus(@CellConnectionStatus int cellConnectionStatus) {
245         mCellConnectionStatus = cellConnectionStatus;
246     }
247 
248     @Override
hashCode()249     public int hashCode() {
250         return Objects.hash(mCellConnectionStatus, mRegistered, mTimeStamp);
251     }
252 
253     @Override
equals(Object o)254     public boolean equals(Object o) {
255         if (this == o) return true;
256         if (!(o instanceof CellInfo)) return false;
257         CellInfo cellInfo = (CellInfo) o;
258         return mCellConnectionStatus == cellInfo.mCellConnectionStatus
259                 && mRegistered == cellInfo.mRegistered
260                 && mTimeStamp == cellInfo.mTimeStamp;
261     }
262 
263     @Override
toString()264     public String toString() {
265         StringBuffer sb = new StringBuffer();
266 
267         sb.append("mRegistered=").append(mRegistered ? "YES" : "NO");
268         sb.append(" mTimeStamp=").append(mTimeStamp).append("ns");
269         sb.append(" mCellConnectionStatus=").append(mCellConnectionStatus);
270 
271         return sb.toString();
272     }
273 
274     /**
275      * Implement the Parcelable interface
276      */
277     @Override
describeContents()278     public int describeContents() {
279         return 0;
280     }
281 
282     /** Implement the Parcelable interface */
283     @Override
writeToParcel(Parcel dest, int flags)284     public abstract void writeToParcel(Parcel dest, int flags);
285 
286     /**
287      * Used by child classes for parceling.
288      *
289      * @hide
290      */
writeToParcel(Parcel dest, int flags, int type)291     protected void writeToParcel(Parcel dest, int flags, int type) {
292         dest.writeInt(type);
293         dest.writeInt(mRegistered ? 1 : 0);
294         dest.writeLong(mTimeStamp);
295         dest.writeInt(mCellConnectionStatus);
296     }
297 
298     /**
299      * Used by child classes for parceling
300      *
301      * @hide
302      */
CellInfo(Parcel in)303     protected CellInfo(Parcel in) {
304         mRegistered = (in.readInt() == 1) ? true : false;
305         mTimeStamp = in.readLong();
306         mCellConnectionStatus = in.readInt();
307     }
308 
309     /** Implement the Parcelable interface */
310     public static final @android.annotation.NonNull Creator<CellInfo> CREATOR = new Creator<CellInfo>() {
311         @Override
312         public CellInfo createFromParcel(Parcel in) {
313                 int type = in.readInt();
314                 switch (type) {
315                     case TYPE_GSM: return CellInfoGsm.createFromParcelBody(in);
316                     case TYPE_CDMA: return CellInfoCdma.createFromParcelBody(in);
317                     case TYPE_LTE: return CellInfoLte.createFromParcelBody(in);
318                     case TYPE_WCDMA: return CellInfoWcdma.createFromParcelBody(in);
319                     case TYPE_TDSCDMA: return CellInfoTdscdma.createFromParcelBody(in);
320                     case TYPE_NR: return CellInfoNr.createFromParcelBody(in);
321                     default: throw new RuntimeException("Bad CellInfo Parcel");
322                 }
323         }
324 
325         @Override
326         public CellInfo[] newArray(int size) {
327             return new CellInfo[size];
328         }
329     };
330 }
331