/*
* Copyright (C) 2008 Google Inc.
*
* 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 com.techbh.ridecall.test;
import java.util.List;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.provider.Settings;
import android.test.AndroidTestCase;
import android.test.suitebuilder.annotation.MediumTest;
import android.util.Log;
/**
* Tests for LocationManager.addProximityAlert
*
* TODO: add tests for more scenarios
*
* To run:
* adb shell am instrument -e class android.location.LocationManagerProximityTest \
* -w android.core/android.test.InstrumentationTestRunner
*
* This test requires that the "Allow mock locations" setting be enabled
*
*/
@MediumTest
public class ProximityAlertTest extends AndroidTestCase {
private static final int UPDATE_LOCATION_WAIT_TIME = 1000;
private static final int PROXIMITY_WAIT_TIME = 2000;
private LocationManager lm;
private PendingIntent mPendingIntent;
private TestIntentReceiver mIntentReceiver;
private static final String LOG_TAG = "LocationProximityTest";
// use network provider as mock location provider, because:
// - proximity alert is hardcoded to listen to only network or gps
// - 'network' provider is not installed in emulator, so can mock it
// using test provider APIs
private static final String PROVIDER_NAME1 = LocationManager.NETWORK_PROVIDER;
private static final String PROVIDER_NAME2 = LocationManager.GPS_PROVIDER;
private String setupProvider = null;
private LocationProvider mP = null;
private List<String> candidatos;
private String bestProvider = null;
private String disponivel = null;
/* Chamado antes de qualquer teste ? */
@Override
protected void setUp() throws Exception {
super.setUp();
// test that mock locations are allowed so a more descriptive error message can be logged
if (Settings.Secure.getInt(getContext().getContentResolver(),
Settings.Secure.ALLOW_MOCK_LOCATION, 0) == 0) {
fail("Mock locations are currently disabled in Settings - this test requires " +
"mock locations");
}
Criteria criteria;
Context ctx = getContext();
boolean enabledOnly = false;
criteria = new Criteria();//TODO Estado atual do telefone?
criteria.setAccuracy(Criteria.ACCURACY_FINE);
lm = (LocationManager) ctx.getSystemService(Context.LOCATION_SERVICE);
bestProvider = lm.getBestProvider(criteria, enabledOnly); //Qual criterio ?
candidatos = lm.getProviders(enabledOnly);
Log.i("RideCall -- Test -- ", "LP Melhor disponvel = " + bestProvider); //network
for (int i=0; i < candidatos.size(); i++) {
Log.i("RideCall -- Test -- ", "Disponvel = " + candidatos.get(i)); //network
}
try {
//tenta usar o bsico
mP = lm.getProvider(PROVIDER_NAME1);
if (mP != null) {
//fallback
disponivel = PROVIDER_NAME1;
Log.i("RideCall -- Test -- ", "LocationProvider = " + mP);
Log.e("RideCall -- Test -- ", "Existe um provedor de Operadora");
}
//tenta melhorar usando o GPS
mP = lm.getProvider(PROVIDER_NAME2);
if (mP != null) {
disponivel = PROVIDER_NAME2;
Log.i("RideCall -- Test -- ", "LocationProvider = " + mP);
Log.e("RideCall -- Test -- ", "Existe um provedor de Satelites");
}
} catch(IllegalArgumentException e){
//No h nenhum disponvel
Log.e("RideCall -- Test -- ", "No h provedores ou no houve melhorias disponveis!");
}
if (disponivel == null) {
//No puderam ser acessados
Log.e("RideCall -- Test -- ", "No h provedores disponveis!");
disponivel = " nenhum disponvel!";
}
Log.e("RideCall -- Test -- ", "Provedor escolhido: " + disponivel);
/*
if (mLocationManager.getProvider(PROVIDER_NAME2) != null) {
setupProvider = PROVIDER_NAME2;
} else*/
if (lm.getProvider(PROVIDER_NAME1) != null) {
//fallback
setupProvider = PROVIDER_NAME1;
} else {
//No h nenhum
return ;
}
lm.addTestProvider(setupProvider,
true, //requiresNetwork ou requiresGPS,
false, // requiresSatellite,
true, // requiresCell,
false, // hasMonetaryCost,
false, // supportsAltitude,
false, // supportsSpeed,
false, // supportsBearing,
Criteria.POWER_MEDIUM, // powerRequirement
Criteria.ACCURACY_FINE); // accuracy
}
/* Chamado aps qualquer teste ? */
@Override
protected void tearDown() throws Exception {
lm.removeTestProvider(setupProvider);
if (mPendingIntent != null) {
lm.removeProximityAlert(mPendingIntent);
}
if (mIntentReceiver != null) {
getContext().unregisterReceiver(mIntentReceiver);
}
}
public void meuTeste(){
// Set location by setting the latitude, longitude and may be the altitude...
/*
String[] MockLoc = str.split(",");
Location location = new Location(mocLocationProvider);
Double lat = Double.valueOf(MockLoc[0]);
location.setLatitude(lat);
Double longi = Double.valueOf(MockLoc[1]);
location.setLongitude(longi);
Double alti = Double.valueOf(MockLoc[2]);
location.setAltitude(alti);
*/
}
/**
* Tests basic proximity alert when entering proximity
*/
public void testEnterProximity() throws Exception {
doTestEnterProximity(10000);
}
/**
* Tests proximity alert when entering proximity, with no expiration
*/
public void testEnterProximity_noexpire() throws Exception {
doTestEnterProximity(-1);
}
/**
* Helper variant for testing enter proximity scenario
* TODO: add additional parameters as more scenarios are added
*
* @param expiration - expiry of proximity alert
*/
private void doTestEnterProximity(long expiration) throws Exception {
// update location to outside proximity range
synchronousSendLocation(30, 30);
registerProximityListener(0, 0, 1000, expiration);
sendLocation(0, 0);
waitForAlert();
assertProximityType(true);
}
/**
* Tests basic proximity alert when exiting proximity
*/
public void testExitProximity() throws Exception {
// first do enter proximity scenario
doTestEnterProximity(-1);
// now update to trigger exit proximity proximity
mIntentReceiver.clearReceivedIntents();
sendLocation(20, 20);
waitForAlert();
assertProximityType(false);
}
/**
* Registers the proximity intent receiver
*/
private void registerProximityListener(double latitude, double longitude,
float radius, long expiration) {
String intentKey = "testProximity";
Intent proximityIntent = new Intent(intentKey);
mPendingIntent = PendingIntent.getBroadcast(getContext(), 0,
proximityIntent, PendingIntent.FLAG_CANCEL_CURRENT);
mIntentReceiver = new TestIntentReceiver(intentKey);
lm.addProximityAlert(latitude, longitude, radius,
expiration, mPendingIntent);
getContext().registerReceiver(mIntentReceiver,
mIntentReceiver.getFilter());
}
/**
* Blocks until proximity intent notification is received
* @throws InterruptedException
*/
private void waitForAlert() throws InterruptedException {
Log.d(LOG_TAG, "Waiting for proximity update");
synchronized (mIntentReceiver) {
mIntentReceiver.wait(PROXIMITY_WAIT_TIME);
}
assertNotNull("Did not receive proximity alert",
mIntentReceiver.getLastReceivedIntent());
}
/**
* Asserts that the received intent had the enter proximity property set as
* expected
* @param expectedEnterProximity - true if enter proximity expected, false if
* exit expected
*/
private void assertProximityType(boolean expectedEnterProximity)
throws Exception {
boolean proximityTest = mIntentReceiver.getLastReceivedIntent().
getBooleanExtra(LocationManager.KEY_PROXIMITY_ENTERING,
!expectedEnterProximity);
assertEquals("proximity alert not set to expected enter proximity value",
expectedEnterProximity, proximityTest);
}
/**
* Synchronous variant of sendLocation
*/
private void synchronousSendLocation(final double latitude,
final double longitude)
throws InterruptedException {
sendLocation(latitude, longitude, this);
// wait for location to be set
synchronized (this) {
wait(UPDATE_LOCATION_WAIT_TIME);
}
}
/**
* Asynchronously update the mock location provider without notification
*/
private void sendLocation(final double latitude, final double longitude) {
sendLocation(latitude, longitude, null);
}
/**
* Asynchronously update the mock location provider with given latitude and
* longitude
*
* @param latitude - update location
* @param longitude - update location
* @param observer - optionally, object to notify when update is sent.If
* null, no update will be sent
*/
private void sendLocation(final double latitude, final double longitude,
final Object observer) {
Thread locationUpdater = new Thread() {
@Override
public void run() {
Location loc = new Location(setupProvider);
loc.setLatitude(latitude);
loc.setLongitude(longitude);
loc.setTime(java.lang.System.currentTimeMillis());
Log.d(LOG_TAG, "Sending update for " + setupProvider);
lm.setTestProviderLocation(setupProvider, loc);
if (observer != null) {
synchronized (observer) {
observer.notify();
}
}
}
};
locationUpdater.start();
}
/**
* Helper class that receives a proximity intent and notifies the main class
* when received
*/
private static class TestIntentReceiver extends BroadcastReceiver {
private String mExpectedAction;
private Intent mLastReceivedIntent;
public TestIntentReceiver(String expectedAction) {
mExpectedAction = expectedAction;
mLastReceivedIntent = null;
}
public IntentFilter getFilter() {
IntentFilter filter = new IntentFilter(mExpectedAction);
return filter;
}
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null && mExpectedAction.equals(intent.getAction())) {
Log.d(LOG_TAG, "Intent Received: " + intent.toString());
mLastReceivedIntent = intent;
synchronized (this) {
notify();
}
}
}
public Intent getLastReceivedIntent() {
return mLastReceivedIntent;
}
public void clearReceivedIntents() {
mLastReceivedIntent = null;
}
}
}
|