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 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 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 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 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 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 216 public void testDescribeContents() { 217 Location location = new Location(""); 218 location.describeContents(); 219 } 220 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 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 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 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 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 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 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 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 340 public void testAccessExtras() { 341 Location location = createTestLocation(); 342 343 assertTestBundle(location.getExtras()); 344 345 location.setExtras(null); 346 assertNull(location.getExtras()); 347 } 348 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 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 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 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 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 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 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 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 472 public void testToString() { 473 Location location = createTestLocation(); 474 475 assertNotNull(location.toString()); 476 } 477 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 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 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 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 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 589 SettingInjectorResultHandler(Looper l) { 590 super(l); 591 } 592 593 @Override 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 611 public void expectEnabled(boolean enabled) { 612 mEnabledShouldBe = enabled; 613 } 614 615 public void expectMessage(boolean expecting) { 616 mMessageArrived = false; 617 mExpectingMessage = expecting; 618 } 619 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 637 SettingInjectorServiceDerived() { 638 super("SettingInjectorServiceDerived"); 639 setEnabled(false); 640 } 641 642 @Override 643 // Deprecated API 644 protected String onGetSummary() { 645 return "Summary"; 646 } 647 648 @Override 649 protected boolean onGetEnabled() { 650 return mEnabled; 651 } 652 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. 659 public IBinder callOnBind(Intent intent) { 660 return super.onBind(intent); 661 } 662 663 public void callOnStart(Intent intent, int startId) { 664 super.onStart(intent, startId); 665 } 666 667 public int callOnStartCommand(Intent intent, int flags, int startId) { 668 return super.onStartCommand(intent, flags, startId); 669 } 670 } 671 672 } 673