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