1 /*
2  * Copyright (C) 2008 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;
18 
19 import android.content.Context;
20 import android.content.Intent;
21 import android.location.Location;
22 import android.location.SettingInjectorService;
23 import android.os.Handler;
24 import android.os.IBinder;
25 import android.os.Looper;
26 import android.os.Message;
27 import android.os.Messenger;
28 import android.os.Bundle;
29 import android.os.Parcel;
30 import android.test.AndroidTestCase;
31 import android.util.Printer;
32 import android.util.StringBuilderPrinter;
33 
34 import java.text.DecimalFormat;
35 
36 public class LocationTest extends AndroidTestCase {
37     private static final float DELTA = 0.1f;
38     private final float TEST_ACCURACY = 1.0f;
39     private final float TEST_VERTICAL_ACCURACY = 2.0f;
40     private final float TEST_SPEED_ACCURACY = 3.0f;
41     private final float TEST_BEARING_ACCURACY = 4.0f;
42     private final double TEST_ALTITUDE = 1.0;
43     private final double TEST_LATITUDE = 50;
44     private final float TEST_BEARING = 1.0f;
45     private final double TEST_LONGITUDE = 20;
46     private final float TEST_SPEED = 5.0f;
47     private final long TEST_TIME = 100;
48     private final String TEST_PROVIDER = "LocationProvider";
49     private final String TEST_KEY1NAME = "key1";
50     private final String TEST_KEY2NAME = "key2";
51     private final boolean TEST_KEY1VALUE = false;
52     private final byte TEST_KEY2VALUE = 10;
53 
54     private static final String ENABLED_KEY = "enabled";
55     private static final String MESSENGER_KEY = "messenger";
56 
57 
testConstructor()58     public void testConstructor() {
59         new Location("LocationProvider");
60 
61         Location l = createTestLocation();
62         Location location = new Location(l);
63         assertTestLocation(location);
64 
65         try {
66             new Location((Location) null);
67             fail("should throw NullPointerException");
68         } catch (NullPointerException e) {
69             // expected.
70         }
71     }
72 
testDump()73     public void testDump() {
74         StringBuilder sb = new StringBuilder();
75         StringBuilderPrinter printer = new StringBuilderPrinter(sb);
76         Location location = new Location("LocationProvider");
77         location.dump(printer, "");
78         assertNotNull(sb.toString());
79     }
80 
testBearingTo()81     public void testBearingTo() {
82         Location location = new Location("");
83         Location dest = new Location("");
84 
85         // set the location to Beijing
86         location.setLatitude(39.9);
87         location.setLongitude(116.4);
88         // set the destination to Chengdu
89         dest.setLatitude(30.7);
90         dest.setLongitude(104.1);
91         assertEquals(-128.66, location.bearingTo(dest), DELTA);
92 
93         float bearing;
94         Location zeroLocation = new Location("");
95         zeroLocation.setLatitude(0);
96         zeroLocation.setLongitude(0);
97 
98         Location testLocation = new Location("");
99         testLocation.setLatitude(0);
100         testLocation.setLongitude(150);
101 
102         bearing = zeroLocation.bearingTo(zeroLocation);
103         assertEquals(0.0f, bearing, DELTA);
104 
105         bearing = zeroLocation.bearingTo(testLocation);
106         assertEquals(90.0f, bearing, DELTA);
107 
108         testLocation.setLatitude(90);
109         testLocation.setLongitude(0);
110         bearing = zeroLocation.bearingTo(testLocation);
111         assertEquals(0.0f, bearing, DELTA);
112 
113         try {
114             location.bearingTo(null);
115             fail("should throw NullPointerException");
116         } catch (NullPointerException e) {
117             // expected.
118         }
119     }
120 
testConvert_CoordinateToRepresentation()121     public void testConvert_CoordinateToRepresentation() {
122         DecimalFormat df = new DecimalFormat("###.#####");
123         String result;
124 
125         result = Location.convert(-80.0, Location.FORMAT_DEGREES);
126         assertEquals("-" + df.format(80.0), result);
127 
128         result = Location.convert(-80.085, Location.FORMAT_MINUTES);
129         assertEquals("-80:" + df.format(5.1), result);
130 
131         result = Location.convert(-80, Location.FORMAT_MINUTES);
132         assertEquals("-80:" + df.format(0), result);
133 
134         result = Location.convert(-80.075, Location.FORMAT_MINUTES);
135         assertEquals("-80:" + df.format(4.5), result);
136 
137         result = Location.convert(-80.075, Location.FORMAT_DEGREES);
138         assertEquals("-" + df.format(80.075), result);
139 
140         result = Location.convert(-80.075, Location.FORMAT_SECONDS);
141         assertEquals("-80:4:30", result);
142 
143         try {
144             Location.convert(-181, Location.FORMAT_SECONDS);
145             fail("should throw IllegalArgumentException.");
146         } catch (IllegalArgumentException e) {
147             // expected.
148         }
149 
150         try {
151             Location.convert(181, Location.FORMAT_SECONDS);
152             fail("should throw IllegalArgumentException.");
153         } catch (IllegalArgumentException e) {
154             // expected.
155         }
156 
157         try {
158             Location.convert(-80.075, -1);
159             fail("should throw IllegalArgumentException.");
160         } catch (IllegalArgumentException e) {
161             // expected.
162         }
163     }
164 
testConvert_RepresentationToCoordinate()165     public void testConvert_RepresentationToCoordinate() {
166         double result;
167 
168         result = Location.convert("-80.075");
169         assertEquals(-80.075, result);
170 
171         result = Location.convert("-80:05.10000");
172         assertEquals(-80.085, result);
173 
174         result = Location.convert("-80:04:03.00000");
175         assertEquals(-80.0675, result);
176 
177         result = Location.convert("-80:4:3");
178         assertEquals(-80.0675, result);
179 
180         try {
181             Location.convert(null);
182             fail("should throw NullPointerException.");
183         } catch (NullPointerException e){
184             // expected.
185         }
186 
187         try {
188             Location.convert(":");
189             fail("should throw IllegalArgumentException.");
190         } catch (IllegalArgumentException e){
191             // expected.
192         }
193 
194         try {
195             Location.convert("190:4:3");
196             fail("should throw IllegalArgumentException.");
197         } catch (IllegalArgumentException e){
198             // expected.
199         }
200 
201         try {
202             Location.convert("-80:60:3");
203             fail("should throw IllegalArgumentException.");
204         } catch (IllegalArgumentException e){
205             // expected.
206         }
207 
208         try {
209             Location.convert("-80:4:60");
210             fail("should throw IllegalArgumentException.");
211         } catch (IllegalArgumentException e){
212             // expected.
213         }
214     }
215 
testDescribeContents()216     public void testDescribeContents() {
217         Location location = new Location("");
218         location.describeContents();
219     }
220 
testDistanceBetween()221     public void testDistanceBetween() {
222         float[] result = new float[3];
223         Location.distanceBetween(0, 0, 0, 0, result);
224         assertEquals(0.0, result[0], DELTA);
225         assertEquals(0.0, result[1], DELTA);
226         assertEquals(0.0, result[2], DELTA);
227 
228         Location.distanceBetween(20, 30, -40, 140, result);
229         assertEquals(1.3094936E7, result[0], 1);
230         assertEquals(125.4538, result[1], DELTA);
231         assertEquals(93.3971, result[2], DELTA);
232 
233         try {
234             Location.distanceBetween(20, 30, -40, 140, null);
235             fail("should throw IllegalArgumentException");
236         } catch (IllegalArgumentException e) {
237             // expected.
238         }
239 
240         try {
241             Location.distanceBetween(20, 30, -40, 140, new float[0]);
242             fail("should throw IllegalArgumentException");
243         } catch (IllegalArgumentException e) {
244             // expected.
245         }
246     }
247 
testDistanceTo()248     public void testDistanceTo() {
249         float distance;
250         Location zeroLocation = new Location("");
251         zeroLocation.setLatitude(0);
252         zeroLocation.setLongitude(0);
253 
254         Location testLocation = new Location("");
255         testLocation.setLatitude(30);
256         testLocation.setLongitude(50);
257 
258         distance = zeroLocation.distanceTo(zeroLocation);
259         assertEquals(0, distance, DELTA);
260 
261         distance = zeroLocation.distanceTo(testLocation);
262         assertEquals(6244139.0, distance, 1);
263     }
264 
testAccessAccuracy()265     public void testAccessAccuracy() {
266         Location location = new Location("");
267         assertFalse(location.hasAccuracy());
268 
269         location.setAccuracy(1.0f);
270         assertEquals(1.0, location.getAccuracy(), DELTA);
271         assertTrue(location.hasAccuracy());
272 
273         location.removeAccuracy();
274         assertEquals(0.0, location.getAccuracy(), DELTA);
275         assertFalse(location.hasAccuracy());
276     }
277 
testAccessVerticalAccuracy()278     public void testAccessVerticalAccuracy() {
279         Location location = new Location("");
280         assertFalse(location.hasVerticalAccuracy());
281 
282         location.setVerticalAccuracyMeters(1.0f);
283         assertEquals(1.0, location.getVerticalAccuracyMeters(), DELTA);
284         assertTrue(location.hasVerticalAccuracy());
285     }
286 
testAccessSpeedAccuracy()287     public void testAccessSpeedAccuracy() {
288         Location location = new Location("");
289         assertFalse(location.hasSpeedAccuracy());
290 
291         location.setSpeedAccuracyMetersPerSecond(1.0f);
292         assertEquals(1.0, location.getSpeedAccuracyMetersPerSecond(), DELTA);
293         assertTrue(location.hasSpeedAccuracy());
294     }
295 
testAccessBearingAccuracy()296     public void testAccessBearingAccuracy() {
297         Location location = new Location("");
298         assertFalse(location.hasBearingAccuracy());
299 
300         location.setBearingAccuracyDegrees(1.0f);
301         assertEquals(1.0, location.getBearingAccuracyDegrees(), DELTA);
302         assertTrue(location.hasBearingAccuracy());
303     }
304 
305 
testAccessAltitude()306     public void testAccessAltitude() {
307         Location location = new Location("");
308         assertFalse(location.hasAltitude());
309 
310         location.setAltitude(1.0);
311         assertEquals(1.0, location.getAltitude(), DELTA);
312         assertTrue(location.hasAltitude());
313 
314         location.removeAltitude();
315         assertEquals(0.0, location.getAltitude(), DELTA);
316         assertFalse(location.hasAltitude());
317     }
318 
testAccessBearing()319     public void testAccessBearing() {
320         Location location = new Location("");
321         assertFalse(location.hasBearing());
322 
323         location.setBearing(1.0f);
324         assertEquals(1.0, location.getBearing(), DELTA);
325         assertTrue(location.hasBearing());
326 
327         location.setBearing(371.0f);
328         assertEquals(11.0, location.getBearing(), DELTA);
329         assertTrue(location.hasBearing());
330 
331         location.setBearing(-361.0f);
332         assertEquals(359.0, location.getBearing(), DELTA);
333         assertTrue(location.hasBearing());
334 
335         location.removeBearing();
336         assertEquals(0.0, location.getBearing(), DELTA);
337         assertFalse(location.hasBearing());
338     }
339 
testAccessExtras()340     public void testAccessExtras() {
341         Location location = createTestLocation();
342 
343         assertTestBundle(location.getExtras());
344 
345         location.setExtras(null);
346         assertNull(location.getExtras());
347     }
348 
testAccessLatitude()349     public void testAccessLatitude() {
350         Location location = new Location("");
351 
352         location.setLatitude(0);
353         assertEquals(0, location.getLatitude(), DELTA);
354 
355         location.setLatitude(90);
356         assertEquals(90, location.getLatitude(), DELTA);
357 
358         location.setLatitude(-90);
359         assertEquals(-90, location.getLatitude(), DELTA);
360     }
361 
testAccessLongitude()362     public void testAccessLongitude() {
363         Location location = new Location("");
364 
365         location.setLongitude(0);
366         assertEquals(0, location.getLongitude(), DELTA);
367 
368         location.setLongitude(180);
369         assertEquals(180, location.getLongitude(), DELTA);
370 
371         location.setLongitude(-180);
372         assertEquals(-180, location.getLongitude(), DELTA);
373     }
374 
testAccessProvider()375     public void testAccessProvider() {
376         Location location = new Location("");
377 
378         String provider = "Location Provider";
379         location.setProvider(provider);
380         assertEquals(provider, location.getProvider());
381 
382         location.setProvider(null);
383         assertNull(location.getProvider());
384     }
385 
testAccessSpeed()386     public void testAccessSpeed() {
387         Location location = new Location("");
388         assertFalse(location.hasSpeed());
389 
390         location.setSpeed(234.0045f);
391         assertEquals(234.0045, location.getSpeed(), DELTA);
392         assertTrue(location.hasSpeed());
393 
394         location.removeSpeed();
395         assertEquals(0.0, location.getSpeed(), DELTA);
396         assertFalse(location.hasSpeed());
397     }
398 
testAccessTime()399     public void testAccessTime() {
400         Location location = new Location("");
401 
402         location.setTime(0);
403         assertEquals(0, location.getTime());
404 
405         location.setTime(Long.MAX_VALUE);
406         assertEquals(Long.MAX_VALUE, location.getTime());
407 
408         location.setTime(12000);
409         assertEquals(12000, location.getTime());
410     }
411 
testAccessElapsedRealtime()412     public void testAccessElapsedRealtime() {
413         Location location = new Location("");
414 
415         location.setElapsedRealtimeNanos(0);
416         assertEquals(0, location.getElapsedRealtimeNanos());
417 
418         location.setElapsedRealtimeNanos(Long.MAX_VALUE);
419         assertEquals(Long.MAX_VALUE, location.getElapsedRealtimeNanos());
420 
421         location.setElapsedRealtimeNanos(12000);
422         assertEquals(12000, location.getElapsedRealtimeNanos());
423     }
424 
testAccessElapsedRealtimeUncertaintyNanos()425     public void testAccessElapsedRealtimeUncertaintyNanos() {
426         Location location = new Location("");
427         assertFalse(location.hasElapsedRealtimeUncertaintyNanos());
428         assertEquals(0.0, location.getElapsedRealtimeUncertaintyNanos());
429 
430         location.setElapsedRealtimeUncertaintyNanos(12000.0);
431         assertEquals(12000.0, location.getElapsedRealtimeUncertaintyNanos());
432         assertTrue(location.hasElapsedRealtimeUncertaintyNanos());
433 
434         location.reset();
435         assertFalse(location.hasElapsedRealtimeUncertaintyNanos());
436         assertEquals(0.0, location.getElapsedRealtimeUncertaintyNanos());
437     }
438 
testSet()439     public void testSet() {
440         Location location = new Location("");
441 
442         Location loc = createTestLocation();
443 
444         location.set(loc);
445         assertTestLocation(location);
446 
447         location.reset();
448         assertNull(location.getProvider());
449         assertEquals(0, location.getTime());
450         assertEquals(0, location.getLatitude(), DELTA);
451         assertEquals(0, location.getLongitude(), DELTA);
452         assertEquals(0, location.getAltitude(), DELTA);
453         assertFalse(location.hasAltitude());
454         assertEquals(0, location.getSpeed(), DELTA);
455         assertFalse(location.hasSpeed());
456         assertEquals(0, location.getBearing(), DELTA);
457         assertFalse(location.hasBearing());
458         assertEquals(0, location.getAccuracy(), DELTA);
459         assertFalse(location.hasAccuracy());
460 
461         assertEquals(0, location.getVerticalAccuracyMeters(), DELTA);
462         assertEquals(0, location.getSpeedAccuracyMetersPerSecond(), DELTA);
463         assertEquals(0, location.getBearingAccuracyDegrees(), DELTA);
464 
465         assertFalse(location.hasVerticalAccuracy());
466         assertFalse(location.hasSpeedAccuracy());
467         assertFalse(location.hasBearingAccuracy());
468 
469         assertNull(location.getExtras());
470     }
471 
testToString()472     public void testToString() {
473         Location location = createTestLocation();
474 
475         assertNotNull(location.toString());
476     }
477 
testWriteToParcel()478     public void testWriteToParcel() {
479         Location location = createTestLocation();
480 
481         Parcel parcel = Parcel.obtain();
482         location.writeToParcel(parcel, 0);
483         parcel.setDataPosition(0);
484         Location newLocation = Location.CREATOR.createFromParcel(parcel);
485         assertTestLocation(newLocation);
486 
487         parcel.recycle();
488     }
489 
testSettingInjectorService()490     public void testSettingInjectorService() {
491         Context c = getContext();
492         SettingInjectorServiceDerived service = new SettingInjectorServiceDerived();
493 
494         assertNotNull(c);
495 
496         Intent intent =
497             new Intent(c, android.location.SettingInjectorService.class);
498 
499         assertNotNull(c.getMainLooper());
500         SettingInjectorResultHandler resultHandler =
501             new SettingInjectorResultHandler(c.getMainLooper());
502 
503         Messenger m = new Messenger(resultHandler);
504         intent.putExtra(MESSENGER_KEY, m);
505 
506         int ret;
507         final long timeout = 500;
508 
509         // should refuse binding
510         IBinder binder = service.callOnBind(intent);
511         assertNull("onBind should always fail.", binder);
512 
513         // test if result consistent with the truth
514         // enabled == false case
515         service.setEnabled(false);
516         resultHandler.expectEnabled(false);
517         resultHandler.expectMessage(true);
518         ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0);
519         assertEquals("onStartCommand return value invalid in (enabled == false) case.",
520             ret, SettingInjectorService.START_NOT_STICKY);
521         assertTrue("Message time out in (enabled == false case).",
522             resultHandler.waitForMessage(timeout));
523 
524         // enabled == true case
525         service.setEnabled(true);
526         assertTrue(service.onGetEnabled());
527         assertEquals("Summary", service.onGetSummary());
528         resultHandler.expectEnabled(true);
529         resultHandler.expectMessage(true);
530         ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0);
531         assertEquals("onStartCommand return value invalid in (enabled == true) case.",
532             ret, SettingInjectorService.START_NOT_STICKY);
533         assertTrue("Message time out in (enabled == true) case.",
534             resultHandler.waitForMessage(timeout));
535 
536         // should not respond to the deprecated method
537         resultHandler.expectMessage(false);
538         service.callOnStart(intent, 0);
539         resultHandler.waitForMessage(timeout);
540     }
541 
assertTestLocation(Location l)542     private void assertTestLocation(Location l) {
543         assertNotNull(l);
544         assertEquals(TEST_PROVIDER, l.getProvider());
545         assertEquals(TEST_ACCURACY, l.getAccuracy(), DELTA);
546         assertEquals(TEST_VERTICAL_ACCURACY, l.getVerticalAccuracyMeters(), DELTA);
547         assertEquals(TEST_SPEED_ACCURACY, l.getSpeedAccuracyMetersPerSecond(), DELTA);
548         assertEquals(TEST_BEARING_ACCURACY, l.getBearingAccuracyDegrees(), DELTA);
549         assertEquals(TEST_ALTITUDE, l.getAltitude(), DELTA);
550         assertEquals(TEST_LATITUDE, l.getLatitude(), DELTA);
551         assertEquals(TEST_BEARING, l.getBearing(), DELTA);
552         assertEquals(TEST_LONGITUDE, l.getLongitude(), DELTA);
553         assertEquals(TEST_SPEED, l.getSpeed(), DELTA);
554         assertEquals(TEST_TIME, l.getTime());
555         assertTestBundle(l.getExtras());
556     }
557 
createTestLocation()558     private Location createTestLocation() {
559         Location l = new Location(TEST_PROVIDER);
560         l.setAccuracy(TEST_ACCURACY);
561         l.setVerticalAccuracyMeters(TEST_VERTICAL_ACCURACY);
562         l.setSpeedAccuracyMetersPerSecond(TEST_SPEED_ACCURACY);
563         l.setBearingAccuracyDegrees(TEST_BEARING_ACCURACY);
564 
565         l.setAltitude(TEST_ALTITUDE);
566         l.setLatitude(TEST_LATITUDE);
567         l.setBearing(TEST_BEARING);
568         l.setLongitude(TEST_LONGITUDE);
569         l.setSpeed(TEST_SPEED);
570         l.setTime(TEST_TIME);
571         Bundle bundle = new Bundle();
572         bundle.putBoolean(TEST_KEY1NAME, TEST_KEY1VALUE);
573         bundle.putByte(TEST_KEY2NAME, TEST_KEY2VALUE);
574         l.setExtras(bundle);
575 
576         return l;
577     }
578 
assertTestBundle(Bundle bundle)579     private void assertTestBundle(Bundle bundle) {
580         assertFalse(bundle.getBoolean(TEST_KEY1NAME));
581         assertEquals(TEST_KEY2VALUE, bundle.getByte(TEST_KEY2NAME));
582     }
583 
584     private class SettingInjectorResultHandler extends Handler {
585         private boolean mEnabledShouldBe;
586         private boolean mExpectingMessage;
587         private boolean mMessageArrived;
588 
SettingInjectorResultHandler(Looper l)589         SettingInjectorResultHandler(Looper l) {
590             super(l);
591         }
592 
593         @Override
handleMessage(Message m)594         public void handleMessage(Message m) {
595 
596             assertTrue("Unexpected message.", mExpectingMessage);
597 
598             boolean enabled = m.getData().getBoolean(ENABLED_KEY);
599 
600             assertEquals(String.format(
601                     "Message value (%s) inconsistent with service state (%s).",
602                     String.valueOf(enabled), String.valueOf(mEnabledShouldBe) ),
603                     mEnabledShouldBe, enabled);
604 
605             synchronized (this) {
606                 mMessageArrived = true;
607                 notify();
608             }
609         }
610 
expectEnabled(boolean enabled)611         public void expectEnabled(boolean enabled) {
612             mEnabledShouldBe = enabled;
613         }
614 
expectMessage(boolean expecting)615         public void expectMessage(boolean expecting) {
616             mMessageArrived = false;
617             mExpectingMessage = expecting;
618         }
619 
waitForMessage(long millis)620         public synchronized boolean waitForMessage(long millis) {
621             synchronized (this) {
622                 try {
623                     wait(millis);
624                 } catch (InterruptedException e) {
625                     e.printStackTrace();
626                 }
627                 return mMessageArrived;
628             }
629         }
630     }
631 
632 
633     private class SettingInjectorServiceDerived extends SettingInjectorService {
634 
635         private boolean mEnabled;
636 
SettingInjectorServiceDerived()637         SettingInjectorServiceDerived() {
638             super("SettingInjectorServiceDerived");
639             setEnabled(false);
640         }
641 
642         @Override
643         // Deprecated API
onGetSummary()644         protected String onGetSummary() {
645             return "Summary";
646         }
647 
648         @Override
onGetEnabled()649         protected boolean onGetEnabled() {
650             return mEnabled;
651         }
652 
setEnabled(boolean enabled)653         public void setEnabled(boolean enabled) {
654             mEnabled = enabled;
655         }
656 
657         // API coverage dashboard will not count method call from derived class.
658         // Thus, it is necessary to make explicit call to SettingInjectorService public methods.
callOnBind(Intent intent)659         public IBinder callOnBind(Intent intent) {
660             return super.onBind(intent);
661         }
662 
callOnStart(Intent intent, int startId)663         public void callOnStart(Intent intent, int startId) {
664             super.onStart(intent, startId);
665         }
666 
callOnStartCommand(Intent intent, int flags, int startId)667         public int callOnStartCommand(Intent intent, int flags, int startId) {
668             return super.onStartCommand(intent, flags, startId);
669         }
670     }
671 
672 }
673