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