1 /*
2  * Copyright (C) 2006 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 static android.telephony.TelephonyManager.NETWORK_TYPE_EDGE;
20 import static android.telephony.TelephonyManager.NETWORK_TYPE_GPRS;
21 import static android.telephony.TelephonyManager.NETWORK_TYPE_HSDPA;
22 import static android.telephony.TelephonyManager.NETWORK_TYPE_HSPA;
23 import static android.telephony.TelephonyManager.NETWORK_TYPE_HSUPA;
24 import static android.telephony.TelephonyManager.NETWORK_TYPE_UMTS;
25 import static android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN;
26 
27 import android.compat.annotation.UnsupportedAppUsage;
28 import android.os.Build;
29 import android.os.Parcel;
30 import android.os.Parcelable;
31 
32 
33 /**
34  * Represents the neighboring cell information, including
35  * Received Signal Strength and Cell ID location.
36  *
37  * @deprecated This class should not be used by any app targeting
38  *     {@link android.os.Build.VERSION_CODES#Q Android Q} or higher. Instead callers should use
39  *     {@link android.telephony.CellInfo CellInfo}.
40  */
41 @Deprecated
42 public class NeighboringCellInfo implements Parcelable
43 {
44     /**
45      * Signal strength is not available
46      */
47     static final public int UNKNOWN_RSSI = 99;
48     /**
49      * Cell location is not available
50      */
51     static final public int UNKNOWN_CID = -1;
52 
53     /**
54      * In GSM, mRssi is the Received RSSI;
55      * In UMTS, mRssi is the Level index of CPICH Received Signal Code Power
56      */
57     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
58     private int mRssi;
59     /**
60      * CID in 16 bits format in GSM. Return UNKNOWN_CID in UMTS and CMDA.
61      */
62     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
63     private int mCid;
64     /**
65      * LAC in 16 bits format in GSM. Return UNKNOWN_CID in UMTS and CMDA.
66      */
67     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
68     private int mLac;
69     /**
70      * Primary Scrambling Code in 9 bits format in UMTS
71      * Return UNKNOWN_CID in GSM and CMDA.
72      */
73     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
74     private int mPsc;
75     /**
76      * Radio network type, value is one of following
77      * TelephonyManager.NETWORK_TYPE_XXXXXX.
78      */
79     @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
80     private int mNetworkType;
81 
82     /**
83      * Empty constructor.  Initializes the RSSI and CID.
84      *
85      * NeighboringCellInfo is one time shot for the neighboring cells based on
86      * the radio network type at that moment. Its constructor needs radio network
87      * type.
88      *
89      * @deprecated by {@link #NeighboringCellInfo(int, String, int)}
90      */
91     @Deprecated
NeighboringCellInfo()92     public NeighboringCellInfo() {
93         mRssi = UNKNOWN_RSSI;
94         mLac = UNKNOWN_CID;
95         mCid = UNKNOWN_CID;
96         mPsc = UNKNOWN_CID;
97         mNetworkType = NETWORK_TYPE_UNKNOWN;
98     }
99 
100     /**
101      * Initialize the object from rssi and cid.
102      *
103      * NeighboringCellInfo is one time shot for the neighboring cells based on
104      * the radio network type at that moment. Its constructor needs radio network
105      * type.
106      *
107      * @deprecated by {@link #NeighboringCellInfo(int, String, int)}
108      */
109     @Deprecated
NeighboringCellInfo(int rssi, int cid)110     public NeighboringCellInfo(int rssi, int cid) {
111         mRssi = rssi;
112         mCid = cid;
113     }
114 
115     /** @hide */
NeighboringCellInfo(final CellInfoGsm info)116     public NeighboringCellInfo(final CellInfoGsm info) {
117         mNetworkType = TelephonyManager.NETWORK_TYPE_GPRS;
118 
119         mRssi = info.getCellSignalStrength().getAsuLevel();
120         if (mRssi == Integer.MAX_VALUE) mRssi = UNKNOWN_RSSI;
121 
122         mLac = info.getCellIdentity().getLac();
123         if (mLac == Integer.MAX_VALUE) mLac = UNKNOWN_CID;
124 
125         mCid = info.getCellIdentity().getCid();
126         if (mCid == Integer.MAX_VALUE) mCid = UNKNOWN_CID;
127 
128         mPsc = UNKNOWN_CID;
129     }
130 
131     /** @hide */
NeighboringCellInfo(final CellInfoWcdma info)132     public NeighboringCellInfo(final CellInfoWcdma info) {
133         mNetworkType = TelephonyManager.NETWORK_TYPE_UMTS;
134 
135         mRssi = info.getCellSignalStrength().getAsuLevel();
136         if (mRssi == Integer.MAX_VALUE) mRssi = UNKNOWN_RSSI;
137 
138         mLac = info.getCellIdentity().getLac();
139         if (mLac == Integer.MAX_VALUE) mLac = UNKNOWN_CID;
140 
141         mCid = info.getCellIdentity().getCid();
142         if (mCid == Integer.MAX_VALUE) mCid = UNKNOWN_CID;
143 
144         mPsc = info.getCellIdentity().getPsc();
145         if (mPsc == Integer.MAX_VALUE) mPsc = UNKNOWN_CID;
146     }
147 
148     /**
149      * Initialize the object from rssi, location string, and radioType
150      * radioType is one of following
151      * {@link TelephonyManager#NETWORK_TYPE_GPRS TelephonyManager.NETWORK_TYPE_GPRS},
152      * {@link TelephonyManager#NETWORK_TYPE_EDGE TelephonyManager.NETWORK_TYPE_EDGE},
153      * {@link TelephonyManager#NETWORK_TYPE_UMTS TelephonyManager.NETWORK_TYPE_UMTS},
154      * {@link TelephonyManager#NETWORK_TYPE_HSDPA TelephonyManager.NETWORK_TYPE_HSDPA},
155      * {@link TelephonyManager#NETWORK_TYPE_HSUPA TelephonyManager.NETWORK_TYPE_HSUPA},
156      * and {@link TelephonyManager#NETWORK_TYPE_HSPA TelephonyManager.NETWORK_TYPE_HSPA}.
157      */
NeighboringCellInfo(int rssi, String location, int radioType)158     public NeighboringCellInfo(int rssi, String location, int radioType) {
159         // set default value
160         mRssi = rssi;
161         mNetworkType = NETWORK_TYPE_UNKNOWN;
162         mPsc = UNKNOWN_CID;
163         mLac = UNKNOWN_CID;
164         mCid = UNKNOWN_CID;
165 
166 
167         // pad location string with leading "0"
168         int l = location.length();
169         if (l > 8) return;
170         if (l < 8) {
171             for (int i = 0; i < (8-l); i++) {
172                 location = "0" + location;
173             }
174         }
175         // TODO - handle LTE and eHRPD (or find they can't be supported)
176         try {// set LAC/CID or PSC based on radioType
177             switch (radioType) {
178             case NETWORK_TYPE_GPRS:
179             case NETWORK_TYPE_EDGE:
180                 mNetworkType = radioType;
181                 // check if 0xFFFFFFFF for UNKNOWN_CID
182                 if (!location.equalsIgnoreCase("FFFFFFFF")) {
183                     mCid = Integer.parseInt(location.substring(4), 16);
184                     mLac = Integer.parseInt(location.substring(0, 4), 16);
185                 }
186                 break;
187             case NETWORK_TYPE_UMTS:
188             case NETWORK_TYPE_HSDPA:
189             case NETWORK_TYPE_HSUPA:
190             case NETWORK_TYPE_HSPA:
191                 mNetworkType = radioType;
192                 mPsc = Integer.parseInt(location, 16);
193                 break;
194             }
195         } catch (NumberFormatException e) {
196             // parsing location error
197             mPsc = UNKNOWN_CID;
198             mLac = UNKNOWN_CID;
199             mCid = UNKNOWN_CID;
200             mNetworkType = NETWORK_TYPE_UNKNOWN;
201         }
202     }
203 
204     /**
205      * Initialize the object from a parcel.
206      */
NeighboringCellInfo(Parcel in)207     public NeighboringCellInfo(Parcel in) {
208         mRssi = in.readInt();
209         mLac = in.readInt();
210         mCid = in.readInt();
211         mPsc = in.readInt();
212         mNetworkType = in.readInt();
213     }
214 
215     /**
216      * @return received signal strength or UNKNOWN_RSSI if unknown
217      *
218      * For GSM, it is in "asu" ranging from 0 to 31 (dBm = -113 + 2*asu)
219      * 0 means "-113 dBm or less" and 31 means "-51 dBm or greater"
220      * For UMTS, it is the Level index of CPICH RSCP defined in TS 25.125
221      */
getRssi()222     public int getRssi() {
223         return mRssi;
224     }
225 
226     /**
227      * @return LAC in GSM, 0xffff max legal value
228      *  UNKNOWN_CID if in UMTS or CMDA or unknown
229      */
getLac()230     public int getLac() {
231         return mLac;
232     }
233 
234     /**
235      * @return cell id in GSM, 0xffff max legal value
236      *  UNKNOWN_CID if in UMTS or CDMA or unknown
237      */
getCid()238     public int getCid() {
239         return mCid;
240     }
241 
242     /**
243      * @return Primary Scrambling Code in 9 bits format in UMTS, 0x1ff max value
244      *  UNKNOWN_CID if in GSM or CMDA or unknown
245      */
getPsc()246     public int getPsc() {
247         return mPsc;
248     }
249 
250     /**
251      * @return Radio network type while neighboring cell location is stored.
252      *
253      * Return {@link TelephonyManager#NETWORK_TYPE_UNKNOWN TelephonyManager.NETWORK_TYPE_UNKNOWN}
254      * means that the location information is unavailable.
255      *
256      * Return {@link TelephonyManager#NETWORK_TYPE_GPRS TelephonyManager.NETWORK_TYPE_GPRS} or
257      * {@link TelephonyManager#NETWORK_TYPE_EDGE TelephonyManager.NETWORK_TYPE_EDGE}
258      * means that Neighboring Cell information is stored for GSM network, in
259      * which {@link NeighboringCellInfo#getLac NeighboringCellInfo.getLac} and
260      * {@link NeighboringCellInfo#getCid NeighboringCellInfo.getCid} should be
261      * called to access location.
262      *
263      * Return {@link TelephonyManager#NETWORK_TYPE_UMTS TelephonyManager.NETWORK_TYPE_UMTS},
264      * {@link TelephonyManager#NETWORK_TYPE_HSDPA TelephonyManager.NETWORK_TYPE_HSDPA},
265      * {@link TelephonyManager#NETWORK_TYPE_HSUPA TelephonyManager.NETWORK_TYPE_HSUPA},
266      * or {@link TelephonyManager#NETWORK_TYPE_HSPA TelephonyManager.NETWORK_TYPE_HSPA}
267      * means that Neighboring Cell information is stored for UMTS network, in
268      * which {@link NeighboringCellInfo#getPsc NeighboringCellInfo.getPsc}
269      * should be called to access location.
270      */
getNetworkType()271     public int getNetworkType() {
272         return mNetworkType;
273     }
274     /**
275      * Set the cell id.
276      *
277      * NeighboringCellInfo is a one time shot for the neighboring cells based on
278      * the radio network type at that moment. It shouldn't be changed after
279      * creation.
280      *
281      * @deprecated cid value passed as in location parameter passed to constructor
282      *              {@link #NeighboringCellInfo(int, String, int)}
283      */
284     @Deprecated
setCid(int cid)285     public void setCid(int cid) {
286         mCid = cid;
287     }
288 
289     /**
290      * Set the signal strength of the cell.
291      *
292      * NeighboringCellInfo is a one time shot for the neighboring cells based on
293      * the radio network type at that moment. It shouldn't be changed after
294      * creation.
295      *
296      * @deprecated initial rssi value passed as parameter to constructor
297      *              {@link #NeighboringCellInfo(int, String, int)}
298      */
299     @Deprecated
setRssi(int rssi)300     public void setRssi(int rssi) {
301         mRssi = rssi;
302     }
303 
304     @Override
toString()305     public String toString() {
306         StringBuilder sb = new StringBuilder();
307 
308         sb.append("[");
309         if (mPsc != UNKNOWN_CID) {
310             sb.append(Integer.toHexString(mPsc))
311                     .append("@").append(((mRssi == UNKNOWN_RSSI)? "-" : mRssi));
312         } else if(mLac != UNKNOWN_CID && mCid != UNKNOWN_CID) {
313             sb.append(Integer.toHexString(mLac))
314                     .append(Integer.toHexString(mCid))
315                     .append("@").append(((mRssi == UNKNOWN_RSSI)? "-" : mRssi));
316         }
317         sb.append("]");
318 
319         return sb.toString();
320     }
321 
describeContents()322     public int describeContents() {
323         return 0;
324     }
325 
writeToParcel(Parcel dest, int flags)326     public void writeToParcel(Parcel dest, int flags) {
327         dest.writeInt(mRssi);
328         dest.writeInt(mLac);
329         dest.writeInt(mCid);
330         dest.writeInt(mPsc);
331         dest.writeInt(mNetworkType);
332     }
333 
334     public static final @android.annotation.NonNull Parcelable.Creator<NeighboringCellInfo> CREATOR
335     = new Parcelable.Creator<NeighboringCellInfo>() {
336         public NeighboringCellInfo createFromParcel(Parcel in) {
337             return new NeighboringCellInfo(in);
338         }
339 
340         public NeighboringCellInfo[] newArray(int size) {
341             return new NeighboringCellInfo[size];
342         }
343     };
344 }
345