1 package android.location.cts.gnss; 2 3 import android.location.cts.common.GnssTestCase; 4 import android.location.cts.common.SoftAssert; 5 import android.location.cts.common.TestGnssStatusCallback; 6 import android.location.cts.common.TestLocationListener; 7 import android.location.cts.common.TestLocationManager; 8 import android.location.cts.common.TestMeasurementUtil; 9 import android.location.cts.common.TestUtils; 10 import android.net.ConnectivityManager; 11 import android.net.NetworkInfo; 12 import android.os.SystemClock; 13 import android.platform.test.annotations.AppModeFull; 14 import android.telephony.TelephonyManager; 15 import android.util.Log; 16 17 import com.android.compatibility.common.util.CddTest; 18 19 import java.util.concurrent.TimeUnit; 20 21 /** 22 * Tests for the ttff (time to the first fix) validating whether TTFF is 23 * below the expected thresholds in different scenario 24 */ 25 public class GnssTtffTests extends GnssTestCase { 26 27 private static final String TAG = "GnssTtffTests"; 28 private static final int LOCATION_TO_COLLECT_COUNT = 1; 29 private static final int STATUS_TO_COLLECT_COUNT = 3; 30 private static final int AIDING_DATA_RESET_DELAY_SECS = 10; 31 // Threshold values 32 private static final int TTFF_HOT_TH_SECS = 5; 33 private static final int TTFF_WITH_WIFI_CELLUAR_COLD_TH_SECS = 10; 34 // The worst case we saw in the Nexus 6p device is 15sec, 35 // adding 20% margin to the threshold 36 private static final int TTFF_WITH_WIFI_ONLY_COLD_TH_SECS = 18; 37 38 @Override setUp()39 protected void setUp() throws Exception { 40 super.setUp(); 41 mTestLocationManager = new TestLocationManager(getContext()); 42 } 43 44 /** 45 * Test the TTFF in the case where there is a network connection for both cold and hot start TTFF 46 * cases. 47 * We first test the "COLD" start where different TTFF thresholds are chosen based on network 48 * connection (cellular vs Wifi). Then we test the "HOT" start where the type of network 49 * connection should not matter hence one threshold is used. 50 * @throws Exception 51 */ 52 @CddTest(requirement="7.3.3") 53 @AppModeFull(reason = "permission ACCESS_LOCATION_EXTRA_COMMANDS not available to instant apps") testTtffWithNetwork()54 public void testTtffWithNetwork() throws Exception { 55 if (!TestUtils.deviceHasGpsFeature(getContext())) { 56 return; 57 } 58 59 // Network connection isn't required for automotive devices. 60 if (TestMeasurementUtil.isAutomotiveDevice(getContext())) { 61 return; 62 } 63 64 ensureNetworkStatus(); 65 if (hasCellularData()) { 66 checkTtffColdWithWifiOn(TTFF_WITH_WIFI_CELLUAR_COLD_TH_SECS); 67 } 68 else { 69 checkTtffColdWithWifiOn(TTFF_WITH_WIFI_ONLY_COLD_TH_SECS); 70 } 71 checkTtffHotWithWifiOn(TTFF_HOT_TH_SECS); 72 } 73 74 /** 75 * Test Scenario 1 76 * Check whether TTFF is below the threshold on the cold start with Wifi ON 77 * 1) Delete the aiding data. 78 * 2) Get GPS, check the TTFF value 79 * @param threshold, the threshold for the TTFF value 80 */ checkTtffColdWithWifiOn(long threshold)81 private void checkTtffColdWithWifiOn(long threshold) throws Exception { 82 SoftAssert softAssert = new SoftAssert(TAG); 83 mTestLocationManager.sendExtraCommand("delete_aiding_data"); 84 Thread.sleep(TimeUnit.SECONDS.toMillis(AIDING_DATA_RESET_DELAY_SECS)); 85 checkTtffByThreshold("checkTtffColdWithWifiOn", 86 TimeUnit.SECONDS.toMillis(threshold), softAssert); 87 softAssert.assertAll(); 88 } 89 90 /** 91 * Test Scenario 2 92 * Check whether TTFF is below the threhold on the hot start with wifi ON 93 * TODO(tccyp): to test the hot case with network connection off 94 * @param threshold, the threshold for the TTFF value 95 */ checkTtffHotWithWifiOn(long threshold)96 private void checkTtffHotWithWifiOn(long threshold) throws Exception { 97 SoftAssert softAssert = new SoftAssert(TAG); 98 checkTtffByThreshold("checkTtffHotWithWifiOn", 99 TimeUnit.SECONDS.toMillis(threshold), softAssert); 100 softAssert.assertAll(); 101 } 102 103 /** 104 * Make sure the device has either wifi data or cellular connection 105 */ ensureNetworkStatus()106 private void ensureNetworkStatus(){ 107 assertTrue("Device has to connect to Wifi or Cellular to complete this test.", 108 TestUtils.isConnectedToWifiOrCellular(getContext())); 109 110 } 111 hasCellularData()112 private boolean hasCellularData() { 113 ConnectivityManager connManager = TestUtils.getConnectivityManager(getContext()); 114 NetworkInfo cellularNetworkInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE); 115 // check whether the cellular data is ON if the device has cellular capability 116 if (cellularNetworkInfo == null) { 117 Log.i(TAG, "This is a wifi only device."); 118 return false; 119 } 120 TelephonyManager telephonyManager = (TelephonyManager) getContext().getApplicationContext() 121 .getSystemService(getContext().TELEPHONY_SERVICE); 122 if (!telephonyManager.isDataEnabled()) { 123 Log.i(TAG, "Device doesn't have cellular data."); 124 return false; 125 } 126 return true; 127 } 128 129 /* 130 * Check whether TTFF is below the threshold 131 * @param testName 132 * @param threshold, the threshold for the TTFF value 133 */ checkTtffByThreshold(String testName, long threshold, SoftAssert softAssert)134 private void checkTtffByThreshold(String testName, 135 long threshold, SoftAssert softAssert) throws Exception { 136 TestLocationListener networkLocationListener 137 = new TestLocationListener(LOCATION_TO_COLLECT_COUNT); 138 // fetch the networklocation first to make sure the ttff is not flaky 139 if (mTestLocationManager.requestNetworkLocationUpdates(networkLocationListener)) { 140 networkLocationListener.await(); 141 } 142 143 TestGnssStatusCallback testGnssStatusCallback = 144 new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT); 145 mTestLocationManager.registerGnssStatusCallback(testGnssStatusCallback); 146 147 TestLocationListener locationListener = new TestLocationListener(LOCATION_TO_COLLECT_COUNT); 148 mTestLocationManager.requestLocationUpdates(locationListener); 149 150 151 long startTimeMillis = SystemClock.elapsedRealtime(); 152 boolean success = testGnssStatusCallback.awaitTtff(); 153 long ttffTimeMillis = SystemClock.elapsedRealtime() - startTimeMillis; 154 155 softAssert.assertTrue( 156 "Test case:" + testName 157 + ". Threshold exceeded without getting a location." 158 + " Possibly, the test has been run deep indoors." 159 + " Consider retrying test outdoors.", 160 success); 161 mTestLocationManager.removeLocationUpdates(locationListener); 162 mTestLocationManager.unregisterGnssStatusCallback(testGnssStatusCallback); 163 softAssert.assertTrue("Test case: " + testName +", TTFF should be less than " + threshold 164 + " . In current test, TTFF value is: " + ttffTimeMillis, ttffTimeMillis < threshold); 165 } 166 } 167