Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2018 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.carrierapi.cts;
     17 
     18 import android.content.Context;
     19 import android.content.pm.PackageManager;
     20 import android.os.Handler;
     21 import android.os.HandlerThread;
     22 import android.os.Message;
     23 import android.os.Parcel;
     24 import android.support.test.InstrumentationRegistry;
     25 import android.support.test.runner.AndroidJUnit4;
     26 import android.telephony.CellInfo;
     27 import android.telephony.CellInfoGsm;
     28 import android.telephony.CellInfoLte;
     29 import android.telephony.CellInfoWcdma;
     30 import android.telephony.NetworkScan;
     31 import android.telephony.NetworkScanRequest;
     32 import android.telephony.RadioAccessSpecifier;
     33 import android.telephony.AccessNetworkConstants;
     34 import android.telephony.TelephonyManager;
     35 import android.telephony.TelephonyScanManager;
     36 import android.util.Log;
     37 
     38 import org.junit.After;
     39 import org.junit.Before;
     40 import org.junit.Test;
     41 import org.junit.runner.RunWith;
     42 
     43 import java.util.ArrayList;
     44 import java.util.Arrays;
     45 import java.util.List;
     46 
     47 import static org.junit.Assert.assertFalse;
     48 import static org.junit.Assert.assertNotSame;
     49 import static org.junit.Assert.assertNull;
     50 import static org.junit.Assert.assertTrue;
     51 import static org.junit.Assert.assertEquals;
     52 import static org.junit.Assert.fail;
     53 
     54 /**
     55  * Build, install and run the tests by running the commands below:
     56  *  make cts -j64
     57  *  cts-tradefed run cts -m CtsCarrierApiTestCases --test android.carrierapi.cts.NetworkScanApiTest
     58  */
     59 @RunWith(AndroidJUnit4.class)
     60 public class NetworkScanApiTest {
     61     private TelephonyManager mTelephonyManager;
     62     private PackageManager mPackageManager;
     63     private static final String TAG = "NetworkScanApiTest";
     64     private int mNetworkScanStatus;
     65     private static final int EVENT_NETWORK_SCAN_START = 100;
     66     private static final int EVENT_NETWORK_SCAN_RESULTS = 200;
     67     private static final int EVENT_NETWORK_SCAN_ERROR = 300;
     68     private static final int EVENT_NETWORK_SCAN_COMPLETED = 400;
     69     private List<CellInfo> mScanResults = null;
     70     private NetworkScanHandlerThread mTestHandlerThread;
     71     private Handler mHandler;
     72     private NetworkScan mNetworkScan;
     73     private NetworkScanRequest mNetworkScanRequest;
     74     private NetworkScanCallbackImpl mNetworkScanCallback;
     75     private static final int MAX_INIT_WAIT_MS = 60000; // 60 seconds
     76     private Object mLock = new Object();
     77     private boolean mReady;
     78     private int mErrorCode;
     79     /* All the following constants are used to construct NetworkScanRequest*/
     80     private static final int SCAN_TYPE = NetworkScanRequest.SCAN_TYPE_ONE_SHOT;
     81     private static final boolean INCREMENTAL_RESULTS = true;
     82     private static final int SEARCH_PERIODICITY_SEC = 5;
     83     private static final int MAX_SEARCH_TIME_SEC = 300;
     84     private static final int INCREMENTAL_RESULTS_PERIODICITY_SEC = 3;
     85     private static final ArrayList<String> MCC_MNC = new ArrayList<>();
     86     private static final RadioAccessSpecifier[] RADIO_ACCESS_SPECIFIERS = {
     87             new RadioAccessSpecifier(
     88                     AccessNetworkConstants.AccessNetworkType.GERAN,
     89                     null /* bands */,
     90                     null /* channels */),
     91             new RadioAccessSpecifier(
     92                     AccessNetworkConstants.AccessNetworkType.EUTRAN,
     93                     null /* bands */,
     94                     null /* channels */),
     95             new RadioAccessSpecifier(
     96                     AccessNetworkConstants.AccessNetworkType.UTRAN,
     97                     null /* bands */,
     98                     null /* channels */)
     99     };
    100 
    101     @Before
    102     public void setUp() throws Exception {
    103         mTelephonyManager = (TelephonyManager)
    104                 InstrumentationRegistry.getContext().getSystemService(Context.TELEPHONY_SERVICE);
    105         mPackageManager = InstrumentationRegistry.getContext().getPackageManager();
    106         mTestHandlerThread = new NetworkScanHandlerThread(TAG);
    107         mTestHandlerThread.start();
    108     }
    109 
    110     @After
    111     public void tearDown() throws Exception {
    112         mTestHandlerThread.quit();
    113     }
    114 
    115     private void waitUntilReady() {
    116         synchronized (mLock) {
    117             try {
    118                 mLock.wait(MAX_INIT_WAIT_MS);
    119             } catch (InterruptedException ie) {
    120             }
    121 
    122             if (!mReady) {
    123                 fail("NetworkScanApiTest failed to initialize");
    124             }
    125         }
    126     }
    127 
    128     private void setReady(boolean ready) {
    129         synchronized (mLock) {
    130             mReady = ready;
    131             mLock.notifyAll();
    132         }
    133     }
    134 
    135     private class NetworkScanHandlerThread extends HandlerThread {
    136 
    137         public NetworkScanHandlerThread(String name) {
    138             super(name);
    139         }
    140 
    141         @Override
    142         public void onLooperPrepared() {
    143             /* create a custom handler for the Handler Thread */
    144             mHandler = new Handler(mTestHandlerThread.getLooper()) {
    145                 @Override
    146                 public void handleMessage(Message msg) {
    147                     switch (msg.what) {
    148                         case EVENT_NETWORK_SCAN_START:
    149                             Log.d(TAG, "request network scan");
    150                             mNetworkScan = mTelephonyManager.requestNetworkScan(
    151                                     mNetworkScanRequest, mNetworkScanCallback);
    152                             break;
    153                         default:
    154                             Log.d(TAG, "Unknown Event " + msg.what);
    155                     }
    156                 }
    157             };
    158         }
    159     }
    160 
    161     private class NetworkScanCallbackImpl extends TelephonyScanManager.NetworkScanCallback {
    162         @Override
    163         public void onResults(List<CellInfo> results) {
    164             Log.d(TAG, "onResults: " + results.toString());
    165             mNetworkScanStatus = EVENT_NETWORK_SCAN_RESULTS;
    166             mScanResults = results;
    167         }
    168 
    169         @Override
    170         public void onComplete() {
    171             Log.d(TAG, "onComplete");
    172             mNetworkScanStatus = EVENT_NETWORK_SCAN_COMPLETED;
    173             setReady(true);
    174         }
    175 
    176         @Override
    177         public void onError(int error) {
    178             Log.d(TAG, "onError: " + String.valueOf(error));
    179             mNetworkScanStatus = EVENT_NETWORK_SCAN_ERROR;
    180             mErrorCode = error;
    181             Log.d(TAG, "Stop the network scan");
    182             mNetworkScan.stopScan();
    183             setReady(true);
    184         }
    185     }
    186 
    187     private RadioAccessSpecifier getRadioAccessSpecifier(CellInfo cellInfo) {
    188         RadioAccessSpecifier ras;
    189         if (cellInfo instanceof CellInfoLte) {
    190             int ranLte = AccessNetworkConstants.AccessNetworkType.EUTRAN;
    191             int[] lteChannels = {((CellInfoLte) cellInfo).getCellIdentity().getEarfcn()};
    192             ras = new RadioAccessSpecifier(ranLte, null /* bands */, lteChannels);
    193         } else if (cellInfo instanceof CellInfoWcdma) {
    194             int ranLte = AccessNetworkConstants.AccessNetworkType.UTRAN;
    195             int[] wcdmaChannels = {((CellInfoWcdma) cellInfo).getCellIdentity().getUarfcn()};
    196             ras = new RadioAccessSpecifier(ranLte, null /* bands */, wcdmaChannels);
    197         } else if (cellInfo instanceof CellInfoGsm) {
    198             int ranGsm = AccessNetworkConstants.AccessNetworkType.GERAN;
    199             int[] gsmChannels = {((CellInfoGsm) cellInfo).getCellIdentity().getArfcn()};
    200             ras = new RadioAccessSpecifier(ranGsm, null /* bands */, gsmChannels);
    201         } else {
    202             ras = null;
    203         }
    204         return ras;
    205     }
    206 
    207     /**
    208      * Tests that the device properly requests a network scan.
    209      */
    210     @Test
    211     public void testRequestNetworkScan() throws InterruptedException {
    212         if (!mPackageManager.hasSystemFeature(PackageManager.FEATURE_TELEPHONY)) {
    213             // Checks whether the cellular stack should be running on this device.
    214             Log.e(TAG, "No cellular support, the test will be skipped.");
    215             return;
    216         }
    217         if (!mTelephonyManager.hasCarrierPrivileges()) {
    218             fail("This test requires a SIM card with carrier privilege rule on it.");
    219         }
    220 
    221         // Make sure that there should be at least one entry.
    222         List<CellInfo> allCellInfo = mTelephonyManager.getAllCellInfo();
    223         if (allCellInfo == null) {
    224             fail("TelephonyManager.getAllCellInfo() returned NULL!");
    225         }
    226         if (allCellInfo.size() == 0) {
    227             fail("TelephonyManager.getAllCellInfo() returned zero-length list!");
    228         }
    229 
    230         // Construct a NetworkScanRequest
    231         List<RadioAccessSpecifier> radioAccessSpecifier = new ArrayList<>();
    232         for (int i = 0; i < allCellInfo.size(); i++) {
    233             RadioAccessSpecifier ras = getRadioAccessSpecifier(allCellInfo.get(i));
    234             if (ras != null) {
    235                 radioAccessSpecifier.add(ras);
    236             }
    237         }
    238         if (radioAccessSpecifier.size() == 0) {
    239             RadioAccessSpecifier gsm = new RadioAccessSpecifier(
    240                     AccessNetworkConstants.AccessNetworkType.GERAN,
    241                     null /* bands */,
    242                     null /* channels */);
    243             RadioAccessSpecifier lte = new RadioAccessSpecifier(
    244                     AccessNetworkConstants.AccessNetworkType.EUTRAN,
    245                     null /* bands */,
    246                     null /* channels */);
    247             RadioAccessSpecifier wcdma = new RadioAccessSpecifier(
    248                     AccessNetworkConstants.AccessNetworkType.UTRAN,
    249                     null /* bands */,
    250                     null /* channels */);
    251             radioAccessSpecifier.add(gsm);
    252             radioAccessSpecifier.add(lte);
    253             radioAccessSpecifier.add(wcdma);
    254         }
    255         RadioAccessSpecifier[] radioAccessSpecifierArray =
    256                 new RadioAccessSpecifier[radioAccessSpecifier.size()];
    257         mNetworkScanRequest = new NetworkScanRequest(
    258                 NetworkScanRequest.SCAN_TYPE_ONE_SHOT /* scan type */,
    259                 radioAccessSpecifier.toArray(radioAccessSpecifierArray),
    260                 5 /* search periodicity */,
    261                 60 /* max search time */,
    262                 true /*enable incremental results*/,
    263                 5 /* incremental results periodicity */,
    264                 null /* List of PLMN ids (MCC-MNC) */);
    265 
    266         mNetworkScanCallback = new NetworkScanCallbackImpl();
    267         Message startNetworkScan = mHandler.obtainMessage(EVENT_NETWORK_SCAN_START);
    268         setReady(false);
    269         startNetworkScan.sendToTarget();
    270         waitUntilReady();
    271 
    272         Log.d(TAG, "mNetworkScanStatus: " + mNetworkScanStatus);
    273         assertTrue("The final scan status is not ScanCompleted or ScanError with an error "
    274                         + "code ERROR_MODEM_UNAVAILABLE or ERROR_UNSUPPORTED",
    275                 isScanStatusValid());
    276     }
    277 
    278     private boolean isScanStatusValid() {
    279         // TODO(b/72162885): test the size of ScanResults is not zero after the blocking bug fixed.
    280         if ((mNetworkScanStatus == EVENT_NETWORK_SCAN_COMPLETED) && (mScanResults != null)) {
    281             // Scan complete.
    282             return true;
    283         }
    284         if ((mNetworkScanStatus == EVENT_NETWORK_SCAN_ERROR)
    285                 && ((mErrorCode == NetworkScan.ERROR_MODEM_UNAVAILABLE)
    286                 || (mErrorCode == NetworkScan.ERROR_UNSUPPORTED))) {
    287             // Scan error but the error type is allowed.
    288             return true;
    289         }
    290         return false;
    291     }
    292 
    293     private ArrayList<String> getPlmns() {
    294         ArrayList<String> mccMncs = new ArrayList<>();
    295         mccMncs.add("310260");
    296         mccMncs.add("310120");
    297         return mccMncs;
    298     }
    299 
    300     /**
    301      * To test its constructor and getters.
    302      */
    303     @Test
    304     public void testNetworkScanRequest_ConstructorAndGetters(){
    305         NetworkScanRequest networkScanRequest = new NetworkScanRequest(
    306                 SCAN_TYPE,
    307                 RADIO_ACCESS_SPECIFIERS,
    308                 SEARCH_PERIODICITY_SEC,
    309                 MAX_SEARCH_TIME_SEC,
    310                 INCREMENTAL_RESULTS,
    311                 INCREMENTAL_RESULTS_PERIODICITY_SEC,
    312                 getPlmns());
    313 
    314         assertEquals("getScanType() returns wrong value",
    315                 SCAN_TYPE, networkScanRequest.getScanType());
    316         assertEquals("getSpecifiers() returns wrong value",
    317                 RADIO_ACCESS_SPECIFIERS, networkScanRequest.getSpecifiers());
    318         assertEquals("getSearchPeriodicity() returns wrong value",
    319                 SEARCH_PERIODICITY_SEC, networkScanRequest.getSearchPeriodicity());
    320         assertEquals("getMaxSearchTime() returns wrong value",
    321                 MAX_SEARCH_TIME_SEC, networkScanRequest.getMaxSearchTime());
    322         assertEquals("getIncrementalResults() returns wrong value",
    323                 INCREMENTAL_RESULTS, networkScanRequest.getIncrementalResults());
    324         assertEquals("getIncrementalResultsPeriodicity() returns wrong value",
    325                 INCREMENTAL_RESULTS_PERIODICITY_SEC,
    326                 networkScanRequest.getIncrementalResultsPeriodicity());
    327         assertEquals("getPlmns() returns wrong value", getPlmns(), networkScanRequest.getPlmns());
    328         assertEquals("describeContents() returns wrong value",
    329                 0, networkScanRequest.describeContents());
    330     }
    331 
    332     /**
    333      * To test its hashCode method.
    334      */
    335     @Test
    336     public void testNetworkScanRequestParcel_Hashcode() {
    337         NetworkScanRequest networkScanRequest1 = new NetworkScanRequest(
    338                 SCAN_TYPE,
    339                 RADIO_ACCESS_SPECIFIERS,
    340                 SEARCH_PERIODICITY_SEC,
    341                 MAX_SEARCH_TIME_SEC,
    342                 INCREMENTAL_RESULTS,
    343                 INCREMENTAL_RESULTS_PERIODICITY_SEC,
    344                 getPlmns());
    345 
    346         NetworkScanRequest networkScanRequest2 = new NetworkScanRequest(
    347                 SCAN_TYPE,
    348                 RADIO_ACCESS_SPECIFIERS,
    349                 SEARCH_PERIODICITY_SEC,
    350                 MAX_SEARCH_TIME_SEC,
    351                 INCREMENTAL_RESULTS,
    352                 INCREMENTAL_RESULTS_PERIODICITY_SEC,
    353                 getPlmns());
    354 
    355         NetworkScanRequest networkScanRequest3 = new NetworkScanRequest(
    356                 SCAN_TYPE,
    357                 null,
    358                 SEARCH_PERIODICITY_SEC,
    359                 MAX_SEARCH_TIME_SEC,
    360                 false,
    361                 0,
    362                 getPlmns());
    363 
    364         assertEquals("hashCode() returns different hash code for same objects",
    365                 networkScanRequest1.hashCode(), networkScanRequest2.hashCode());
    366         assertNotSame("hashCode() returns same hash code for different objects",
    367                 networkScanRequest1.hashCode(), networkScanRequest3.hashCode());
    368     }
    369 
    370     /**
    371      * To test its comparision method.
    372      */
    373     @Test
    374     public void testNetworkScanRequestParcel_Equals() {
    375         NetworkScanRequest networkScanRequest1 = new NetworkScanRequest(
    376                 SCAN_TYPE,
    377                 RADIO_ACCESS_SPECIFIERS,
    378                 SEARCH_PERIODICITY_SEC,
    379                 MAX_SEARCH_TIME_SEC,
    380                 INCREMENTAL_RESULTS,
    381                 INCREMENTAL_RESULTS_PERIODICITY_SEC,
    382                 getPlmns());
    383 
    384         NetworkScanRequest networkScanRequest2 = new NetworkScanRequest(
    385                 SCAN_TYPE,
    386                 RADIO_ACCESS_SPECIFIERS,
    387                 SEARCH_PERIODICITY_SEC,
    388                 MAX_SEARCH_TIME_SEC,
    389                 INCREMENTAL_RESULTS,
    390                 INCREMENTAL_RESULTS_PERIODICITY_SEC,
    391                 getPlmns());
    392 
    393         assertTrue(networkScanRequest1.equals(networkScanRequest2));
    394 
    395         networkScanRequest2 = new NetworkScanRequest(
    396                 SCAN_TYPE,
    397                 RADIO_ACCESS_SPECIFIERS,
    398                 SEARCH_PERIODICITY_SEC,
    399                 MAX_SEARCH_TIME_SEC,
    400                 INCREMENTAL_RESULTS,
    401                 INCREMENTAL_RESULTS_PERIODICITY_SEC,
    402                 null /* List of PLMN ids (MCC-MNC) */);
    403         assertFalse(networkScanRequest1.equals(networkScanRequest2));
    404     }
    405 
    406     /**
    407      * To test its writeToParcel and createFromParcel methods.
    408      */
    409     @Test
    410     public void testNetworkScanRequestParcel_Parcel() {
    411         NetworkScanRequest networkScanRequest = new NetworkScanRequest(
    412                 SCAN_TYPE,
    413                 null /* Radio Access Specifier */,
    414                 SEARCH_PERIODICITY_SEC,
    415                 MAX_SEARCH_TIME_SEC,
    416                 INCREMENTAL_RESULTS,
    417                 INCREMENTAL_RESULTS_PERIODICITY_SEC,
    418                 getPlmns());
    419 
    420         Parcel p = Parcel.obtain();
    421         networkScanRequest.writeToParcel(p, 0);
    422         p.setDataPosition(0);
    423         NetworkScanRequest newnsr = NetworkScanRequest.CREATOR.createFromParcel(p);
    424         assertTrue(networkScanRequest.equals(newnsr));
    425 
    426     }
    427 }
    428