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 testSet()425 public void testSet() { 426 Location location = new Location(""); 427 428 Location loc = createTestLocation(); 429 430 location.set(loc); 431 assertTestLocation(location); 432 433 location.reset(); 434 assertNull(location.getProvider()); 435 assertEquals(0, location.getTime()); 436 assertEquals(0, location.getLatitude(), DELTA); 437 assertEquals(0, location.getLongitude(), DELTA); 438 assertEquals(0, location.getAltitude(), DELTA); 439 assertFalse(location.hasAltitude()); 440 assertEquals(0, location.getSpeed(), DELTA); 441 assertFalse(location.hasSpeed()); 442 assertEquals(0, location.getBearing(), DELTA); 443 assertFalse(location.hasBearing()); 444 assertEquals(0, location.getAccuracy(), DELTA); 445 assertFalse(location.hasAccuracy()); 446 447 assertEquals(0, location.getVerticalAccuracyMeters(), DELTA); 448 assertEquals(0, location.getSpeedAccuracyMetersPerSecond(), DELTA); 449 assertEquals(0, location.getBearingAccuracyDegrees(), DELTA); 450 451 assertFalse(location.hasVerticalAccuracy()); 452 assertFalse(location.hasSpeedAccuracy()); 453 assertFalse(location.hasBearingAccuracy()); 454 455 assertNull(location.getExtras()); 456 } 457 testToString()458 public void testToString() { 459 Location location = createTestLocation(); 460 461 assertNotNull(location.toString()); 462 } 463 testWriteToParcel()464 public void testWriteToParcel() { 465 Location location = createTestLocation(); 466 467 Parcel parcel = Parcel.obtain(); 468 location.writeToParcel(parcel, 0); 469 parcel.setDataPosition(0); 470 Location newLocation = Location.CREATOR.createFromParcel(parcel); 471 assertTestLocation(newLocation); 472 } 473 testSettingInjectorService()474 public void testSettingInjectorService() { 475 Context c = getContext(); 476 SettingInjectorServiceDerived service = new SettingInjectorServiceDerived(); 477 478 assertNotNull(c); 479 480 Intent intent = 481 new Intent(c, android.location.SettingInjectorService.class); 482 483 assertNotNull(c.getMainLooper()); 484 SettingInjectorResultHandler resultHandler = 485 new SettingInjectorResultHandler(c.getMainLooper()); 486 487 Messenger m = new Messenger(resultHandler); 488 intent.putExtra(MESSENGER_KEY, m); 489 490 int ret; 491 final long timeout = 500; 492 493 // should refuse binding 494 IBinder binder = service.callOnBind(intent); 495 assertNull("onBind should always fail.", binder); 496 497 // test if result consistent with the truth 498 // enabled == false case 499 service.setEnabled(false); 500 resultHandler.expectEnabled(false); 501 resultHandler.expectMessage(true); 502 ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0); 503 assertEquals("onStartCommand return value invalid in (enabled == false) case.", 504 ret, SettingInjectorService.START_NOT_STICKY); 505 assertTrue("Message time out in (enabled == false case).", 506 resultHandler.waitForMessage(timeout)); 507 508 // enabled == true case 509 service.setEnabled(true); 510 assertTrue(service.onGetEnabled()); 511 assertEquals("Summary", service.onGetSummary()); 512 resultHandler.expectEnabled(true); 513 resultHandler.expectMessage(true); 514 ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0); 515 assertEquals("onStartCommand return value invalid in (enabled == true) case.", 516 ret, SettingInjectorService.START_NOT_STICKY); 517 assertTrue("Message time out in (enabled == true) case.", 518 resultHandler.waitForMessage(timeout)); 519 520 // should not respond to the deprecated method 521 resultHandler.expectMessage(false); 522 service.callOnStart(intent, 0); 523 resultHandler.waitForMessage(timeout); 524 } 525 assertTestLocation(Location l)526 private void assertTestLocation(Location l) { 527 assertNotNull(l); 528 assertEquals(TEST_PROVIDER, l.getProvider()); 529 assertEquals(TEST_ACCURACY, l.getAccuracy(), DELTA); 530 assertEquals(TEST_VERTICAL_ACCURACY, l.getVerticalAccuracyMeters(), DELTA); 531 assertEquals(TEST_SPEED_ACCURACY, l.getSpeedAccuracyMetersPerSecond(), DELTA); 532 assertEquals(TEST_BEARING_ACCURACY, l.getBearingAccuracyDegrees(), DELTA); 533 assertEquals(TEST_ALTITUDE, l.getAltitude(), DELTA); 534 assertEquals(TEST_LATITUDE, l.getLatitude(), DELTA); 535 assertEquals(TEST_BEARING, l.getBearing(), DELTA); 536 assertEquals(TEST_LONGITUDE, l.getLongitude(), DELTA); 537 assertEquals(TEST_SPEED, l.getSpeed(), DELTA); 538 assertEquals(TEST_TIME, l.getTime()); 539 assertTestBundle(l.getExtras()); 540 } 541 createTestLocation()542 private Location createTestLocation() { 543 Location l = new Location(TEST_PROVIDER); 544 l.setAccuracy(TEST_ACCURACY); 545 l.setVerticalAccuracyMeters(TEST_VERTICAL_ACCURACY); 546 l.setSpeedAccuracyMetersPerSecond(TEST_SPEED_ACCURACY); 547 l.setBearingAccuracyDegrees(TEST_BEARING_ACCURACY); 548 549 l.setAltitude(TEST_ALTITUDE); 550 l.setLatitude(TEST_LATITUDE); 551 l.setBearing(TEST_BEARING); 552 l.setLongitude(TEST_LONGITUDE); 553 l.setSpeed(TEST_SPEED); 554 l.setTime(TEST_TIME); 555 Bundle bundle = new Bundle(); 556 bundle.putBoolean(TEST_KEY1NAME, TEST_KEY1VALUE); 557 bundle.putByte(TEST_KEY2NAME, TEST_KEY2VALUE); 558 l.setExtras(bundle); 559 560 return l; 561 } 562 assertTestBundle(Bundle bundle)563 private void assertTestBundle(Bundle bundle) { 564 assertFalse(bundle.getBoolean(TEST_KEY1NAME)); 565 assertEquals(TEST_KEY2VALUE, bundle.getByte(TEST_KEY2NAME)); 566 } 567 568 private class SettingInjectorResultHandler extends Handler { 569 private boolean mEnabledShouldBe; 570 private boolean mExpectingMessage; 571 private boolean mMessageArrived; 572 SettingInjectorResultHandler(Looper l)573 SettingInjectorResultHandler(Looper l) { 574 super(l); 575 } 576 577 @Override handleMessage(Message m)578 public void handleMessage(Message m) { 579 580 assertTrue("Unexpected message.", mExpectingMessage); 581 582 boolean enabled = m.getData().getBoolean(ENABLED_KEY); 583 584 assertEquals(String.format( 585 "Message value (%s) inconsistent with service state (%s).", 586 String.valueOf(enabled), String.valueOf(mEnabledShouldBe) ), 587 mEnabledShouldBe, enabled); 588 589 synchronized (this) { 590 mMessageArrived = true; 591 notify(); 592 } 593 } 594 expectEnabled(boolean enabled)595 public void expectEnabled(boolean enabled) { 596 mEnabledShouldBe = enabled; 597 } 598 expectMessage(boolean expecting)599 public void expectMessage(boolean expecting) { 600 mMessageArrived = false; 601 mExpectingMessage = expecting; 602 } 603 waitForMessage(long millis)604 public synchronized boolean waitForMessage(long millis) { 605 synchronized (this) { 606 try { 607 wait(millis); 608 } catch (InterruptedException e) { 609 e.printStackTrace(); 610 } 611 return mMessageArrived; 612 } 613 } 614 } 615 616 617 private class SettingInjectorServiceDerived extends SettingInjectorService { 618 619 private boolean mEnabled; 620 SettingInjectorServiceDerived()621 SettingInjectorServiceDerived() { 622 super("SettingInjectorServiceDerived"); 623 setEnabled(false); 624 } 625 626 @Override 627 // Deprecated API onGetSummary()628 protected String onGetSummary() { 629 return "Summary"; 630 } 631 632 @Override onGetEnabled()633 protected boolean onGetEnabled() { 634 return mEnabled; 635 } 636 setEnabled(boolean enabled)637 public void setEnabled(boolean enabled) { 638 mEnabled = enabled; 639 } 640 641 // API coverage dashboard will not count method call from derived class. 642 // Thus, it is necessary to make explicit call to SettingInjectorService public methods. callOnBind(Intent intent)643 public IBinder callOnBind(Intent intent) { 644 return super.onBind(intent); 645 } 646 callOnStart(Intent intent, int startId)647 public void callOnStart(Intent intent, int startId) { 648 super.onStart(intent, startId); 649 } 650 callOnStartCommand(Intent intent, int flags, int startId)651 public int callOnStartCommand(Intent intent, int flags, int startId) { 652 return super.onStartCommand(intent, flags, startId); 653 } 654 } 655 656 } 657