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 testSet()380 public void testSet() { 381 Location location = new Location(""); 382 383 Location loc = createTestLocation(); 384 385 location.set(loc); 386 assertTestLocation(location); 387 388 location.reset(); 389 assertNull(location.getProvider()); 390 assertEquals(0, location.getTime()); 391 assertEquals(0, location.getLatitude(), DELTA); 392 assertEquals(0, location.getLongitude(), DELTA); 393 assertEquals(0, location.getAltitude(), DELTA); 394 assertFalse(location.hasAltitude()); 395 assertEquals(0, location.getSpeed(), DELTA); 396 assertFalse(location.hasSpeed()); 397 assertEquals(0, location.getBearing(), DELTA); 398 assertFalse(location.hasBearing()); 399 assertEquals(0, location.getAccuracy(), DELTA); 400 assertFalse(location.hasAccuracy()); 401 assertNull(location.getExtras()); 402 } 403 testToString()404 public void testToString() { 405 Location location = createTestLocation(); 406 407 assertNotNull(location.toString()); 408 } 409 testWriteToParcel()410 public void testWriteToParcel() { 411 Location location = createTestLocation(); 412 413 Parcel parcel = Parcel.obtain(); 414 location.writeToParcel(parcel, 0); 415 parcel.setDataPosition(0); 416 Location newLocation = Location.CREATOR.createFromParcel(parcel); 417 assertTestLocation(newLocation); 418 } 419 testSettingInjectorService()420 public void testSettingInjectorService() { 421 Context c = getContext(); 422 SettingInjectorServiceDerived service = new SettingInjectorServiceDerived(); 423 424 assertNotNull(c); 425 426 Intent intent = 427 new Intent(c, android.location.SettingInjectorService.class); 428 429 assertNotNull(c.getMainLooper()); 430 SettingInjectorResultHandler resultHandler = 431 new SettingInjectorResultHandler(c.getMainLooper()); 432 433 Messenger m = new Messenger(resultHandler); 434 intent.putExtra(MESSENGER_KEY, m); 435 436 int ret; 437 final long timeout = 500; 438 439 // should refuse binding 440 IBinder binder = service.callOnBind(intent); 441 assertNull("onBind should always fail.", binder); 442 443 // test if result consistent with the truth 444 // enabled == false case 445 service.setEnabled(false); 446 resultHandler.expectEnabled(false); 447 resultHandler.expectMessage(true); 448 ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0); 449 assertEquals("onStartCommand return value invalid in (enabled == false) case.", 450 ret, SettingInjectorService.START_NOT_STICKY); 451 assertTrue("Message time out in (enabled == false case).", 452 resultHandler.waitForMessage(timeout)); 453 454 // enabled == true case 455 service.setEnabled(true); 456 resultHandler.expectEnabled(true); 457 resultHandler.expectMessage(true); 458 ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0); 459 assertEquals("onStartCommand return value invalid in (enabled == true) case.", 460 ret, SettingInjectorService.START_NOT_STICKY); 461 assertTrue("Message time out in (enabled == true) case.", 462 resultHandler.waitForMessage(timeout)); 463 464 // should not respond to the deprecated method 465 resultHandler.expectMessage(false); 466 service.callOnStart(intent, 0); 467 resultHandler.waitForMessage(timeout); 468 } 469 assertTestLocation(Location l)470 private void assertTestLocation(Location l) { 471 assertNotNull(l); 472 assertEquals(TEST_PROVIDER, l.getProvider()); 473 assertEquals(TEST_ACCURACY, l.getAccuracy(), DELTA); 474 assertEquals(TEST_ALTITUDE, l.getAltitude(), DELTA); 475 assertEquals(TEST_LATITUDE, l.getLatitude(), DELTA); 476 assertEquals(TEST_BEARING, l.getBearing(), DELTA); 477 assertEquals(TEST_LONGITUDE, l.getLongitude(), DELTA); 478 assertEquals(TEST_SPEED, l.getSpeed(), DELTA); 479 assertEquals(TEST_TIME, l.getTime()); 480 assertTestBundle(l.getExtras()); 481 } 482 createTestLocation()483 private Location createTestLocation() { 484 Location l = new Location(TEST_PROVIDER); 485 l.setAccuracy(TEST_ACCURACY); 486 l.setAltitude(TEST_ALTITUDE); 487 l.setLatitude(TEST_LATITUDE); 488 l.setBearing(TEST_BEARING); 489 l.setLongitude(TEST_LONGITUDE); 490 l.setSpeed(TEST_SPEED); 491 l.setTime(TEST_TIME); 492 Bundle bundle = new Bundle(); 493 bundle.putBoolean(TEST_KEY1NAME, TEST_KEY1VALUE); 494 bundle.putByte(TEST_KEY2NAME, TEST_KEY2VALUE); 495 l.setExtras(bundle); 496 497 return l; 498 } 499 assertTestBundle(Bundle bundle)500 private void assertTestBundle(Bundle bundle) { 501 assertFalse(bundle.getBoolean(TEST_KEY1NAME)); 502 assertEquals(TEST_KEY2VALUE, bundle.getByte(TEST_KEY2NAME)); 503 } 504 505 private class SettingInjectorResultHandler extends Handler { 506 private boolean mEnabledShouldBe; 507 private boolean mExpectingMessage; 508 private boolean mMessageArrived; 509 SettingInjectorResultHandler(Looper l)510 SettingInjectorResultHandler(Looper l) { 511 super(l); 512 } 513 514 @Override handleMessage(Message m)515 public void handleMessage(Message m) { 516 517 assertTrue("Unexpected message.", mExpectingMessage); 518 519 boolean enabled = m.getData().getBoolean(ENABLED_KEY); 520 521 assertEquals(String.format( 522 "Message value (%s) inconsistent with service state (%s).", 523 String.valueOf(enabled), String.valueOf(mEnabledShouldBe) ), 524 mEnabledShouldBe, enabled); 525 526 synchronized (this) { 527 mMessageArrived = true; 528 notify(); 529 } 530 } 531 expectEnabled(boolean enabled)532 public void expectEnabled(boolean enabled) { 533 mEnabledShouldBe = enabled; 534 } 535 expectMessage(boolean expecting)536 public void expectMessage(boolean expecting) { 537 mMessageArrived = false; 538 mExpectingMessage = expecting; 539 } 540 waitForMessage(long millis)541 public synchronized boolean waitForMessage(long millis) { 542 synchronized (this) { 543 try { 544 wait(millis); 545 } catch (InterruptedException e) { 546 e.printStackTrace(); 547 } 548 return mMessageArrived; 549 } 550 } 551 } 552 553 554 private class SettingInjectorServiceDerived extends SettingInjectorService { 555 556 private boolean mEnabled; 557 SettingInjectorServiceDerived()558 SettingInjectorServiceDerived() { 559 super("SettingInjectorServiceDerived"); 560 setEnabled(false); 561 } 562 563 @Override 564 // Deprecated API onGetSummary()565 protected String onGetSummary() { 566 return ""; 567 } 568 569 @Override onGetEnabled()570 protected boolean onGetEnabled() { 571 return mEnabled; 572 } 573 setEnabled(boolean enabled)574 public void setEnabled(boolean enabled) { 575 mEnabled = enabled; 576 } 577 578 // API coverage dashboard will not cound method call from derived class. 579 // Thus, it is necessary to make explicit call to SettingInjectorService public methods. callOnBind(Intent intent)580 public IBinder callOnBind(Intent intent) { 581 return super.onBind(intent); 582 } 583 callOnStart(Intent intent, int startId)584 public void callOnStart(Intent intent, int startId) { 585 super.onStart(intent, startId); 586 } 587 callOnStartCommand(Intent intent, int flags, int startId)588 public int callOnStartCommand(Intent intent, int flags, int startId) { 589 return super.onStartCommand(intent, flags, startId); 590 } 591 } 592 593 } 594