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