• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2014 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 package android.telephony.cts;
17 
18 import static androidx.test.InstrumentationRegistry.getContext;
19 
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotNull;
23 import static org.junit.Assert.assertNull;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26 
27 import android.Manifest;
28 import android.Manifest.permission;
29 import android.app.UiAutomation;
30 import android.content.Context;
31 import android.content.pm.PackageManager;
32 import android.os.Parcel;
33 import android.os.SystemClock;
34 import android.telephony.CellIdentity;
35 import android.telephony.CellIdentityCdma;
36 import android.telephony.CellIdentityGsm;
37 import android.telephony.CellIdentityLte;
38 import android.telephony.CellIdentityNr;
39 import android.telephony.CellIdentityTdscdma;
40 import android.telephony.CellIdentityWcdma;
41 import android.telephony.CellInfo;
42 import android.telephony.CellInfoCdma;
43 import android.telephony.CellInfoGsm;
44 import android.telephony.CellInfoLte;
45 import android.telephony.CellInfoNr;
46 import android.telephony.CellInfoTdscdma;
47 import android.telephony.CellInfoWcdma;
48 import android.telephony.CellSignalStrengthCdma;
49 import android.telephony.CellSignalStrengthGsm;
50 import android.telephony.CellSignalStrengthLte;
51 import android.telephony.CellSignalStrengthNr;
52 import android.telephony.CellSignalStrengthTdscdma;
53 import android.telephony.CellSignalStrengthWcdma;
54 import android.telephony.PhoneStateListener;
55 import android.telephony.ServiceState;
56 import android.telephony.TelephonyManager;
57 import android.util.Log;
58 import android.util.Pair;
59 
60 import androidx.test.InstrumentationRegistry;
61 
62 import org.junit.Before;
63 import org.junit.Test;
64 
65 import java.util.List;
66 import java.util.concurrent.Executor;
67 
68 /**
69  * Test TelephonyManager.getAllCellInfo()
70  * <p>
71  * TODO(chesnutt): test onCellInfoChanged() once the implementation
72  * of async callbacks is complete (see http://b/13788638)
73  */
74 public class CellInfoTest {
75     private static final String TAG = "android.telephony.cts.CellInfoTest";
76 
77     // Maximum and minimum possible RSSI values(in dbm).
78     private static final int MAX_RSSI = -10;
79     private static final int MIN_RSSI = -150;
80     // Maximum and minimum possible RSSP values(in dbm).
81     private static final int MAX_RSRP = -44;
82     private static final int MIN_RSRP = -140;
83     // Maximum and minimum possible RSSQ values.
84     private static final int MAX_RSRQ = -3;
85     private static final int MIN_RSRQ = -35;
86     // Maximum and minimum possible RSSNR values.
87     private static final int MAX_RSSNR = 50;
88     private static final int MIN_RSSNR = 0;
89     // Maximum and minimum possible CQI values.
90     private static final int MAX_CQI = 30;
91     private static final int MIN_CQI = 0;
92 
93     /**
94      * Maximum and minimum valid LTE RSSI values in dBm
95      *
96      * The valid RSSI ASU range from current HAL is [0,31].
97      * Convert RSSI ASU to dBm: dBm = -113 + 2 * ASU, which is [-113, -51]
98      *
99      * Reference: TS 27.007 8.5 - Signal quality +CSQ
100      */
101     private static final int MAX_LTE_RSSI = -51;
102     private static final int MIN_LTE_RSSI = -113;
103 
104     // The followings are parameters for testing CellIdentityCdma
105     // Network Id ranges from 0 to 65535.
106     private static final int NETWORK_ID  = 65535;
107     // CDMA System Id ranges from 0 to 32767
108     private static final int SYSTEM_ID = 32767;
109     // Base Station Id ranges from 0 to 65535
110     private static final int BASESTATION_ID = 65535;
111     // Longitude ranges from -2592000 to 2592000.
112     private static final int LONGITUDE = 2592000;
113     // Latitude ranges from -1296000 to 1296000.
114     private static final int LATITUDE = 1296000;
115     // Cell identity ranges from 0 to 268435456.
116 
117     // The followings are parameters for testing CellIdentityLte
118     private static final int CI = 268435456;
119     // Physical cell id ranges from 0 to 503.
120     private static final int PCI = 503;
121     // Tracking area code ranges from 0 to 65535.
122     private static final int TAC = 65535;
123     // Absolute RF Channel Number ranges from 0 to 262143.
124     private static final int EARFCN_MAX = 262143;
125     private static final int BANDWIDTH_LOW = 1400;  // kHz
126     private static final int BANDWIDTH_HIGH = 20000;  // kHz
127 
128     // The followings are parameters for testing CellIdentityWcdma
129     // Location Area Code ranges from 0 to 65535.
130     private static final int LAC = 65535;
131     // UMTS Cell Identity ranges from 0 to 268435455.
132     private static final int CID_UMTS = 268435455;
133     // Primary Scrambling Code ranges from 0 to 511.
134     private static final int PSC = 511;
135     // Cell Parameters Index rangest from 0-127.
136     private static final int CPID = 127;
137 
138     // The followings are parameters for testing CellIdentityGsm
139     // GSM Cell Identity ranges from 0 to 65535.
140     private static final int CID_GSM = 65535;
141     // GSM Absolute RF Channel Number ranges from 0 to 65535.
142     private static final int ARFCN = 1024;
143 
144     // 3gpp 36.101 Sec 5.7.2
145     private static final int CHANNEL_RASTER_EUTRAN = 100; //kHz
146 
147     private static final int MAX_CELLINFO_WAIT_MILLIS = 5000;
148     private static final int MAX_LISTENER_WAIT_MILLIS = 1000; // usually much less
149     // The maximum interval between CellInfo updates from the modem. In the AOSP code it varies
150     // between 2 and 10 seconds, and there is an allowable modem delay of 3 seconds, so if we
151     // cannot get a seconds CellInfo update within 15 seconds, then something is broken.
152     // See DeviceStateMonitor#CELL_INFO_INTERVAL_*
153     private static final int MAX_CELLINFO_INTERVAL_MILLIS = 15000; // in AOSP the max is 10s
154     private static final int RADIO_HAL_VERSION_1_2 = makeRadioVersion(1, 2);
155 
156     private PackageManager mPm;
157     private TelephonyManager mTm;
158 
159     private int mRadioHalVersion;
160 
makeRadioVersion(int major, int minor)161     private static final int makeRadioVersion(int major, int minor) {
162         if (major < 0 || minor < 0) return 0;
163         return major * 100 + minor;
164     }
165 
166     private Executor mSimpleExecutor = new Executor() {
167         @Override
168         public void execute(Runnable r) {
169             r.run();
170         }
171     };
172 
173     private static class CellInfoResultsCallback extends TelephonyManager.CellInfoCallback {
174         List<CellInfo> cellInfo;
175 
176         @Override
onCellInfo(List<CellInfo> cellInfo)177         public synchronized void onCellInfo(List<CellInfo> cellInfo) {
178             this.cellInfo = cellInfo;
179             notifyAll();
180         }
181 
wait(int millis)182         public synchronized void wait(int millis) throws InterruptedException {
183             if (cellInfo == null) {
184                 super.wait(millis);
185             }
186         }
187     }
188 
189     private static class CellInfoListener extends PhoneStateListener {
190         List<CellInfo> cellInfo;
191 
CellInfoListener(Executor e)192         public CellInfoListener(Executor e) {
193             super(e);
194         }
195 
196         @Override
onCellInfoChanged(List<CellInfo> cellInfo)197         public synchronized void onCellInfoChanged(List<CellInfo> cellInfo) {
198             this.cellInfo = cellInfo;
199             notifyAll();
200         }
201 
wait(int millis)202         public synchronized void wait(int millis) throws InterruptedException {
203             if (cellInfo == null) {
204                 super.wait(millis);
205             }
206         }
207     }
208 
isCamped()209     private boolean isCamped() {
210         ServiceState ss = mTm.getServiceState();
211         if (ss == null) return false;
212         return (ss.getState() == ServiceState.STATE_IN_SERVICE
213                 || ss.getState() == ServiceState.STATE_EMERGENCY_ONLY);
214     }
215 
216     @Before
setUp()217     public void setUp() throws Exception {
218         mTm = (TelephonyManager) getContext().getSystemService(Context.TELEPHONY_SERVICE);
219         mPm = getContext().getPackageManager();
220         Pair<Integer, Integer> verPair = mTm.getRadioHalVersion();
221         mRadioHalVersion = makeRadioVersion(verPair.first, verPair.second);
222         TelephonyManagerTest.grantLocationPermissions();
223     }
224 
225     /**
226      * Test to ensure that the PhoneStateListener receives callbacks every time that new CellInfo
227      * is received and not otherwise.
228      */
229     @Test
testPhoneStateListenerCallback()230     public void testPhoneStateListenerCallback() throws Throwable {
231         if (!mPm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) return;
232 
233         CellInfoResultsCallback resultsCallback = new CellInfoResultsCallback();
234         // Prime the system by requesting a CellInfoUpdate
235         mTm.requestCellInfoUpdate(mSimpleExecutor, resultsCallback);
236         resultsCallback.wait(MAX_CELLINFO_WAIT_MILLIS);
237         // Register a new PhoneStateListener for CellInfo
238         CellInfoListener listener = new CellInfoListener(mSimpleExecutor);
239         mTm.listen(listener, PhoneStateListener.LISTEN_CELL_INFO);
240         // Expect a callback immediately upon registration
241         listener.wait(MAX_LISTENER_WAIT_MILLIS);
242         assertNotNull("CellInfo Listener Never Fired on Registration", listener.cellInfo);
243         // Save the initial listener result as a baseline
244         List<CellInfo> referenceList = listener.cellInfo;
245         assertFalse("CellInfo does not contain valid results", referenceList.isEmpty());
246         assertTrue("Listener Didn't Receive the Right Data",
247                 referenceList.containsAll(resultsCallback.cellInfo));
248         listener.cellInfo = null;
249         resultsCallback.cellInfo = null;
250         long timeoutTime = SystemClock.elapsedRealtime() + MAX_CELLINFO_INTERVAL_MILLIS;
251         while (timeoutTime > SystemClock.elapsedRealtime()) {
252             // Request a CellInfo update to try and coax an update from the listener
253             mTm.requestCellInfoUpdate(mSimpleExecutor, resultsCallback);
254             resultsCallback.wait(MAX_CELLINFO_WAIT_MILLIS);
255             assertNotNull("CellInfoCallback should return valid data", resultsCallback.cellInfo);
256             if (referenceList.containsAll(resultsCallback.cellInfo)) {
257                 // Check the a call to getAllCellInfo doesn't trigger the listener.
258                 mTm.getAllCellInfo();
259                 // Wait for the listener to fire; it shouldn't.
260                 listener.wait(MAX_LISTENER_WAIT_MILLIS);
261                 // Check to ensure the listener didn't fire for stale data.
262                 assertNull("PhoneStateListener Fired For Old CellInfo Data", listener.cellInfo);
263             } else {
264                 // If there is new CellInfo data, then the listener should fire
265                 listener.wait(MAX_LISTENER_WAIT_MILLIS);
266                 assertNotNull("Listener did not receive updated CellInfo Data",
267                         listener.cellInfo);
268                 assertFalse("CellInfo data should be different from the old listener data."
269                         + referenceList + " : " + listener.cellInfo,
270                         referenceList.containsAll(listener.cellInfo));
271                 return; // pass the test
272             }
273             // Reset the resultsCallback for the next iteration
274             resultsCallback.cellInfo = null;
275         }
276     }
277 
278     @Test
testCellInfo()279     public void testCellInfo() throws Throwable {
280         if(!(mPm.hasSystemFeature(PackageManager.FEATURE_TELEPHONY))) {
281             Log.d(TAG, "Skipping test that requires FEATURE_TELEPHONY");
282             return;
283         }
284 
285         if (!isCamped()) fail("Device is not camped to a cell");
286 
287         // Make a blocking call to requestCellInfoUpdate for results (for simplicity of test).
288         CellInfoResultsCallback resultsCallback = new CellInfoResultsCallback();
289         mTm.requestCellInfoUpdate(mSimpleExecutor, resultsCallback);
290         resultsCallback.wait(MAX_CELLINFO_WAIT_MILLIS);
291         List<CellInfo> allCellInfo = resultsCallback.cellInfo;
292 
293         assertNotNull("TelephonyManager.getAllCellInfo() returned NULL!", allCellInfo);
294         assertTrue("TelephonyManager.getAllCellInfo() returned zero-length list!",
295             allCellInfo.size() > 0);
296 
297         int numRegisteredCells = 0;
298         for (CellInfo cellInfo : allCellInfo) {
299             if (cellInfo.isRegistered()) {
300                 ++numRegisteredCells;
301             }
302             verifyBaseCellInfo(cellInfo);
303             verifyBaseCellIdentity(cellInfo.getCellIdentity(), cellInfo.isRegistered());
304             if (cellInfo instanceof CellInfoLte) {
305                 verifyLteInfo((CellInfoLte) cellInfo);
306             } else if (cellInfo instanceof CellInfoWcdma) {
307                 verifyWcdmaInfo((CellInfoWcdma) cellInfo);
308             } else if (cellInfo instanceof CellInfoGsm) {
309                 verifyGsmInfo((CellInfoGsm) cellInfo);
310             } else if (cellInfo instanceof CellInfoCdma) {
311                 verifyCdmaInfo((CellInfoCdma) cellInfo);
312             } else if (cellInfo instanceof CellInfoTdscdma) {
313                 verifyTdscdmaInfo((CellInfoTdscdma) cellInfo);
314             } else if (cellInfo instanceof CellInfoNr) {
315                 verifyNrInfo((CellInfoNr) cellInfo);
316             } else {
317                 fail("Unknown CellInfo Type reported.");
318             }
319         }
320 
321         //FIXME: The maximum needs to be calculated based on the number of
322         //       radios and the technologies used (ex SRLTE); however, we have
323         //       not hit any of these cases yet.
324         assertTrue("None or too many registered cells : " + numRegisteredCells,
325                 numRegisteredCells > 0 && numRegisteredCells <= 2);
326     }
327 
verifyBaseCellInfo(CellInfo info)328     private void verifyBaseCellInfo(CellInfo info) {
329         assertTrue("Invalid timestamp in CellInfo: " + info.getTimeStamp(),
330                 info.getTimeStamp() > 0 && info.getTimeStamp() < Long.MAX_VALUE);
331 
332         if (mRadioHalVersion >= RADIO_HAL_VERSION_1_2) {
333             // In HAL 1.2 or greater, the connection status must be reported
334             assertTrue(info.getCellConnectionStatus() != CellInfo.CONNECTION_UNKNOWN);
335         }
336     }
337 
verifyBaseCellIdentity(CellIdentity id, boolean isRegistered)338     private void verifyBaseCellIdentity(CellIdentity id, boolean isRegistered) {
339         if (mRadioHalVersion >= RADIO_HAL_VERSION_1_2) {
340             if (isRegistered) {
341                 String alphaLong = (String) id.getOperatorAlphaLong();
342                 assertNotNull("getOperatorAlphaLong() returns NULL!", alphaLong);
343 
344                 String alphaShort = (String) id.getOperatorAlphaShort();
345                 assertNotNull("getOperatorAlphaShort() returns NULL!", alphaShort);
346             }
347         }
348     }
349 
verifyCdmaInfo(CellInfoCdma cdma)350     private void verifyCdmaInfo(CellInfoCdma cdma) {
351         verifyCellConnectionStatus(cdma.getCellConnectionStatus());
352         verifyCellInfoCdmaParcelandHashcode(cdma);
353         verifyCellIdentityCdma(cdma.getCellIdentity(), cdma.isRegistered());
354         verifyCellIdentityCdmaParcel(cdma.getCellIdentity());
355         verifyCellSignalStrengthCdma(cdma.getCellSignalStrength());
356         verifyCellSignalStrengthCdmaParcel(cdma.getCellSignalStrength());
357     }
358 
verifyCellInfoCdmaParcelandHashcode(CellInfoCdma cdma)359     private void verifyCellInfoCdmaParcelandHashcode(CellInfoCdma cdma) {
360         Parcel p = Parcel.obtain();
361         cdma.writeToParcel(p, 0);
362         p.setDataPosition(0);
363 
364         CellInfoCdma newCi = CellInfoCdma.CREATOR.createFromParcel(p);
365         assertTrue(cdma.equals(newCi));
366         assertEquals("hashCode() did not get right hashCode", cdma.hashCode(), newCi.hashCode());
367     }
368 
verifyCellIdentityCdma(CellIdentityCdma cdma, boolean isRegistered)369     private void verifyCellIdentityCdma(CellIdentityCdma cdma, boolean isRegistered) {
370         int networkId = cdma.getNetworkId();
371         assertTrue("getNetworkId() out of range [0,65535], networkId=" + networkId,
372                 networkId == Integer.MAX_VALUE || (networkId >= 0 && networkId <= NETWORK_ID));
373 
374         int systemId = cdma.getSystemId();
375         assertTrue("getSystemId() out of range [0,32767], systemId=" + systemId,
376                 systemId == Integer.MAX_VALUE || (systemId >= 0 && systemId <= SYSTEM_ID));
377 
378         int basestationId = cdma.getBasestationId();
379         assertTrue("getBasestationId() out of range [0,65535], basestationId=" + basestationId,
380                 basestationId == Integer.MAX_VALUE
381                         || (basestationId >= 0 && basestationId <= BASESTATION_ID));
382 
383         int longitude = cdma.getLongitude();
384         assertTrue("getLongitude() out of range [-2592000,2592000], longitude=" + longitude,
385                 longitude == Integer.MAX_VALUE
386                         || (longitude >= -LONGITUDE && longitude <= LONGITUDE));
387 
388         int latitude = cdma.getLatitude();
389         assertTrue("getLatitude() out of range [-1296000,1296000], latitude=" + latitude,
390                 latitude == Integer.MAX_VALUE || (latitude >= -LATITUDE && latitude <= LATITUDE));
391 
392         if (isRegistered) {
393             assertTrue("SID is required for registered cells", systemId != Integer.MAX_VALUE);
394             assertTrue("NID is required for registered cells", networkId != Integer.MAX_VALUE);
395             assertTrue("BSID is required for registered cells", basestationId != Integer.MAX_VALUE);
396         }
397     }
398 
verifyCellIdentityCdmaParcel(CellIdentityCdma cdma)399     private void verifyCellIdentityCdmaParcel(CellIdentityCdma cdma) {
400         Parcel p = Parcel.obtain();
401         cdma.writeToParcel(p, 0);
402         p.setDataPosition(0);
403 
404         CellIdentityCdma newCi = CellIdentityCdma.CREATOR.createFromParcel(p);
405         assertTrue(cdma.equals(newCi));
406     }
407 
verifyCellSignalStrengthCdma(CellSignalStrengthCdma cdma)408     private void verifyCellSignalStrengthCdma(CellSignalStrengthCdma cdma) {
409         int level = cdma.getLevel();
410         assertTrue("getLevel() out of range [0,4], level=" + level,
411                 level >= 0 && level <= 4);
412 
413         int asuLevel = cdma.getAsuLevel();
414         assertTrue("getAsuLevel() out of range [0,97] (or 99 is unknown), asuLevel=" + asuLevel,
415                 asuLevel == 99 || (asuLevel >= 0 && asuLevel <= 97));
416 
417         int cdmaLevel = cdma.getCdmaLevel();
418         assertTrue("getCdmaLevel() out of range [0,4], cdmaLevel=" + cdmaLevel,
419                 cdmaLevel >= 0 && cdmaLevel <= 4);
420 
421         int evdoLevel = cdma.getEvdoLevel();
422         assertTrue("getEvdoLevel() out of range [0,4], evdoLevel=" + evdoLevel,
423                 evdoLevel >= 0 && evdoLevel <= 4);
424 
425         // The following four fields do not have specific limits. So just calling to verify that
426         // they don't crash the phone.
427         int cdmaDbm = cdma.getCdmaDbm();
428         int evdoDbm = cdma.getEvdoDbm();
429         cdma.getCdmaEcio();
430         cdma.getEvdoEcio();
431 
432         int dbm = (cdmaDbm < evdoDbm) ? cdmaDbm : evdoDbm;
433         assertEquals("getDbm() did not get correct value", dbm, cdma.getDbm());
434 
435         int evdoSnr = cdma.getEvdoSnr();
436         assertTrue("getEvdoSnr() out of range [0,8], evdoSnr=" + evdoSnr,
437                 (evdoSnr == Integer.MAX_VALUE) || (evdoSnr >= 0 && evdoSnr <= 8));
438     }
439 
verifyCellSignalStrengthCdmaParcel(CellSignalStrengthCdma cdma)440     private void verifyCellSignalStrengthCdmaParcel(CellSignalStrengthCdma cdma) {
441         Parcel p = Parcel.obtain();
442         cdma.writeToParcel(p, 0);
443         p.setDataPosition(0);
444 
445         CellSignalStrengthCdma newCss = CellSignalStrengthCdma.CREATOR.createFromParcel(p);
446         assertEquals(cdma, newCss);
447     }
448 
verifyPlmnInfo(String mccStr, String mncStr, int mcc, int mnc)449     private static void verifyPlmnInfo(String mccStr, String mncStr, int mcc, int mnc) {
450         // If either int value is invalid, all values must be invalid
451         if (mcc == Integer.MAX_VALUE) {
452             assertTrue("MNC and MNC must always be reported together.",
453                     mnc == Integer.MAX_VALUE && mccStr == null && mncStr == null);
454             return;
455         }
456 
457         assertTrue("getMcc() out of range [0, 999], mcc=" + mcc, (mcc >= 0 && mcc <= 999));
458         assertTrue("getMnc() out of range [0, 999], mnc=" + mnc, (mnc >= 0 && mnc <= 999));
459         assertTrue("MCC and MNC Strings must always be reported together.",
460                 (mccStr == null) == (mncStr == null));
461 
462         // For legacy compatibility, it's possible to have int values without valid string values
463         // but not the other way around.
464         // mccStr is set as NULL if empty, unknown or invalid.
465         assertTrue("getMccString() out of range [0, 999], mcc=" + mccStr,
466                 mccStr == null || mccStr.matches("^[0-9]{3}$"));
467         // mccStr must either be null or match mcc integer.
468         assertTrue("MccString must match Mcc Integer, str=" + mccStr + " int=" + mcc,
469                 mccStr == null || mcc == Integer.parseInt(mccStr));
470 
471         // mncStr is set as NULL if empty, unknown or invalid.
472         assertTrue("getMncString() out of range [0, 999], mnc=" + mncStr,
473                 mncStr == null || mncStr.matches("^[0-9]{2,3}$"));
474         // mncStr must either be null or match mnc integer.
475         assertTrue("MncString must match Mnc Integer, str=" + mncStr + " int=" + mnc,
476                 mncStr == null || mnc == Integer.parseInt(mncStr));
477     }
478 
479     // Verify lte cell information is within correct range.
verifyLteInfo(CellInfoLte lte)480     private void verifyLteInfo(CellInfoLte lte) {
481         verifyCellConnectionStatus(lte.getCellConnectionStatus());
482         verifyCellInfoLteParcelandHashcode(lte);
483         verifyCellIdentityLte(lte.getCellIdentity(), lte.isRegistered());
484         verifyCellIdentityLteParcel(lte.getCellIdentity());
485         verifyCellSignalStrengthLte(lte.getCellSignalStrength());
486         verifyCellSignalStrengthLteParcel(lte.getCellSignalStrength());
487     }
488 
489     // Verify NR 5G cell information is within correct range.
verifyNrInfo(CellInfoNr nr)490     private void verifyNrInfo(CellInfoNr nr) {
491         verifyCellConnectionStatus(nr.getCellConnectionStatus());
492         verifyCellIdentityNr((CellIdentityNr) nr.getCellIdentity(), nr.isRegistered());
493         verifyCellIdentityNrParcel((CellIdentityNr) nr.getCellIdentity());
494         verifyCellSignalStrengthNr((CellSignalStrengthNr) nr.getCellSignalStrength());
495         verifyCellSignalStrengthNrParcel((CellSignalStrengthNr) nr.getCellSignalStrength());
496     }
497 
verifyCellSignalStrengthNrParcel(CellSignalStrengthNr nr)498     private void verifyCellSignalStrengthNrParcel(CellSignalStrengthNr nr) {
499         Parcel p = Parcel.obtain();
500         nr.writeToParcel(p, 0);
501         p.setDataPosition(0);
502 
503         CellSignalStrengthNr newCss = CellSignalStrengthNr.CREATOR.createFromParcel(p);
504         assertEquals(nr, newCss);
505     }
506 
verifyCellIdentityNrParcel(CellIdentityNr nr)507     private void verifyCellIdentityNrParcel(CellIdentityNr nr) {
508         Parcel p = Parcel.obtain();
509         nr.writeToParcel(p, 0);
510         p.setDataPosition(0);
511 
512         CellIdentityNr newCi = CellIdentityNr.CREATOR.createFromParcel(p);
513         assertEquals(nr, newCi);
514     }
515 
verifyCellIdentityNr(CellIdentityNr nr, boolean isRegistered)516     private void verifyCellIdentityNr(CellIdentityNr nr, boolean isRegistered) {
517         int pci = nr.getPci();
518         assertTrue("getPci() out of range [0, 1007], pci = " + pci, 0 <= pci && pci <= 1007);
519 
520         int tac = nr.getTac();
521         assertTrue("getTac() out of range [0, 65536], tac = " + tac, 0 <= tac && tac <= 65536);
522 
523         int nrArfcn = nr.getNrarfcn();
524         assertTrue("getNrarfcn() out of range [0, 3279165], nrarfcn = " + nrArfcn,
525                 0 <= nrArfcn && nrArfcn <= 3279165);
526 
527         String mccStr = nr.getMccString();
528         String mncStr = nr.getMncString();
529         // mccStr is set as NULL if empty, unknown or invalid.
530         assertTrue("getMccString() out of range [0, 999], mcc=" + mccStr,
531                 mccStr == null || mccStr.matches("^[0-9]{3}$"));
532 
533         // mncStr is set as NULL if empty, unknown or invalid.
534         assertTrue("getMncString() out of range [0, 999], mnc=" + mncStr,
535                 mncStr == null || mncStr.matches("^[0-9]{2,3}$"));
536 
537         // If the cell is reported as registered, then all the logical cell info must be reported
538         if (isRegistered) {
539             assertTrue("TAC is required for registered cells", tac != Integer.MAX_VALUE);
540             assertTrue("MCC is required for registered cells", nr.getMccString() != null);
541             assertTrue("MNC is required for registered cells", nr.getMncString() != null);
542         }
543     }
544 
verifyCellSignalStrengthNr(CellSignalStrengthNr nr)545     private void verifyCellSignalStrengthNr(CellSignalStrengthNr nr) {
546         int csiRsrp = nr.getCsiRsrp();
547         int csiRsrq = nr.getCsiRsrq();
548         int csiSinr = nr.getSsSinr();
549         int ssRsrp = nr.getSsRsrp();
550         int ssRsrq = nr.getSsRsrq();
551         int ssSinr = nr.getSsSinr();
552 
553         assertTrue("getCsiRsrp() out of range [-140, -44] | Integer.MAX_INTEGER, csiRsrp = "
554                         + csiRsrp, -140 <= csiRsrp && csiRsrp <= -44
555                 || csiRsrp == Integer.MAX_VALUE);
556         assertTrue("getCsiRsrq() out of range [-20, -3] | Integer.MAX_INTEGER, csiRsrq = "
557                 + csiRsrq, -20 <= csiRsrq && csiRsrq <= -3 || csiRsrq == Integer.MAX_VALUE);
558         assertTrue("getCsiSinr() out of range [-23, 40] | Integer.MAX_INTEGER, csiSinr = "
559                 + csiSinr, -23 <= csiSinr && csiSinr <= 40 || csiSinr == Integer.MAX_VALUE);
560         assertTrue("getSsRsrp() out of range [-140, -44] | Integer.MAX_INTEGER, ssRsrp = "
561                         + ssRsrp, -140 <= ssRsrp && ssRsrp <= -44 || ssRsrp == Integer.MAX_VALUE);
562         assertTrue("getSsRsrq() out of range [-20, -3] | Integer.MAX_INTEGER, ssRsrq = "
563                 + ssRsrq, -20 <= ssRsrq && ssRsrq <= -3 || ssRsrq == Integer.MAX_VALUE);
564         assertTrue("getSsSinr() out of range [-23, 40] | Integer.MAX_INTEGER, ssSinr = "
565                 + ssSinr, -23 <= ssSinr && ssSinr <= 40 || ssSinr == Integer.MAX_VALUE);
566     }
567 
verifyCellInfoLteParcelandHashcode(CellInfoLte lte)568     private void verifyCellInfoLteParcelandHashcode(CellInfoLte lte) {
569         Parcel p = Parcel.obtain();
570         lte.writeToParcel(p, 0);
571         p.setDataPosition(0);
572 
573         CellInfoLte newCi = CellInfoLte.CREATOR.createFromParcel(p);
574         assertTrue(lte.equals(newCi));
575         assertEquals("hashCode() did not get right hashCode", lte.hashCode(), newCi.hashCode());
576     }
577 
verifyCellIdentityLte(CellIdentityLte lte, boolean isRegistered)578     private void verifyCellIdentityLte(CellIdentityLte lte, boolean isRegistered) {
579         verifyPlmnInfo(lte.getMccString(), lte.getMncString(), lte.getMcc(), lte.getMnc());
580 
581         // Cell identity ranges from 0 to 268435456.
582         int ci = lte.getCi();
583         assertTrue("getCi() out of range [0,268435456], ci=" + ci,
584                 (ci == Integer.MAX_VALUE) || (ci >= 0 && ci <= CI));
585 
586         // Verify LTE physical cell id information.
587         // Only physical cell id is available for LTE neighbor.
588         int pci = lte.getPci();
589         // Physical cell id should be within [0, 503].
590         assertTrue("getPci() out of range [0, 503], pci=" + pci,
591                 (pci== Integer.MAX_VALUE) || (pci >= 0 && pci <= PCI));
592 
593         // Tracking area code ranges from 0 to 65535.
594         int tac = lte.getTac();
595         assertTrue("getTac() out of range [0,65535], tac=" + tac,
596                 (tac == Integer.MAX_VALUE) || (tac >= 0 && tac <= TAC));
597 
598         int bw = lte.getBandwidth();
599         assertTrue("getBandwidth out of range [1400, 20000] | Integer.Max_Value, bw=",
600                 bw == Integer.MAX_VALUE || bw >= BANDWIDTH_LOW && bw <= BANDWIDTH_HIGH);
601 
602         int earfcn = lte.getEarfcn();
603         // Reference 3GPP 36.101 Table 5.7.3-1
604         // As per NOTE 1 in the table, although 0-6 are valid channel numbers for
605         // LTE, the reported EARFCN is the center frequency, rendering these channels
606         // out of the range of the narrowest 1.4Mhz deployment.
607         int minEarfcn = 7;
608         int maxEarfcn = EARFCN_MAX - 7;
609         if (bw != Integer.MAX_VALUE) {
610             // The number of channels used by a cell is equal to the cell bandwidth divided
611             // by the channel raster (bandwidth of a channel). The center channel is the channel
612             // the n/2-th channel where n is the number of channels, and since it is the center
613             // channel that is reported as the channel number for a cell, we can exclude any channel
614             // numbers within a band that would place the bottom of a cell's bandwidth below the
615             // edge of the band. For channel numbers in Band 1, the EARFCN numbering starts from
616             // channel 0, which means that we can exclude from the valid range channels starting
617             // from 0 and numbered less than half the total number of channels occupied by a cell.
618             minEarfcn = bw / CHANNEL_RASTER_EUTRAN / 2;
619             maxEarfcn = EARFCN_MAX - (bw / CHANNEL_RASTER_EUTRAN / 2);
620         }
621         assertTrue(
622                 "getEarfcn() out of range [" + minEarfcn + "," + maxEarfcn + "], earfcn=" + earfcn,
623                 earfcn == Integer.MAX_VALUE || (earfcn >= minEarfcn && earfcn <= maxEarfcn));
624 
625         String mobileNetworkOperator = lte.getMobileNetworkOperator();
626         assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
627                         + mobileNetworkOperator,
628                 mobileNetworkOperator == null
629                         || mobileNetworkOperator.matches("^[0-9]{5,6}$"));
630 
631         // If the cell is reported as registered, then all the logical cell info must be reported
632         if (isRegistered) {
633             assertTrue("TAC is required for registered cells", tac != Integer.MAX_VALUE);
634             assertTrue("CID is required for registered cells", ci != Integer.MAX_VALUE);
635             assertTrue("MCC is required for registered cells",
636                     lte.getMccString() != null || lte.getMcc() != Integer.MAX_VALUE);
637             assertTrue("MNC is required for registered cells",
638                     lte.getMncString() != null || lte.getMnc() != Integer.MAX_VALUE);
639         }
640     }
641 
verifyCellIdentityLteParcel(CellIdentityLte lte)642     private void verifyCellIdentityLteParcel(CellIdentityLte lte) {
643         Parcel p = Parcel.obtain();
644         lte.writeToParcel(p, 0);
645         p.setDataPosition(0);
646 
647         CellIdentityLte newci = CellIdentityLte.CREATOR.createFromParcel(p);
648         assertEquals(lte, newci);
649     }
650 
verifyCellSignalStrengthLte(CellSignalStrengthLte cellSignalStrengthLte)651     private void verifyCellSignalStrengthLte(CellSignalStrengthLte cellSignalStrengthLte) {
652         verifyRssiDbm(cellSignalStrengthLte.getDbm());
653 
654         //Integer.MAX_VALUE indicates an unavailable field
655         int rsrp = cellSignalStrengthLte.getRsrp();
656         // RSRP is being treated as RSSI in LTE (they are similar but not quite right)
657         // so reusing the constants here.
658         assertTrue("getRsrp() out of range, rsrp=" + rsrp, rsrp >= MIN_RSRP && rsrp <= MAX_RSRP);
659 
660         int rsrq = cellSignalStrengthLte.getRsrq();
661         assertTrue("getRsrq() out of range | Integer.MAX_VALUE, rsrq=" + rsrq,
662             rsrq == Integer.MAX_VALUE || (rsrq >= MIN_RSRQ && rsrq <= MAX_RSRQ));
663 
664         int rssi = cellSignalStrengthLte.getRssi();
665         assertTrue("getRssi() out of range [-113, -51] or Integer.MAX_VALUE if unknown, rssi="
666                 + rssi, rssi == CellInfo.UNAVAILABLE
667                 || (rssi >= MIN_LTE_RSSI && rssi <= MAX_LTE_RSSI));
668 
669         int rssnr = cellSignalStrengthLte.getRssnr();
670         assertTrue("getRssnr() out of range | Integer.MAX_VALUE, rssnr=" + rssnr,
671             rssnr == Integer.MAX_VALUE || (rssnr >= MIN_RSSNR && rssnr <= MAX_RSSNR));
672 
673         int cqi = cellSignalStrengthLte.getCqi();
674         assertTrue("getCqi() out of range | Integer.MAX_VALUE, cqi=" + cqi,
675             cqi == Integer.MAX_VALUE || (cqi >= MIN_CQI && cqi <= MAX_CQI));
676 
677         int ta = cellSignalStrengthLte.getTimingAdvance();
678         assertTrue("getTimingAdvance() invalid [0-1282] | Integer.MAX_VALUE, ta=" + ta,
679                 ta == Integer.MAX_VALUE || (ta >= 0 && ta <=1282));
680 
681         int level = cellSignalStrengthLte.getLevel();
682         assertTrue("getLevel() out of range [0,4], level=" + level, level >= 0 && level <= 4);
683 
684         int asuLevel = cellSignalStrengthLte.getAsuLevel();
685         assertTrue("getAsuLevel() out of range [0,97] (or 99 is unknown), asuLevel=" + asuLevel,
686                 (asuLevel == 99) || (asuLevel >= 0 && asuLevel <= 97));
687 
688         int timingAdvance = cellSignalStrengthLte.getTimingAdvance();
689         assertTrue("getTimingAdvance() out of range [0,1282], timingAdvance=" + timingAdvance,
690                 timingAdvance == Integer.MAX_VALUE || (timingAdvance >= 0 && timingAdvance <= 1282));
691 
692         if (mRadioHalVersion >= RADIO_HAL_VERSION_1_2) {
693             assertTrue("RSRP Must be valid for LTE",
694                     cellSignalStrengthLte.getRsrp() != CellInfo.UNAVAILABLE);
695         }
696     }
697 
verifyCellSignalStrengthLteParcel(CellSignalStrengthLte cellSignalStrengthLte)698     private void verifyCellSignalStrengthLteParcel(CellSignalStrengthLte cellSignalStrengthLte) {
699         Parcel p = Parcel.obtain();
700         cellSignalStrengthLte.writeToParcel(p, 0);
701         p.setDataPosition(0);
702 
703         CellSignalStrengthLte newCss = CellSignalStrengthLte.CREATOR.createFromParcel(p);
704         assertEquals(cellSignalStrengthLte, newCss);
705     }
706 
707     // Verify wcdma cell information is within correct range.
verifyWcdmaInfo(CellInfoWcdma wcdma)708     private void verifyWcdmaInfo(CellInfoWcdma wcdma) {
709         verifyCellConnectionStatus(wcdma.getCellConnectionStatus());
710         verifyCellInfoWcdmaParcelandHashcode(wcdma);
711         verifyCellIdentityWcdma(wcdma.getCellIdentity(), wcdma.isRegistered());
712         verifyCellIdentityWcdmaParcel(wcdma.getCellIdentity());
713         verifyCellSignalStrengthWcdma(wcdma.getCellSignalStrength());
714         verifyCellSignalStrengthWcdmaParcel(wcdma.getCellSignalStrength());
715     }
716 
verifyCellInfoWcdmaParcelandHashcode(CellInfoWcdma wcdma)717     private void verifyCellInfoWcdmaParcelandHashcode(CellInfoWcdma wcdma) {
718         Parcel p = Parcel.obtain();
719         wcdma.writeToParcel(p, 0);
720         p.setDataPosition(0);
721 
722         CellInfoWcdma newCi = CellInfoWcdma.CREATOR.createFromParcel(p);
723         assertTrue(wcdma.equals(newCi));
724         assertEquals("hashCode() did not get right hashCode", wcdma.hashCode(), newCi.hashCode());
725     }
726 
verifyCellIdentityWcdma(CellIdentityWcdma wcdma, boolean isRegistered)727     private void verifyCellIdentityWcdma(CellIdentityWcdma wcdma, boolean isRegistered) {
728         verifyPlmnInfo(wcdma.getMccString(), wcdma.getMncString(), wcdma.getMcc(), wcdma.getMnc());
729 
730         int lac = wcdma.getLac();
731         assertTrue("getLac() out of range [0, 65535], lac=" + lac,
732                 (lac >= 0 && lac <= LAC) || lac == Integer.MAX_VALUE);
733 
734         int cid = wcdma.getCid();
735         assertTrue("getCid() out of range [0, 268435455], cid=" + cid,
736                 (cid >= 0 && cid <= CID_UMTS) || cid == Integer.MAX_VALUE);
737 
738         // Verify wcdma primary scrambling code information.
739         // Primary scrambling code should be within [0, 511].
740         int psc = wcdma.getPsc();
741         assertTrue("getPsc() out of range [0, 511], psc=" + psc,
742                 (psc >= 0 && psc <= PSC) || psc == Integer.MAX_VALUE);
743 
744         String mobileNetworkOperator = wcdma.getMobileNetworkOperator();
745         assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
746                         + mobileNetworkOperator,
747                 mobileNetworkOperator == null
748                         || mobileNetworkOperator.matches("^[0-9]{5,6}$"));
749 
750         int uarfcn = wcdma.getUarfcn();
751         // Reference 3GPP 25.101 Table 5.2
752         // From Appendix E.1, even though UARFCN is numbered from 400, the minumum
753         // usable channel is 412 due to the fixed bandwidth of 5Mhz
754         assertTrue("getUarfcn() out of range [412,11000], uarfcn=" + uarfcn,
755                 uarfcn >= 412 && uarfcn <= 11000);
756 
757         // If the cell is reported as registered, then all the logical cell info must be reported
758         if (isRegistered) {
759             assertTrue("LAC is required for registered cells", lac != Integer.MAX_VALUE);
760             assertTrue("CID is required for registered cells", cid != Integer.MAX_VALUE);
761             assertTrue("MCC is required for registered cells",
762                     wcdma.getMccString() != null || wcdma.getMcc() != Integer.MAX_VALUE);
763             assertTrue("MNC is required for registered cells",
764                     wcdma.getMncString() != null || wcdma.getMnc() != Integer.MAX_VALUE);
765         }
766     }
767 
verifyCellIdentityWcdmaParcel(CellIdentityWcdma wcdma)768     private void verifyCellIdentityWcdmaParcel(CellIdentityWcdma wcdma) {
769         Parcel p = Parcel.obtain();
770         wcdma.writeToParcel(p, 0);
771         p.setDataPosition(0);
772 
773         CellIdentityWcdma newci = CellIdentityWcdma.CREATOR.createFromParcel(p);
774         assertEquals(wcdma, newci);
775     }
776 
verifyCellSignalStrengthWcdma(CellSignalStrengthWcdma wcdma)777     private void verifyCellSignalStrengthWcdma(CellSignalStrengthWcdma wcdma) {
778         verifyRssiDbm(wcdma.getDbm());
779 
780         // Dbm here does not have specific limits. So just calling to verify that it does not crash
781         // the phone
782         wcdma.getDbm();
783 
784         int asuLevel = wcdma.getAsuLevel();
785         assertTrue("getLevel() out of range [0,31] (or 99 is unknown), level=" + asuLevel,
786                 asuLevel == 99 || (asuLevel >= 0 && asuLevel <= 31));
787 
788         int level = wcdma.getLevel();
789         assertTrue("getLevel() out of range [0,4], level=" + level, level >= 0 && level <= 4);
790 
791         if (mRadioHalVersion >= RADIO_HAL_VERSION_1_2) {
792             assertTrue("RSCP Must be valid for WCDMA", wcdma.getRscp() != CellInfo.UNAVAILABLE);
793         }
794     }
795 
verifyCellSignalStrengthWcdmaParcel(CellSignalStrengthWcdma wcdma)796     private void verifyCellSignalStrengthWcdmaParcel(CellSignalStrengthWcdma wcdma) {
797         Parcel p = Parcel.obtain();
798         wcdma.writeToParcel(p, 0);
799         p.setDataPosition(0);
800 
801         CellSignalStrengthWcdma newCss = CellSignalStrengthWcdma.CREATOR.createFromParcel(p);
802         assertEquals(wcdma, newCss);
803     }
804 
805     // Verify gsm cell information is within correct range.
verifyGsmInfo(CellInfoGsm gsm)806     private void verifyGsmInfo(CellInfoGsm gsm) {
807         verifyCellConnectionStatus(gsm.getCellConnectionStatus());
808         verifyCellInfoWcdmaParcelandHashcode(gsm);
809         verifyCellIdentityGsm(gsm.getCellIdentity(), gsm.isRegistered());
810         verifyCellIdentityGsmParcel(gsm.getCellIdentity());
811         verifyCellSignalStrengthGsm(gsm.getCellSignalStrength());
812         verifyCellSignalStrengthGsmParcel(gsm.getCellSignalStrength());
813     }
814 
verifyCellInfoWcdmaParcelandHashcode(CellInfoGsm gsm)815     private void verifyCellInfoWcdmaParcelandHashcode(CellInfoGsm gsm) {
816         Parcel p = Parcel.obtain();
817         gsm.writeToParcel(p, 0);
818         p.setDataPosition(0);
819 
820         CellInfoGsm newCi = CellInfoGsm.CREATOR.createFromParcel(p);
821         assertTrue(gsm.equals(newCi));
822         assertEquals("hashCode() did not get right hashCode", gsm.hashCode(), newCi.hashCode());
823     }
824 
verifyCellIdentityGsm(CellIdentityGsm gsm, boolean isRegistered)825     private void verifyCellIdentityGsm(CellIdentityGsm gsm, boolean isRegistered) {
826         verifyPlmnInfo(gsm.getMccString(), gsm.getMncString(), gsm.getMcc(), gsm.getMnc());
827 
828         // Local area code and cellid should be with [0, 65535].
829         int lac = gsm.getLac();
830         assertTrue("getLac() out of range [0, 65535], lac=" + lac,
831                 lac == Integer.MAX_VALUE || (lac >= 0 && lac <= LAC));
832         int cid = gsm.getCid();
833         assertTrue("getCid() out range [0, 65535], cid=" + cid,
834                 cid== Integer.MAX_VALUE || (cid >= 0 && cid <= CID_GSM));
835 
836         int arfcn = gsm.getArfcn();
837         // Reference 3GPP 45.005 Table 2-2
838         assertTrue("getArfcn() out of range [0,1024], arfcn=" + arfcn,
839                 arfcn == Integer.MAX_VALUE || (arfcn >= 0 && arfcn <= ARFCN));
840 
841         String mobileNetworkOperator = gsm.getMobileNetworkOperator();
842         assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
843                         + mobileNetworkOperator,
844                 mobileNetworkOperator == null
845                         || mobileNetworkOperator.matches("^[0-9]{5,6}$"));
846 
847         int bsic = gsm.getBsic();
848         // TODO(b/32774471) - Bsic should always be valid
849         //assertTrue("getBsic() out of range [0,63]", bsic >= 0 && bsic <=63);
850 
851         // If the cell is reported as registered, then all the logical cell info must be reported
852         if (isRegistered) {
853             assertTrue("LAC is required for registered cells", lac != Integer.MAX_VALUE);
854             assertTrue("CID is required for registered cells", cid != Integer.MAX_VALUE);
855             assertTrue("MCC is required for registered cells",
856                     gsm.getMccString() != null || gsm.getMcc() != Integer.MAX_VALUE);
857             assertTrue("MNC is required for registered cells",
858                     gsm.getMncString() != null || gsm.getMnc() != Integer.MAX_VALUE);
859         }
860     }
861 
verifyCellIdentityGsmParcel(CellIdentityGsm gsm)862     private void verifyCellIdentityGsmParcel(CellIdentityGsm gsm) {
863         Parcel p = Parcel.obtain();
864         gsm.writeToParcel(p, 0);
865         p.setDataPosition(0);
866 
867         CellIdentityGsm newci = CellIdentityGsm.CREATOR.createFromParcel(p);
868         assertEquals(gsm, newci);
869     }
870 
verifyCellSignalStrengthGsm(CellSignalStrengthGsm gsm)871     private void verifyCellSignalStrengthGsm(CellSignalStrengthGsm gsm) {
872         verifyRssiDbm(gsm.getDbm());
873 
874         int level = gsm.getLevel();
875         assertTrue("getLevel() out of range [0,4], level=" + level, level >= 0 && level <= 4);
876 
877         int ta = gsm.getTimingAdvance();
878         assertTrue("getTimingAdvance() out of range [0,219] | Integer.MAX_VALUE, ta=" + ta,
879                 ta == Integer.MAX_VALUE || (ta >= 0 && ta <= 219));
880 
881         // Dbm here does not have specific limits. So just calling to verify that it does not
882         // crash the phone
883         gsm.getDbm();
884 
885         int asuLevel = gsm.getAsuLevel();
886         assertTrue("getLevel() out of range [0,31] (or 99 is unknown), level=" + asuLevel,
887                 asuLevel == 99 || (asuLevel >=0 && asuLevel <= 31));
888 
889         int ber = gsm.getBitErrorRate();
890         assertTrue("getBitErrorRate out of range [0,7], 99, or CellInfo.UNAVAILABLE, ber=" + ber,
891                 ber == 99 || ber == CellInfo.UNAVAILABLE || (ber >= 0 && ber <= 7));
892 
893         if (mRadioHalVersion >= RADIO_HAL_VERSION_1_2) {
894             assertTrue("RSSI Must be valid for GSM", gsm.getDbm() != CellInfo.UNAVAILABLE);
895         }
896     }
897 
verifyCellSignalStrengthGsmParcel(CellSignalStrengthGsm gsm)898     private void verifyCellSignalStrengthGsmParcel(CellSignalStrengthGsm gsm) {
899         Parcel p = Parcel.obtain();
900         gsm.writeToParcel(p, 0);
901         p.setDataPosition(0);
902 
903         CellSignalStrengthGsm newCss = CellSignalStrengthGsm.CREATOR.createFromParcel(p);
904         assertEquals(gsm, newCss);
905     }
906 
907     // Verify tdscdma cell information is within correct range.
verifyTdscdmaInfo(CellInfoTdscdma tdscdma)908     private void verifyTdscdmaInfo(CellInfoTdscdma tdscdma) {
909         verifyCellConnectionStatus(tdscdma.getCellConnectionStatus());
910         verifyCellInfoTdscdmaParcelandHashcode(tdscdma);
911         verifyCellIdentityTdscdma(tdscdma.getCellIdentity(), tdscdma.isRegistered());
912         verifyCellIdentityTdscdmaParcel(tdscdma.getCellIdentity());
913         verifyCellSignalStrengthTdscdma(tdscdma.getCellSignalStrength());
914         verifyCellSignalStrengthTdscdmaParcel(tdscdma.getCellSignalStrength());
915     }
916 
verifyCellInfoTdscdmaParcelandHashcode(CellInfoTdscdma tdscdma)917     private void verifyCellInfoTdscdmaParcelandHashcode(CellInfoTdscdma tdscdma) {
918         Parcel p = Parcel.obtain();
919         tdscdma.writeToParcel(p, 0);
920         p.setDataPosition(0);
921 
922         CellInfoTdscdma newCi = CellInfoTdscdma.CREATOR.createFromParcel(p);
923         assertTrue(tdscdma.equals(newCi));
924         assertEquals("hashCode() did not get right hashCode", tdscdma.hashCode(), newCi.hashCode());
925     }
926 
verifyCellIdentityTdscdma(CellIdentityTdscdma tdscdma, boolean isRegistered)927     private void verifyCellIdentityTdscdma(CellIdentityTdscdma tdscdma, boolean isRegistered) {
928         String mccStr = tdscdma.getMccString();
929         String mncStr = tdscdma.getMncString();
930 
931         // This class was added after numeric mcc/mncs were no longer provided, so it lacks the
932         // basic getMcc() and getMnc() - Dummy out those checks.
933         verifyPlmnInfo(tdscdma.getMccString(), tdscdma.getMncString(),
934                 mccStr != null ? Integer.parseInt(mccStr) : CellInfo.UNAVAILABLE,
935                 mncStr != null ? Integer.parseInt(mncStr) : CellInfo.UNAVAILABLE);
936 
937         int lac = tdscdma.getLac();
938         assertTrue("getLac() out of range [0, 65535], lac=" + lac,
939                 (lac >= 0 && lac <= LAC) || lac == Integer.MAX_VALUE);
940 
941         int cid = tdscdma.getCid();
942         assertTrue("getCid() out of range [0, 268435455], cid=" + cid,
943                 (cid >= 0 && cid <= CID_UMTS) || cid == Integer.MAX_VALUE);
944 
945         // Verify tdscdma primary scrambling code information.
946         // Primary scrambling code should be within [0, 511].
947         int cpid = tdscdma.getCpid();
948         assertTrue("getCpid() out of range [0, 127], cpid=" + cpid, (cpid >= 0 && cpid <= CPID));
949 
950         String mobileNetworkOperator = tdscdma.getMobileNetworkOperator();
951         assertTrue("getMobileNetworkOperator() out of range [0, 999999], mobileNetworkOperator="
952                         + mobileNetworkOperator,
953                 mobileNetworkOperator == null
954                         || mobileNetworkOperator.matches("^[0-9]{5,6}$"));
955 
956         int uarfcn = tdscdma.getUarfcn();
957         // Reference 3GPP 25.101 Table 5.2
958         // From Appendix E.1, even though UARFCN is numbered from 400, the minumum
959         // usable channel is 412 due to the fixed bandwidth of 5Mhz
960         assertTrue("getUarfcn() out of range [412,11000], uarfcn=" + uarfcn,
961                 uarfcn >= 412 && uarfcn <= 11000);
962 
963         // If the cell is reported as registered, then all the logical cell info must be reported
964         if (isRegistered) {
965             assertTrue("LAC is required for registered cells", lac != Integer.MAX_VALUE);
966             assertTrue("CID is required for registered cells", cid != Integer.MAX_VALUE);
967             assertTrue("MCC is required for registered cells", tdscdma.getMccString() != null);
968             assertTrue("MNC is required for registered cells", tdscdma.getMncString() != null);
969         }
970     }
971 
verifyCellIdentityTdscdmaParcel(CellIdentityTdscdma tdscdma)972     private void verifyCellIdentityTdscdmaParcel(CellIdentityTdscdma tdscdma) {
973         Parcel p = Parcel.obtain();
974         tdscdma.writeToParcel(p, 0);
975         p.setDataPosition(0);
976 
977         CellIdentityTdscdma newci = CellIdentityTdscdma.CREATOR.createFromParcel(p);
978         assertEquals(tdscdma, newci);
979     }
980 
verifyCellSignalStrengthTdscdma(CellSignalStrengthTdscdma tdscdma)981     private void verifyCellSignalStrengthTdscdma(CellSignalStrengthTdscdma tdscdma) {
982         verifyRssiDbm(tdscdma.getDbm());
983 
984         // Dbm here does not have specific limits. So just calling to verify that it does not crash
985         // the phone
986         tdscdma.getDbm();
987 
988         int asuLevel = tdscdma.getAsuLevel();
989         assertTrue("getLevel() out of range [0,31] (or 99 is unknown), level=" + asuLevel,
990                 asuLevel == 99 || (asuLevel >= 0 && asuLevel <= 31));
991 
992         int level = tdscdma.getLevel();
993         assertTrue("getLevel() out of range [0,4], level=" + level, level >= 0 && level <= 4);
994 
995         if (mRadioHalVersion >= RADIO_HAL_VERSION_1_2) {
996             assertTrue("RSCP Must be valid for TDSCDMA", tdscdma.getRscp() != CellInfo.UNAVAILABLE);
997         }
998     }
999 
verifyCellSignalStrengthTdscdmaParcel(CellSignalStrengthTdscdma tdscdma)1000     private void verifyCellSignalStrengthTdscdmaParcel(CellSignalStrengthTdscdma tdscdma) {
1001         Parcel p = Parcel.obtain();
1002         tdscdma.writeToParcel(p, 0);
1003         p.setDataPosition(0);
1004 
1005         CellSignalStrengthTdscdma newCss = CellSignalStrengthTdscdma.CREATOR.createFromParcel(p);
1006         assertEquals(tdscdma, newCss);
1007     }
1008 
1009     // Rssi(in dbm) should be within [MIN_RSSI, MAX_RSSI].
verifyRssiDbm(int dbm)1010     private void verifyRssiDbm(int dbm) {
1011         assertTrue("getCellSignalStrength().getDbm() out of range, dbm=" + dbm,
1012                 dbm >= MIN_RSSI && dbm <= MAX_RSSI);
1013     }
1014 
verifyCellConnectionStatus(int status)1015     private void verifyCellConnectionStatus(int status) {
1016         assertTrue("getCellConnectionStatus() invalid [0,2] | Integer.MAX_VALUE, status=",
1017             status == CellInfo.CONNECTION_NONE
1018                 || status == CellInfo.CONNECTION_PRIMARY_SERVING
1019                 || status == CellInfo.CONNECTION_SECONDARY_SERVING
1020                 || status == CellInfo.CONNECTION_UNKNOWN);
1021     }
1022 }
1023