• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2015 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;
18 
19 import junit.framework.TestCase;
20 
21 import android.test.suitebuilder.annotation.SmallTest;
22 
23 import java.lang.reflect.Constructor;
24 import java.lang.reflect.Method;
25 import java.util.HashSet;
26 import java.util.Iterator;
27 import java.util.Random;
28 import java.util.Set;
29 
30 /**
31  * Unit tests for {@link GpsStatus}.
32  */
33 @SmallTest
34 public class GpsStatusTest extends TestCase {
35 
36     private static final int MAX_VALUE = 250;
37 
38     private final Random mRandom = new Random();
39 
40     private GpsStatus mStatus;
41     private int mCount;
42     private int[] mPrns;
43     private float[] mCn0s;
44     private float[] mElevations;
45     private float[] mAzimuth;
46     private int mEphemerisMask;
47     private int mAlmanacMask;
48     private int mUsedInFixMask;
49 
setUp()50     public void setUp() throws Exception {
51         super.setUp();
52         mStatus = createGpsStatus();
53         generateSatellitesData(generateInt());
54     }
55 
testEmptyGpsStatus()56     public void testEmptyGpsStatus() throws Exception {
57         verifyIsEmpty(mStatus);
58     }
59 
testGpsStatusIterator()60     public void testGpsStatusIterator() throws Exception {
61         generateSatellitesData(2);
62         setSatellites(mStatus);
63         Iterator<GpsSatellite> iterator = mStatus.getSatellites().iterator();
64         assertTrue("hasNext(1)", iterator.hasNext());
65         assertTrue("hasNext(1) does not overflow", iterator.hasNext());
66         GpsSatellite satellite1 = iterator.next();
67         assertNotNull("satellite", satellite1);
68         assertTrue("hasNext(2)", iterator.hasNext());
69         assertTrue("hasNext(2) does not overflow", iterator.hasNext());
70         GpsSatellite satellite2 = iterator.next();
71         assertNotNull("satellite", satellite2);
72         assertFalse("hasNext() no elements", iterator.hasNext());
73     }
74 
testTtff()75     public void testTtff() throws Exception {
76         int testTtff = generateInt();
77         set(mStatus, testTtff);
78         verifyTtff(mStatus, testTtff);
79     }
80 
testCopyTtff()81     public void testCopyTtff() throws Exception {
82         int testTtff = generateInt();
83         verifyTtff(mStatus, 0);
84 
85         GpsStatus otherStatus = createGpsStatus();
86         set(otherStatus, testTtff);
87         verifyTtff(otherStatus, testTtff);
88 
89         set(mStatus, otherStatus);
90         verifyTtff(mStatus, testTtff);
91     }
92 
testSetSatellites()93     public void testSetSatellites() throws Exception {
94         setSatellites(mStatus);
95         verifySatellites(mStatus);
96     }
97 
testCopySatellites()98     public void testCopySatellites() throws Exception {
99         verifyIsEmpty(mStatus);
100 
101         GpsStatus otherStatus = createGpsStatus();
102         setSatellites(otherStatus);
103         verifySatellites(otherStatus);
104 
105         set(mStatus, otherStatus);
106         verifySatellites(mStatus);
107     }
108 
testOverrideSatellites()109     public void testOverrideSatellites() throws Exception {
110         setSatellites(mStatus);
111         verifySatellites(mStatus);
112 
113         GpsStatus otherStatus = createGpsStatus();
114         generateSatellitesData(mCount, true /* reusePrns */);
115         setSatellites(otherStatus);
116         verifySatellites(otherStatus);
117 
118         set(mStatus, otherStatus);
119         verifySatellites(mStatus);
120     }
121 
testAddSatellites()122     public void testAddSatellites() throws Exception {
123         int count = 10;
124         generateSatellitesData(count);
125         setSatellites(mStatus);
126         verifySatellites(mStatus);
127 
128         GpsStatus otherStatus = createGpsStatus();
129         generateSatellitesData(count);
130         setSatellites(otherStatus);
131         verifySatellites(otherStatus);
132 
133         set(mStatus, otherStatus);
134         verifySatellites(mStatus);
135     }
136 
testAddMoreSatellites()137     public void testAddMoreSatellites() throws Exception {
138         int count = 25;
139         generateSatellitesData(count);
140         setSatellites(mStatus);
141         verifySatellites(mStatus);
142 
143         GpsStatus otherStatus = createGpsStatus();
144         generateSatellitesData(count * 2);
145         setSatellites(otherStatus);
146         verifySatellites(otherStatus);
147 
148         set(mStatus, otherStatus);
149         verifySatellites(mStatus);
150     }
151 
testAddLessSatellites()152     public void testAddLessSatellites() throws Exception {
153         int count = 25;
154         generateSatellitesData(count * 2);
155         setSatellites(mStatus);
156         verifySatellites(mStatus);
157 
158         GpsStatus otherStatus = createGpsStatus();
159         generateSatellitesData(count);
160         setSatellites(otherStatus);
161         verifySatellites(otherStatus);
162 
163         set(mStatus, otherStatus);
164         verifySatellites(mStatus);
165     }
166 
verifyIsEmpty(GpsStatus status)167     private static void verifyIsEmpty(GpsStatus status) {
168         verifySatelliteCount(status, 0);
169         verifyTtff(status, 0);
170     }
171 
verifySatelliteCount(GpsStatus status, int expectedCount)172     private static void verifySatelliteCount(GpsStatus status, int expectedCount) {
173         int satellites = 0;
174         for (GpsSatellite s : status.getSatellites()) {
175             ++satellites;
176         }
177         assertEquals("GpsStatus::SatelliteCount", expectedCount, satellites);
178     }
179 
verifySatellites(GpsStatus status)180     private void verifySatellites(GpsStatus status) {
181         verifySatelliteCount(status, mCount);
182         verifySatellites(status, mCount, mPrns, mCn0s, mElevations, mAzimuth, mEphemerisMask,
183                 mAlmanacMask, mUsedInFixMask);
184     }
185 
verifySatellites( GpsStatus status, int count, int[] prns, float[] cn0s, float[] elevations, float[] azimuth, int ephemerisMask, int almanacMask, int usedInFixMask)186     private static void verifySatellites(
187             GpsStatus status,
188             int count,
189             int[] prns,
190             float[] cn0s,
191             float[] elevations,
192             float[] azimuth,
193             int ephemerisMask,
194             int almanacMask,
195             int usedInFixMask) {
196         for (int i = 0; i < count; ++i) {
197             int prn = prns[i];
198             GpsSatellite satellite = getSatellite(status, prn);
199             assertNotNull(getSatelliteAssertInfo(i, prn, "non-null"), satellite);
200             assertEquals(getSatelliteAssertInfo(i, prn, "Snr"), cn0s[i], satellite.getSnr());
201             assertEquals(
202                     getSatelliteAssertInfo(i, prn, "Elevation"),
203                     elevations[i],
204                     satellite.getElevation());
205             assertEquals(
206                     getSatelliteAssertInfo(i, prn, "Azimuth"),
207                     azimuth[i],
208                     satellite.getAzimuth());
209             int prnShift = 1 << (prn - 1);
210             assertEquals(
211                     getSatelliteAssertInfo(i, prn, "ephemeris"),
212                     (ephemerisMask & prnShift) != 0,
213                     satellite.hasEphemeris());
214             assertEquals(
215                     getSatelliteAssertInfo(i, prn, "almanac"),
216                     (almanacMask & prnShift) != 0,
217                     satellite.hasAlmanac());
218             assertEquals(
219                     getSatelliteAssertInfo(i, prn, "usedInFix"),
220                     (usedInFixMask & prnShift) != 0,
221                     satellite.usedInFix());
222         }
223     }
224 
verifyTtff(GpsStatus status, int expectedTtff)225     private static void verifyTtff(GpsStatus status, int expectedTtff) {
226         assertEquals("GpsStatus::TTFF", expectedTtff, status.getTimeToFirstFix());
227     }
228 
createGpsStatus()229     private static GpsStatus createGpsStatus() throws Exception {
230         Constructor<GpsStatus>  ctor = GpsStatus.class.getDeclaredConstructor();
231         ctor.setAccessible(true);
232         return ctor.newInstance();
233     }
234 
set(GpsStatus status, int ttff)235     private static void set(GpsStatus status, int ttff) throws Exception {
236         Class<?> statusClass = status.getClass();
237         Method setTtff = statusClass.getDeclaredMethod("setTimeToFirstFix", Integer.TYPE);
238         setTtff.setAccessible(true);
239         setTtff.invoke(status, ttff);
240     }
241 
set(GpsStatus status, GpsStatus statusToSet)242     private static void set(GpsStatus status, GpsStatus statusToSet) throws Exception {
243         Class<?> statusClass = status.getClass();
244         Method setStatus = statusClass.getDeclaredMethod("setStatus", statusClass);
245         setStatus.setAccessible(true);
246         setStatus.invoke(status, statusToSet);
247     }
248 
setSatellites(GpsStatus status)249     private void setSatellites(GpsStatus status) throws Exception {
250         set(status, mCount, mPrns, mCn0s, mElevations, mAzimuth, mEphemerisMask, mAlmanacMask,
251                 mUsedInFixMask);
252     }
253 
set( GpsStatus status, int count, int[] prns, float[] cn0s, float[] elevations, float[] azimuth, int ephemerisMask, int almanacMask, int usedInFixMask)254     private static void set(
255             GpsStatus status,
256             int count,
257             int[] prns,
258             float[] cn0s,
259             float[] elevations,
260             float[] azimuth,
261             int ephemerisMask,
262             int almanacMask,
263             int usedInFixMask) throws Exception {
264         Class<?> statusClass = status.getClass();
265         Class<?> intClass = Integer.TYPE;
266         Class<?> floatArrayClass = Class.forName("[F");
267         Method setStatus = statusClass.getDeclaredMethod(
268                 "setStatus",
269                 intClass,
270                 Class.forName("[I"),
271                 floatArrayClass,
272                 floatArrayClass,
273                 floatArrayClass,
274                 intClass,
275                 intClass,
276                 intClass);
277         setStatus.setAccessible(true);
278         setStatus.invoke(
279                 status,
280                 count,
281                 prns,
282                 cn0s,
283                 elevations,
284                 azimuth,
285                 ephemerisMask,
286                 almanacMask,
287                 usedInFixMask);
288     }
289 
generateInt()290     private int generateInt() {
291         return mRandom.nextInt(MAX_VALUE) + 1;
292     }
293 
generateIntArray(int count)294     private int[] generateIntArray(int count) {
295         Set<Integer> generatedPrns = new HashSet<>();
296         int[] array = new int[count];
297         for(int i = 0; i < count; ++i) {
298             int generated;
299             do {
300                 generated = generateInt();
301             } while (generatedPrns.contains(generated));
302             array[i] = generated;
303             generatedPrns.add(generated);
304         }
305         return array;
306     }
307 
generateFloatArray(int count)308     private float[] generateFloatArray(int count) {
309         float[] array = new float[count];
310         for(int i = 0; i < count; ++i) {
311             array[i] = generateInt();
312         }
313         return array;
314     }
315 
generateMask(int[] prns)316     private int generateMask(int[] prns) {
317         int mask = 0;
318         int prnsLength = prns.length;
319         for (int i = 0; i < prnsLength; ++i) {
320             if (mRandom.nextBoolean()) {
321                 mask |= 1 << (prns[i] - 1);
322             }
323         }
324         return mask;
325     }
326 
generateSatellitesData(int count)327     private void generateSatellitesData(int count) {
328         generateSatellitesData(count, false /* reusePrns */);
329     }
330 
generateSatellitesData(int count, boolean reusePrns)331     private void generateSatellitesData(int count, boolean reusePrns) {
332         mCount = count;
333         if (!reusePrns) {
334             mPrns = generateIntArray(count);
335         }
336         mCn0s = generateFloatArray(count);
337         mElevations = generateFloatArray(count);
338         mAzimuth = generateFloatArray(count);
339         mEphemerisMask = generateMask(mPrns);
340         mAlmanacMask = generateMask(mPrns);
341         mUsedInFixMask = generateMask(mPrns);
342     }
343 
getSatellite(GpsStatus status, int prn)344     private static GpsSatellite getSatellite(GpsStatus status, int prn) {
345         for (GpsSatellite satellite : status.getSatellites()) {
346             if (satellite.getPrn() == prn) {
347                 return satellite;
348             }
349         }
350         return null;
351     }
352 
getSatelliteAssertInfo(int index, int prn, String param)353     private static String getSatelliteAssertInfo(int index, int prn, String param) {
354         return String.format("Satellite::%s [i=%d, prn=%d]", param, index, prn);
355     }
356 }
357