1 /* 2 * Copyright (C) 2022 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 17 package android.location.cts.privileged; 18 19 import static org.junit.Assume.assumeTrue; 20 21 import android.Manifest; 22 import android.content.Context; 23 import android.location.GnssMeasurementCorrections; 24 import android.location.GnssSingleSatCorrection; 25 import android.location.GnssStatus; 26 import android.location.Location; 27 import android.location.cts.common.TestGnssStatusCallback; 28 import android.location.cts.common.TestLocationListener; 29 import android.location.cts.common.TestLocationManager; 30 import android.location.cts.common.TestMeasurementUtil; 31 import android.util.Log; 32 33 import androidx.test.core.app.ApplicationProvider; 34 import androidx.test.ext.junit.runners.AndroidJUnit4; 35 import androidx.test.platform.app.InstrumentationRegistry; 36 37 import org.junit.After; 38 import org.junit.Assert; 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.List; 45 46 /** 47 * Tests for {@link GnssMeasurementCorrections} injection. 48 * 49 * This class tests {@link GnssMeasurementCorrections} injection by requesting GNSS locations and 50 * GnssStatus, constructing {@link GnssMeasurementCorrections}, and injecting them via calling 51 * {@link android.location.LocationManager#injectGnssMeasurementCorrections()} API. 52 */ 53 @RunWith(AndroidJUnit4.class) 54 public class GnssMeasurementCorrectionsInjectionTest { 55 56 private static final String TAG = "GnssMeasCorrTest"; 57 private static final int LOCATION_TO_COLLECT_COUNT = 1; 58 private static final int STATUS_TO_COLLECT_COUNT = 3; 59 private TestLocationManager mTestLocationManager; 60 61 @Before setUp()62 public void setUp() throws Exception { 63 Context context = ApplicationProvider.getApplicationContext(); 64 mTestLocationManager = new TestLocationManager(context); 65 InstrumentationRegistry.getInstrumentation() 66 .getUiAutomation() 67 .adoptShellPermissionIdentity(Manifest.permission.LOCATION_HARDWARE); 68 assumeTrue(TestMeasurementUtil.canTestRunOnCurrentDevice(mTestLocationManager, TAG)); 69 assumeTrue( 70 mTestLocationManager.getLocationManager().getGnssCapabilities() 71 .hasMeasurementCorrections()); 72 } 73 74 @After tearDown()75 public void tearDown() throws Exception { 76 InstrumentationRegistry.getInstrumentation() 77 .getUiAutomation() 78 .dropShellPermissionIdentity(); 79 } 80 81 /** 82 * Tests {@link android.location.LocationManager#injectGnssMeasurementCorrections()}. 83 * 84 * Test steps: 85 * 1. Requests and waits for a GNSS location and GnssStatus. 86 * 2. Constructs a {@link GnssMeasurementCorrections} with the received location and GnssStatus 87 * by setting all the satellites as line-of-sight of 1.0 probability. 88 * 3. Injects the constructed {@link GnssMeasurementCorrections} via 89 * {@link android.location.LocationManager#injectGnssMeasurementCorrections()}. 90 */ 91 @Test testInjectGnssMeasurementCorrections()92 public void testInjectGnssMeasurementCorrections() throws InterruptedException { 93 TestGnssStatusCallback testGnssStatusCallback = 94 new TestGnssStatusCallback(TAG, STATUS_TO_COLLECT_COUNT); 95 mTestLocationManager.registerGnssStatusCallback(testGnssStatusCallback); 96 97 TestLocationListener locationListener = new TestLocationListener(LOCATION_TO_COLLECT_COUNT); 98 mTestLocationManager.requestLocationUpdates(locationListener); 99 100 boolean success = testGnssStatusCallback.awaitStatus() && testGnssStatusCallback.awaitTtff() 101 && locationListener.await(); 102 mTestLocationManager.removeLocationUpdates(locationListener); 103 mTestLocationManager.unregisterGnssStatusCallback(testGnssStatusCallback); 104 105 if (success) { 106 Log.i(TAG, "Successfully received " + LOCATION_TO_COLLECT_COUNT 107 + " GNSS locations."); 108 } 109 110 Assert.assertTrue("Time elapsed without getting enough regular GNSS locations." 111 + " Possibly, the test has been run deep indoors." 112 + " Consider retrying test outdoors.", success); 113 114 GnssStatus gnssStatus = testGnssStatusCallback.getGnssStatus(); 115 List<GnssSingleSatCorrection> singleSatCorrectionList = getGnssSingleSatCorrectionList( 116 gnssStatus); 117 118 List<Location> locations = locationListener.getReceivedLocationList(); 119 Log.i(TAG, "Received location list size = " + locations.size()); 120 Assert.assertTrue("Received location list must be non-empty.", locations.size() > 0); 121 for (Location location : locations) { 122 GnssMeasurementCorrections corrections = new GnssMeasurementCorrections.Builder() 123 .setLatitudeDegrees(location.getLatitude()) 124 .setLongitudeDegrees(location.getLongitude()) 125 .setAltitudeMeters(location.getAltitude()) 126 .setSingleSatelliteCorrectionList(singleSatCorrectionList) 127 .build(); 128 mTestLocationManager.getLocationManager().injectGnssMeasurementCorrections(corrections); 129 } 130 } 131 getGnssSingleSatCorrectionList( GnssStatus gnssStatus)132 private static List<GnssSingleSatCorrection> getGnssSingleSatCorrectionList( 133 GnssStatus gnssStatus) { 134 List<GnssSingleSatCorrection> list = new ArrayList<>(gnssStatus.getSatelliteCount()); 135 for (int i = 0; i < gnssStatus.getSatelliteCount(); i++) { 136 GnssSingleSatCorrection correction = new GnssSingleSatCorrection.Builder() 137 .setConstellationType(gnssStatus.getConstellationType(i)) 138 .setCarrierFrequencyHz(gnssStatus.getCarrierFrequencyHz(i)) 139 .setSatelliteId(gnssStatus.getSvid(i)) 140 .setProbabilityLineOfSight(1.0f) // assume all satellites are in line-of-sight 141 .build(); 142 list.add(correction); 143 } 144 return list; 145 } 146 } 147