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