|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 package com.nokia.mj.test.lapi; |
|
18 |
|
19 import j2meunit.framework.*; |
|
20 import javax.microedition.location.*; |
|
21 |
|
22 public class PeriodicUpdateTest extends TestCase implements LocationListener |
|
23 { |
|
24 final static int ONLY_STATUS_INTERVAL = 0; |
|
25 |
|
26 final static int DEFAULT_INTERVAL = -1; |
|
27 |
|
28 final static int INTERVAL = 10; |
|
29 |
|
30 final static int TIMEOUT = 3; |
|
31 |
|
32 final static int MAXAGE = 2; |
|
33 |
|
34 final static int LARGE_TIMEOUT = 12; |
|
35 |
|
36 final static int LARGE_MAXAGE = 11; |
|
37 |
|
38 final static int[] badInterval = new int[] { -2, -12345, Integer.MIN_VALUE }; |
|
39 |
|
40 final static int[] badTimeout = new int[] { 0, -2, -12345, |
|
41 Integer.MIN_VALUE |
|
42 }; |
|
43 |
|
44 final static int[] badMaxAge = badTimeout; |
|
45 |
|
46 private Coordinates currentCoords; |
|
47 |
|
48 private Location[] iLocations; |
|
49 |
|
50 private int iNumUpdates; |
|
51 |
|
52 private long[] iLocUpdateCallbackTime; |
|
53 |
|
54 final static int TIMETOFIX = 5; |
|
55 |
|
56 protected LocationProvider iLP = null; |
|
57 |
|
58 long[] iTimeArray; |
|
59 |
|
60 public PeriodicUpdateTest() |
|
61 { |
|
62 } |
|
63 |
|
64 public PeriodicUpdateTest(String sTestName, TestMethod rTestMethod) |
|
65 { |
|
66 super(sTestName, rTestMethod); |
|
67 } |
|
68 |
|
69 /*************************************************************************** |
|
70 * Creates the test suite. You need to add a new aSuite.addTest antry for |
|
71 * any new test methods, otherwise they won't be run. |
|
72 */ |
|
73 public Test suite() |
|
74 { |
|
75 TestSuite aSuite = new TestSuite(); |
|
76 |
|
77 aSuite.addTest(new PeriodicUpdateTest("testBadArguments", |
|
78 new TestMethod() |
|
79 { |
|
80 public void run(TestCase tc) |
|
81 { |
|
82 ((PeriodicUpdateTest) tc).testBadArguments(); |
|
83 } |
|
84 })); |
|
85 |
|
86 aSuite.addTest(new PeriodicUpdateTest("testGoodArguments", |
|
87 new TestMethod() |
|
88 { |
|
89 public void run(TestCase tc) |
|
90 { |
|
91 ((PeriodicUpdateTest) tc).testGoodArguments(); |
|
92 } |
|
93 })); |
|
94 |
|
95 aSuite.addTest(new PeriodicUpdateTest("testLocationListenerDefault", |
|
96 new TestMethod() |
|
97 { |
|
98 public void run(TestCase tc) |
|
99 { |
|
100 ((PeriodicUpdateTest) tc).testLocationListenerDefault(); |
|
101 } |
|
102 })); |
|
103 |
|
104 aSuite.addTest(new PeriodicUpdateTest( |
|
105 "testLocationListenerInterval_1s", new TestMethod() |
|
106 { |
|
107 public void run(TestCase tc) |
|
108 { |
|
109 ((PeriodicUpdateTest) tc) |
|
110 .testLocationListenerInterval_1s(); |
|
111 } |
|
112 })); |
|
113 |
|
114 aSuite.addTest(new PeriodicUpdateTest( |
|
115 "testLocationListenerInterval_3s", new TestMethod() |
|
116 { |
|
117 public void run(TestCase tc) |
|
118 { |
|
119 ((PeriodicUpdateTest) tc) |
|
120 .testLocationListenerInterval_3s(); |
|
121 } |
|
122 })); |
|
123 |
|
124 aSuite.addTest(new PeriodicUpdateTest( |
|
125 "testLocationListenerInterval_7s", new TestMethod() |
|
126 { |
|
127 public void run(TestCase tc) |
|
128 { |
|
129 ((PeriodicUpdateTest) tc) |
|
130 .testLocationListenerInterval_7s(); |
|
131 } |
|
132 })); |
|
133 |
|
134 aSuite.addTest(new PeriodicUpdateTest("testChangeListener", |
|
135 new TestMethod() |
|
136 { |
|
137 public void run(TestCase tc) |
|
138 { |
|
139 ((PeriodicUpdateTest) tc).testChangeListener(); |
|
140 } |
|
141 })); |
|
142 |
|
143 return aSuite; |
|
144 |
|
145 } |
|
146 |
|
147 private void assertContinue(String aReason, boolean aCond) |
|
148 { |
|
149 if (!aCond) |
|
150 assertTrue(aReason, false); |
|
151 } |
|
152 |
|
153 public void testBadArguments() |
|
154 { |
|
155 providerSetUp(null); |
|
156 assertContinue("LocationProvider is null", iLP != null); |
|
157 |
|
158 assertBad(INTERVAL, TIMEOUT, LARGE_MAXAGE); // MaxAge > Interval |
|
159 assertBad(INTERVAL, LARGE_TIMEOUT, MAXAGE); // Timeout > Interval |
|
160 assertBad(INTERVAL, LARGE_TIMEOUT, LARGE_MAXAGE); |
|
161 |
|
162 for (int i = 0; i < badInterval.length; ++i) |
|
163 { |
|
164 assertBad(badInterval[i], TIMEOUT, MAXAGE); |
|
165 } |
|
166 |
|
167 for (int i = 0; i < badTimeout.length; ++i) |
|
168 { |
|
169 assertBad(INTERVAL, badTimeout[i], MAXAGE); |
|
170 assertBad(INTERVAL, badTimeout[i], LARGE_MAXAGE); |
|
171 } |
|
172 |
|
173 for (int i = 0; i < badMaxAge.length; ++i) |
|
174 { |
|
175 assertBad(INTERVAL, TIMEOUT, badMaxAge[i]); |
|
176 assertBad(INTERVAL, LARGE_TIMEOUT, badMaxAge[i]); |
|
177 } |
|
178 |
|
179 for (int i = 0; i < badInterval.length; ++i) |
|
180 { |
|
181 for (int j = 0; j < badTimeout.length; ++j) |
|
182 { |
|
183 for (int k = 0; k < badMaxAge.length; ++k) |
|
184 { |
|
185 assertBad(badInterval[i], badTimeout[j], badMaxAge[k]); |
|
186 } |
|
187 } |
|
188 } |
|
189 assertTrue("", true); |
|
190 } |
|
191 |
|
192 public void testGoodArguments() |
|
193 { |
|
194 providerSetUp(null); |
|
195 assertContinue("LocationProvider is null", iLP != null); |
|
196 |
|
197 // These arguments should not throw exceptions |
|
198 testGoodWithBad(this, DEFAULT_INTERVAL); |
|
199 testGoodWithBad(this, ONLY_STATUS_INTERVAL); |
|
200 |
|
201 testGoodWithBad(null, INTERVAL); |
|
202 testGoodWithBad(null, DEFAULT_INTERVAL); |
|
203 testGoodWithBad(null, ONLY_STATUS_INTERVAL); |
|
204 |
|
205 for (int i = 0; i < badInterval.length; ++i) |
|
206 { |
|
207 testGoodWithBad(null, badInterval[i]); |
|
208 } |
|
209 |
|
210 int bigValue = Integer.MAX_VALUE / 1000000; |
|
211 assertGood(this, bigValue, bigValue, bigValue); |
|
212 |
|
213 assertGood(this, Integer.MAX_VALUE, Integer.MAX_VALUE, |
|
214 Integer.MAX_VALUE); |
|
215 |
|
216 assertTrue("", true); |
|
217 } |
|
218 |
|
219 public void testLocationListenerDefault() |
|
220 { |
|
221 final int MAXTIME = 1000 * (TIMETOFIX + 13 + 1); // Interval ~ 6.25 |
|
222 |
|
223 providerSetUp(null); // Simulation PSY should be default |
|
224 assertContinue("LocationProvider is null", iLP != null); |
|
225 |
|
226 // Start listening for location changes |
|
227 iLP.setLocationListener(this, -1, -1, -1); |
|
228 |
|
229 getUpdates(2, MAXTIME); |
|
230 |
|
231 checkLocationData(iLocations[0]); |
|
232 checkLocationData(iLocations[1]); |
|
233 |
|
234 iLocations = null; |
|
235 assertTrue("", true); |
|
236 } |
|
237 |
|
238 public void testLocationListenerInterval_1s() |
|
239 { |
|
240 testInterval(1, 4); |
|
241 assertTrue("", true); |
|
242 } |
|
243 |
|
244 public void testLocationListenerInterval_3s() |
|
245 { |
|
246 testInterval(3, 5); |
|
247 assertTrue("", true); |
|
248 } |
|
249 |
|
250 public void testLocationListenerInterval_7s() |
|
251 { |
|
252 testInterval(7, 3); |
|
253 assertTrue("", true); |
|
254 } |
|
255 |
|
256 public void testChangeListener() |
|
257 { |
|
258 providerSetUp(null); |
|
259 assertContinue("LocationProvider is null", iLP != null); |
|
260 |
|
261 final int PERIOD1 = 10; // seconds |
|
262 final int PERIOD2 = 7; // seconds |
|
263 |
|
264 LocationListener listener = new LocationListener() |
|
265 { |
|
266 public void providerStateChanged(LocationProvider lp, int s) |
|
267 { |
|
268 } |
|
269 |
|
270 public void locationUpdated(LocationProvider lp, Location l) |
|
271 { |
|
272 } |
|
273 }; |
|
274 |
|
275 // Change interval |
|
276 iLP.setLocationListener(this, PERIOD1, -1, -1); |
|
277 int maxtime = 1000 * (2 * PERIOD1 + TIMETOFIX); |
|
278 getUpdates(2, maxtime); |
|
279 |
|
280 iLP.setLocationListener(this, PERIOD2, -1, -1); |
|
281 maxtime = 1000 * (2 * PERIOD2 + TIMETOFIX); |
|
282 getUpdates(2, maxtime); |
|
283 |
|
284 // Change listener |
|
285 iLP.setLocationListener(listener, -1, -1, -1); |
|
286 |
|
287 try |
|
288 { |
|
289 if (iLP != null) |
|
290 iLP.setLocationListener(null, -1, -1, -1); |
|
291 } |
|
292 catch (Exception e) |
|
293 { |
|
294 } |
|
295 assertTrue("", true); |
|
296 } |
|
297 |
|
298 public void providerStateChanged(LocationProvider l, int event) |
|
299 { |
|
300 } |
|
301 |
|
302 public void locationUpdated(LocationProvider l, Location fix) |
|
303 { |
|
304 iLocUpdateCallbackTime[iNumUpdates] = System.currentTimeMillis(); |
|
305 |
|
306 iLocations[iNumUpdates] = fix; |
|
307 ++iNumUpdates; |
|
308 assertContinue("LocationProvider is null", l != null); |
|
309 } |
|
310 |
|
311 // ------------------------ Helper methods ----------------------- |
|
312 |
|
313 private void assertBad(int aInterval, int aTimeout, int aMaxAge) |
|
314 { |
|
315 try |
|
316 { |
|
317 iLP.setLocationListener(this, aInterval, aTimeout, aMaxAge); |
|
318 // Oops, no exception thrown, remove listener |
|
319 iLP.setLocationListener(null, -1, -1, -1); |
|
320 assertContinue("Bad arguments should throw exception: " + aInterval |
|
321 + "," + aTimeout + "," + aMaxAge, false); |
|
322 } |
|
323 catch (IllegalArgumentException iae) |
|
324 { |
|
325 // OK |
|
326 assertContinue("no message allowed for the exception: " + iae, iae |
|
327 .getMessage() == null); |
|
328 } |
|
329 catch (Exception e) |
|
330 { |
|
331 assertContinue("Unknown error: " + e, false); |
|
332 } |
|
333 } |
|
334 |
|
335 private void testGoodWithBad(LocationListener aListener, int aInterval) |
|
336 { |
|
337 assertGood(aListener, aInterval, LARGE_TIMEOUT, LARGE_MAXAGE); |
|
338 |
|
339 for (int i = 0; i < badTimeout.length; ++i) |
|
340 { |
|
341 assertGood(aListener, aInterval, badTimeout[i], LARGE_MAXAGE); |
|
342 } |
|
343 |
|
344 for (int i = 0; i < badMaxAge.length; ++i) |
|
345 { |
|
346 assertGood(aListener, aInterval, LARGE_TIMEOUT, badMaxAge[i]); |
|
347 } |
|
348 |
|
349 for (int j = 0; j < badTimeout.length; ++j) |
|
350 { |
|
351 for (int k = 0; k < badMaxAge.length; ++k) |
|
352 { |
|
353 assertGood(aListener, aInterval, badTimeout[j], badMaxAge[k]); |
|
354 } |
|
355 } |
|
356 } |
|
357 |
|
358 private void assertGood(LocationListener aListener, int aInterval, |
|
359 int aTimeout, int aMaxAge) |
|
360 { |
|
361 try |
|
362 { |
|
363 iLP.setLocationListener(aListener, aInterval, aTimeout, aMaxAge); |
|
364 } |
|
365 catch (IllegalArgumentException iae) |
|
366 { |
|
367 assertContinue("setLocationListener(" + aListener + "," + aInterval |
|
368 + "," + aTimeout + "," + aMaxAge + ") threw exception:\n" |
|
369 + iae, false); |
|
370 } |
|
371 |
|
372 // remove listener |
|
373 try |
|
374 { |
|
375 if (iLP != null) |
|
376 iLP.setLocationListener(null, -1, -1, -1); |
|
377 } |
|
378 catch (Exception e) |
|
379 { |
|
380 } |
|
381 } |
|
382 |
|
383 private void testInterval(int aInterval, int aNumberOfFixes) |
|
384 { |
|
385 assertContinue("Must test with at least one fix!", aNumberOfFixes > 0); |
|
386 |
|
387 final int TIMETOFIX = 100; // 100 ms |
|
388 final int TIMEOUT = 1000 + 2 * TIMETOFIX; |
|
389 final int MAXTIME = 1000 * (aNumberOfFixes * aInterval) + TIMEOUT; |
|
390 |
|
391 Criteria criteria = new Criteria(); |
|
392 criteria.setPreferredResponseTime(TIMETOFIX); |
|
393 |
|
394 providerSetUp(criteria); |
|
395 assertContinue("LocationProvider is null", iLP != null); |
|
396 |
|
397 // Start listening for location changes |
|
398 iLP.setLocationListener(this, aInterval, -1, -1); |
|
399 |
|
400 getUpdates(aNumberOfFixes, MAXTIME); |
|
401 |
|
402 checkLocationData(iLocations[0]); |
|
403 // Fixes at interval starts after first fix |
|
404 long startTime = iLocUpdateCallbackTime[0]; |
|
405 long lastTimeOfFix = startTime; |
|
406 |
|
407 for (int i = 1; i < aNumberOfFixes; ++i) |
|
408 { |
|
409 checkLocationData(iLocations[i]); |
|
410 long timeOfFix = iLocUpdateCallbackTime[i]; |
|
411 long timeDiff = timeOfFix - lastTimeOfFix; |
|
412 assertContinue("Period difference is less than allowed for fix" + i |
|
413 + ": " + timeDiff, timeDiff > (aInterval - TIMEOUT) * 1000); |
|
414 assertContinue("Period difference is more than allowed for fix" + i |
|
415 + ": " + timeDiff, timeDiff < (aInterval + TIMEOUT) * 1000); |
|
416 assertContinue("Timestamp too late for fix" + i, |
|
417 (timeOfFix - startTime) < ((i + 1) * aInterval * 1000)); |
|
418 lastTimeOfFix = timeOfFix; |
|
419 } |
|
420 iLocations = null; |
|
421 } |
|
422 |
|
423 private void getUpdates(int aNumUpdates, int aTimeout) |
|
424 { |
|
425 iLocations = new Location[aNumUpdates]; |
|
426 iLocUpdateCallbackTime = new long[aNumUpdates]; |
|
427 iNumUpdates = 0; |
|
428 |
|
429 // Wait for the first result or timeout |
|
430 boolean timeout = false; |
|
431 long startTime = System.currentTimeMillis(); |
|
432 while (iNumUpdates < aNumUpdates) |
|
433 { |
|
434 // Wait a moment before checking things |
|
435 try |
|
436 { |
|
437 Thread.sleep(250); |
|
438 } |
|
439 catch (InterruptedException ie) |
|
440 { |
|
441 } |
|
442 |
|
443 // Use a safeguard timeout in case the updating thread hangs |
|
444 // or takes too long |
|
445 if (System.currentTimeMillis() - startTime > aTimeout) |
|
446 { |
|
447 timeout = true; |
|
448 break; |
|
449 } |
|
450 } |
|
451 |
|
452 try |
|
453 { |
|
454 if (iLP != null) |
|
455 iLP.setLocationListener(null, -1, -1, -1); |
|
456 } |
|
457 catch (Exception e) |
|
458 { |
|
459 } |
|
460 |
|
461 assertContinue("Got a timeout", !timeout); |
|
462 } |
|
463 |
|
464 protected void providerSetUp(Criteria aCriteria) |
|
465 { |
|
466 iLP = null; |
|
467 try |
|
468 { |
|
469 iLP = LocationProvider.getInstance(aCriteria); |
|
470 if (iLP != null) |
|
471 { |
|
472 int state = iLP.getState(); |
|
473 assertContinue("Initial state=" + state |
|
474 + ", expected AVAILABLE", |
|
475 state == LocationProvider.AVAILABLE); |
|
476 } |
|
477 } |
|
478 catch (LocationException le) |
|
479 { |
|
480 } |
|
481 } |
|
482 |
|
483 protected void checkLocationData(Location aLoc) |
|
484 { |
|
485 assertContinue("Location is null", aLoc != null); |
|
486 assertContinue("Location is invalid", aLoc.isValid()); |
|
487 assertContinue("Location is valid, but Coordinates are null", aLoc |
|
488 .getQualifiedCoordinates() != null); |
|
489 |
|
490 long timestamp = aLoc.getTimestamp(); |
|
491 long now = System.currentTimeMillis(); |
|
492 assertContinue("Timestamp incorrect: t=" + timestamp + ", now=" + now, |
|
493 now >= timestamp && (now - timestamp < 30000) && timestamp > 0); |
|
494 |
|
495 QualifiedCoordinates coords = aLoc.getQualifiedCoordinates(); |
|
496 double lat = coords.getLatitude(); |
|
497 double lon = coords.getLongitude(); |
|
498 |
|
499 assertContinue("Latitude out of range", lat >= -90.0 || lat <= 90.0); |
|
500 assertContinue("Longitude out of range", lon >= -180.0 || lon < 180.0); |
|
501 |
|
502 float hacc = coords.getHorizontalAccuracy(); |
|
503 assertContinue("Horizontal accuracy is negative", Float.isNaN(hacc) |
|
504 || hacc >= 0); |
|
505 |
|
506 float vacc = coords.getVerticalAccuracy(); |
|
507 assertContinue("Vertical accuracy is negative", Float.isNaN(vacc) |
|
508 || vacc >= 0); |
|
509 |
|
510 float speed = aLoc.getSpeed(); |
|
511 assertContinue("Speed is negative", Float.isNaN(speed) || speed >= 0); |
|
512 |
|
513 float course = aLoc.getCourse(); |
|
514 assertContinue("Course out of range", Float.isNaN(course) |
|
515 || (course >= 0 && course < 360)); |
|
516 |
|
517 String nmea = aLoc.getExtraInfo("application/X-jsr179-location-nmea"); |
|
518 if (nmea != null) |
|
519 { |
|
520 assertTrue("Bad NMEA data", nmea.startsWith("$GP")); |
|
521 } |
|
522 } |
|
523 } |
|
524 |
|
525 // End of file |