blob: db2820c3f46d1e6de05d3e19c830423e6a328847 [file] [log] [blame]
/*
* Copyright (C) 2008 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.location.cts;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.SettingInjectorService;
import android.os.Handler;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
import android.os.Messenger;
import android.os.Bundle;
import android.os.Parcel;
import android.test.AndroidTestCase;
import android.util.Printer;
import android.util.StringBuilderPrinter;
import java.text.DecimalFormat;
public class LocationTest extends AndroidTestCase {
private static final float DELTA = 0.1f;
private final float TEST_ACCURACY = 1.0f;
private final double TEST_ALTITUDE = 1.0;
private final double TEST_LATITUDE = 50;
private final float TEST_BEARING = 1.0f;
private final double TEST_LONGITUDE = 20;
private final float TEST_SPEED = 5.0f;
private final long TEST_TIME = 100;
private final String TEST_PROVIDER = "LocationProvider";
private final String TEST_KEY1NAME = "key1";
private final String TEST_KEY2NAME = "key2";
private final boolean TEST_KEY1VALUE = false;
private final byte TEST_KEY2VALUE = 10;
private static final String ENABLED_KEY = "enabled";
private static final String MESSENGER_KEY = "messenger";
public void testConstructor() {
new Location("LocationProvider");
Location l = createTestLocation();
Location location = new Location(l);
assertTestLocation(location);
try {
new Location((Location) null);
fail("should throw NullPointerException");
} catch (NullPointerException e) {
// expected.
}
}
public void testDump() {
StringBuilder sb = new StringBuilder();
StringBuilderPrinter printer = new StringBuilderPrinter(sb);
Location location = new Location("LocationProvider");
location.dump(printer, "");
assertNotNull(sb.toString());
}
public void testBearingTo() {
Location location = new Location("");
Location dest = new Location("");
// set the location to Beijing
location.setLatitude(39.9);
location.setLongitude(116.4);
// set the destination to Chengdu
dest.setLatitude(30.7);
dest.setLongitude(104.1);
assertEquals(-128.66, location.bearingTo(dest), DELTA);
float bearing;
Location zeroLocation = new Location("");
zeroLocation.setLatitude(0);
zeroLocation.setLongitude(0);
Location testLocation = new Location("");
testLocation.setLatitude(0);
testLocation.setLongitude(150);
bearing = zeroLocation.bearingTo(zeroLocation);
assertEquals(0.0f, bearing, DELTA);
bearing = zeroLocation.bearingTo(testLocation);
assertEquals(90.0f, bearing, DELTA);
testLocation.setLatitude(90);
testLocation.setLongitude(0);
bearing = zeroLocation.bearingTo(testLocation);
assertEquals(0.0f, bearing, DELTA);
try {
location.bearingTo(null);
fail("should throw NullPointerException");
} catch (NullPointerException e) {
// expected.
}
}
public void testConvert_CoordinateToRepresentation() {
DecimalFormat df = new DecimalFormat("###.#####");
String result;
result = Location.convert(-80.0, Location.FORMAT_DEGREES);
assertEquals("-" + df.format(80.0), result);
result = Location.convert(-80.085, Location.FORMAT_MINUTES);
assertEquals("-80:" + df.format(5.1), result);
result = Location.convert(-80, Location.FORMAT_MINUTES);
assertEquals("-80:" + df.format(0), result);
result = Location.convert(-80.075, Location.FORMAT_MINUTES);
assertEquals("-80:" + df.format(4.5), result);
result = Location.convert(-80.075, Location.FORMAT_DEGREES);
assertEquals("-" + df.format(80.075), result);
result = Location.convert(-80.075, Location.FORMAT_SECONDS);
assertEquals("-80:4:30", result);
try {
Location.convert(-181, Location.FORMAT_SECONDS);
fail("should throw IllegalArgumentException.");
} catch (IllegalArgumentException e) {
// expected.
}
try {
Location.convert(181, Location.FORMAT_SECONDS);
fail("should throw IllegalArgumentException.");
} catch (IllegalArgumentException e) {
// expected.
}
try {
Location.convert(-80.075, -1);
fail("should throw IllegalArgumentException.");
} catch (IllegalArgumentException e) {
// expected.
}
}
public void testConvert_RepresentationToCoordinate() {
double result;
result = Location.convert("-80.075");
assertEquals(-80.075, result);
result = Location.convert("-80:05.10000");
assertEquals(-80.085, result);
result = Location.convert("-80:04:03.00000");
assertEquals(-80.0675, result);
result = Location.convert("-80:4:3");
assertEquals(-80.0675, result);
try {
Location.convert(null);
fail("should throw NullPointerException.");
} catch (NullPointerException e){
// expected.
}
try {
Location.convert(":");
fail("should throw IllegalArgumentException.");
} catch (IllegalArgumentException e){
// expected.
}
try {
Location.convert("190:4:3");
fail("should throw IllegalArgumentException.");
} catch (IllegalArgumentException e){
// expected.
}
try {
Location.convert("-80:60:3");
fail("should throw IllegalArgumentException.");
} catch (IllegalArgumentException e){
// expected.
}
try {
Location.convert("-80:4:60");
fail("should throw IllegalArgumentException.");
} catch (IllegalArgumentException e){
// expected.
}
}
public void testDescribeContents() {
Location location = new Location("");
location.describeContents();
}
public void testDistanceBetween() {
float[] result = new float[3];
Location.distanceBetween(0, 0, 0, 0, result);
assertEquals(0.0, result[0], DELTA);
assertEquals(0.0, result[1], DELTA);
assertEquals(0.0, result[2], DELTA);
Location.distanceBetween(20, 30, -40, 140, result);
assertEquals(1.3094936E7, result[0], 1);
assertEquals(125.4538, result[1], DELTA);
assertEquals(93.3971, result[2], DELTA);
try {
Location.distanceBetween(20, 30, -40, 140, null);
fail("should throw IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected.
}
try {
Location.distanceBetween(20, 30, -40, 140, new float[0]);
fail("should throw IllegalArgumentException");
} catch (IllegalArgumentException e) {
// expected.
}
}
public void testDistanceTo() {
float distance;
Location zeroLocation = new Location("");
zeroLocation.setLatitude(0);
zeroLocation.setLongitude(0);
Location testLocation = new Location("");
testLocation.setLatitude(30);
testLocation.setLongitude(50);
distance = zeroLocation.distanceTo(zeroLocation);
assertEquals(0, distance, DELTA);
distance = zeroLocation.distanceTo(testLocation);
assertEquals(6244139.0, distance, 1);
}
public void testAccessAccuracy() {
Location location = new Location("");
assertFalse(location.hasAccuracy());
location.setAccuracy(1.0f);
assertEquals(1.0, location.getAccuracy(), DELTA);
assertTrue(location.hasAccuracy());
location.removeAccuracy();
assertEquals(0.0, location.getAccuracy(), DELTA);
assertFalse(location.hasAccuracy());
}
public void testAccessAltitude() {
Location location = new Location("");
assertFalse(location.hasAltitude());
location.setAltitude(1.0);
assertEquals(1.0, location.getAltitude(), DELTA);
assertTrue(location.hasAltitude());
location.removeAltitude();
assertEquals(0.0, location.getAltitude(), DELTA);
assertFalse(location.hasAltitude());
}
public void testAccessBearing() {
Location location = new Location("");
assertFalse(location.hasBearing());
location.setBearing(1.0f);
assertEquals(1.0, location.getBearing(), DELTA);
assertTrue(location.hasBearing());
location.setBearing(371.0f);
assertEquals(11.0, location.getBearing(), DELTA);
assertTrue(location.hasBearing());
location.setBearing(-361.0f);
assertEquals(359.0, location.getBearing(), DELTA);
assertTrue(location.hasBearing());
location.removeBearing();
assertEquals(0.0, location.getBearing(), DELTA);
assertFalse(location.hasBearing());
}
public void testAccessExtras() {
Location location = createTestLocation();
assertTestBundle(location.getExtras());
location.setExtras(null);
assertNull(location.getExtras());
}
public void testAccessLatitude() {
Location location = new Location("");
location.setLatitude(0);
assertEquals(0, location.getLatitude(), DELTA);
location.setLatitude(90);
assertEquals(90, location.getLatitude(), DELTA);
location.setLatitude(-90);
assertEquals(-90, location.getLatitude(), DELTA);
}
public void testAccessLongitude() {
Location location = new Location("");
location.setLongitude(0);
assertEquals(0, location.getLongitude(), DELTA);
location.setLongitude(180);
assertEquals(180, location.getLongitude(), DELTA);
location.setLongitude(-180);
assertEquals(-180, location.getLongitude(), DELTA);
}
public void testAccessProvider() {
Location location = new Location("");
String provider = "Location Provider";
location.setProvider(provider);
assertEquals(provider, location.getProvider());
location.setProvider(null);
assertNull(location.getProvider());
}
public void testAccessSpeed() {
Location location = new Location("");
assertFalse(location.hasSpeed());
location.setSpeed(234.0045f);
assertEquals(234.0045, location.getSpeed(), DELTA);
assertTrue(location.hasSpeed());
location.removeSpeed();
assertEquals(0.0, location.getSpeed(), DELTA);
assertFalse(location.hasSpeed());
}
public void testAccessTime() {
Location location = new Location("");
location.setTime(0);
assertEquals(0, location.getTime());
location.setTime(Long.MAX_VALUE);
assertEquals(Long.MAX_VALUE, location.getTime());
location.setTime(12000);
assertEquals(12000, location.getTime());
}
public void testSet() {
Location location = new Location("");
Location loc = createTestLocation();
location.set(loc);
assertTestLocation(location);
location.reset();
assertNull(location.getProvider());
assertEquals(0, location.getTime());
assertEquals(0, location.getLatitude(), DELTA);
assertEquals(0, location.getLongitude(), DELTA);
assertEquals(0, location.getAltitude(), DELTA);
assertFalse(location.hasAltitude());
assertEquals(0, location.getSpeed(), DELTA);
assertFalse(location.hasSpeed());
assertEquals(0, location.getBearing(), DELTA);
assertFalse(location.hasBearing());
assertEquals(0, location.getAccuracy(), DELTA);
assertFalse(location.hasAccuracy());
assertNull(location.getExtras());
}
public void testToString() {
Location location = createTestLocation();
assertNotNull(location.toString());
}
public void testWriteToParcel() {
Location location = createTestLocation();
Parcel parcel = Parcel.obtain();
location.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
Location newLocation = Location.CREATOR.createFromParcel(parcel);
assertTestLocation(newLocation);
}
public void testSettingInjectorService() {
Context c = getContext();
SettingInjectorServiceDerived service = new SettingInjectorServiceDerived();
assertNotNull(c);
Intent intent =
new Intent(c, android.location.SettingInjectorService.class);
assertNotNull(c.getMainLooper());
SettingInjectorResultHandler resultHandler =
new SettingInjectorResultHandler(c.getMainLooper());
Messenger m = new Messenger(resultHandler);
intent.putExtra(MESSENGER_KEY, m);
int ret;
final long timeout = 500;
// should refuse binding
IBinder binder = service.callOnBind(intent);
assertNull("onBind should always fail.", binder);
// test if result consistent with the truth
// enabled == false case
service.setEnabled(false);
resultHandler.expectEnabled(false);
resultHandler.expectMessage(true);
ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0);
assertEquals("onStartCommand return value invalid in (enabled == false) case.",
ret, SettingInjectorService.START_NOT_STICKY);
assertTrue("Message time out in (enabled == false case).",
resultHandler.waitForMessage(timeout));
// enabled == true case
service.setEnabled(true);
resultHandler.expectEnabled(true);
resultHandler.expectMessage(true);
ret = service.callOnStartCommand(intent, SettingInjectorService.START_NOT_STICKY, 0);
assertEquals("onStartCommand return value invalid in (enabled == true) case.",
ret, SettingInjectorService.START_NOT_STICKY);
assertTrue("Message time out in (enabled == true) case.",
resultHandler.waitForMessage(timeout));
// should not respond to the deprecated method
resultHandler.expectMessage(false);
service.callOnStart(intent, 0);
resultHandler.waitForMessage(timeout);
}
private void assertTestLocation(Location l) {
assertNotNull(l);
assertEquals(TEST_PROVIDER, l.getProvider());
assertEquals(TEST_ACCURACY, l.getAccuracy(), DELTA);
assertEquals(TEST_ALTITUDE, l.getAltitude(), DELTA);
assertEquals(TEST_LATITUDE, l.getLatitude(), DELTA);
assertEquals(TEST_BEARING, l.getBearing(), DELTA);
assertEquals(TEST_LONGITUDE, l.getLongitude(), DELTA);
assertEquals(TEST_SPEED, l.getSpeed(), DELTA);
assertEquals(TEST_TIME, l.getTime());
assertTestBundle(l.getExtras());
}
private Location createTestLocation() {
Location l = new Location(TEST_PROVIDER);
l.setAccuracy(TEST_ACCURACY);
l.setAltitude(TEST_ALTITUDE);
l.setLatitude(TEST_LATITUDE);
l.setBearing(TEST_BEARING);
l.setLongitude(TEST_LONGITUDE);
l.setSpeed(TEST_SPEED);
l.setTime(TEST_TIME);
Bundle bundle = new Bundle();
bundle.putBoolean(TEST_KEY1NAME, TEST_KEY1VALUE);
bundle.putByte(TEST_KEY2NAME, TEST_KEY2VALUE);
l.setExtras(bundle);
return l;
}
private void assertTestBundle(Bundle bundle) {
assertFalse(bundle.getBoolean(TEST_KEY1NAME));
assertEquals(TEST_KEY2VALUE, bundle.getByte(TEST_KEY2NAME));
}
private class SettingInjectorResultHandler extends Handler {
private boolean mEnabledShouldBe;
private boolean mExpectingMessage;
private boolean mMessageArrived;
SettingInjectorResultHandler(Looper l) {
super(l);
}
@Override
public void handleMessage(Message m) {
assertTrue("Unexpected message.", mExpectingMessage);
boolean enabled = m.getData().getBoolean(ENABLED_KEY);
assertEquals(String.format(
"Message value (%s) inconsistent with service state (%s).",
String.valueOf(enabled), String.valueOf(mEnabledShouldBe) ),
mEnabledShouldBe, enabled);
synchronized (this) {
mMessageArrived = true;
notify();
}
}
public void expectEnabled(boolean enabled) {
mEnabledShouldBe = enabled;
}
public void expectMessage(boolean expecting) {
mMessageArrived = false;
mExpectingMessage = expecting;
}
public synchronized boolean waitForMessage(long millis) {
synchronized (this) {
try {
wait(millis);
} catch (InterruptedException e) {
e.printStackTrace();
}
return mMessageArrived;
}
}
}
private class SettingInjectorServiceDerived extends SettingInjectorService {
private boolean mEnabled;
SettingInjectorServiceDerived() {
super("SettingInjectorServiceDerived");
setEnabled(false);
}
@Override
// Deprecated API
protected String onGetSummary() {
return "";
}
@Override
protected boolean onGetEnabled() {
return mEnabled;
}
public void setEnabled(boolean enabled) {
mEnabled = enabled;
}
// API coverage dashboard will not cound method call from derived class.
// Thus, it is necessary to make explicit call to SettingInjectorService public methods.
public IBinder callOnBind(Intent intent) {
return super.onBind(intent);
}
public void callOnStart(Intent intent, int startId) {
super.onStart(intent, startId);
}
public int callOnStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
}
}