Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a test for barometric height and some code simplification #2400

Merged
merged 2 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/androidTest/java/de/blau/android/TestUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -1383,7 +1383,7 @@ public static void scrollTo(@NonNull String text, boolean fail) {
}
}
}

/**
* Scroll to a specific text
*
Expand Down
192 changes: 192 additions & 0 deletions src/androidTest/java/de/blau/android/gpx/GpxBarometerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
package de.blau.android.gpx;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

import java.io.IOException;
import java.io.InputStream;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import android.app.Instrumentation;
import android.app.Instrumentation.ActivityMonitor;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import androidx.test.core.app.ActivityScenario;
import androidx.test.ext.junit.rules.ActivityScenarioRule;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.LargeTest;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.uiautomator.UiDevice;
import de.blau.android.App;
import de.blau.android.Logic;
import de.blau.android.Main;
import de.blau.android.Map;
import de.blau.android.MockTileServer;
import de.blau.android.R;
import de.blau.android.SignalHandler;
import de.blau.android.TestUtils;
import de.blau.android.layer.LayerType;
import de.blau.android.prefs.AdvancedPrefDatabase;
import de.blau.android.prefs.Preferences;
import de.blau.android.resources.TileLayerDatabase;
import de.blau.android.services.TrackerService;
import okhttp3.mockwebserver.MockWebServer;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class GpxBarometerTest {

public static final int TIMEOUT = 180;

Main main = null;
UiDevice device = null;
Instrumentation instrumentation = null;
MockWebServer tileServer = null;
Preferences prefs = null;

/**
* Manual start of activity so that we can set up the monitor for main
*/
@Rule
public ActivityScenarioRule<Main> activityScenarioRule = new ActivityScenarioRule<>(Main.class);

/**
* Pre-test setup
*/
@Before
public void setup() {
instrumentation = InstrumentationRegistry.getInstrumentation();
device = UiDevice.getInstance(instrumentation);
// this sets the mock location permission
instrumentation.getUiAutomation().executeShellCommand("appops set de.blau.android android:mock_location allow");

prefs = App.getPreferences(instrumentation.getTargetContext());
prefs.setGpsDistance(0);
prefs.enableBarometricHeight(true); // this needs to be set before TrackerService is created

ActivityMonitor monitor = instrumentation.addMonitor(Main.class.getName(), null, false);
ActivityScenario.launch(Main.class);

main = (Main) instrumentation.waitForMonitorWithTimeout(monitor, 30000);
instrumentation.removeMonitor(monitor);

tileServer = MockTileServer.setupTileServer(main, "ersatz_background.mbt", true);

Logic logic = App.getLogic();
Map map = main.getMap();

App.getDelegator().reset(true);
try (AdvancedPrefDatabase db = new AdvancedPrefDatabase(main)) {
db.deleteLayer(LayerType.GPX, null);
}

TestUtils.grantPermissons(device);
TestUtils.dismissStartUpDialogs(device, main);
TestUtils.stopEasyEdit(main);
TestUtils.zoomToNullIsland(logic, map);
}

/**
* Post-test teardown
*/
@After
public void teardown() {
instrumentation.waitForIdleSync();
prefs.enableBarometricHeight(false);
try {
tileServer.close();
} catch (IOException | NullPointerException e) {
// ignore
}
if (main != null) {
try (AdvancedPrefDatabase db = new AdvancedPrefDatabase(main)) {
db.deleteLayer(LayerType.GPX, null);
}
TestUtils.stopEasyEdit(main);
main.deleteDatabase(TileLayerDatabase.DATABASE_NAME);
main.finish();
} else {
System.out.println("main is null");
}
}

/**
* Turn on using barometric height, calibrate default pressure at sea level to -100m
*/
// @SdkSuppress(minSdkVersion = 26)
@Test
public void recordWithBarometricElevation() {
Intent intent = new Intent(main, TrackerService.class);
intent.putExtra(TrackerService.CALIBRATE_KEY, true);
intent.putExtra(TrackerService.CALIBRATE_HEIGHT_KEY, -100);
main.bindService(intent, main, Context.BIND_AUTO_CREATE);

main.startService(intent);
//
TestUtils.setupMockLocation(main, Criteria.ACCURACY_FINE);
// wait for the trackerservice to start
// unluckily there doesn't seem to be any elegant way to do this
int retries = 0;
synchronized (device) {
while (main.getTracker() == null && retries < 60) {
try {
device.wait(1000);
} catch (InterruptedException e) {
// Ignore
}
retries++;
if (retries >= 60) {
fail("Tracker service didn't start");
}
}
}

TestUtils.zoomToLevel(device, main, 19);
TestUtils.clickButton(device, device.getCurrentPackageName() + ":id/follow", false);

ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("short.gpx");
Track track = new Track(main, false);
track.importFromGPX(is);

// set a different current location so that the first point always gets recorded
int trackSize = track.getTrackPoints().size();
TrackPoint startPoint = track.getTrackPoints().get(trackSize / 2);
Location loc = new Location(LocationManager.GPS_PROVIDER);
loc.setLatitude(startPoint.getLatitude());
loc.setLongitude(startPoint.getLongitude());
main.getTracker().updateLocation(loc);
TestUtils.sleep();
main.invalidateOptionsMenu();

GpxTest.clickGpsButton(device);
assertTrue(TestUtils.clickText(device, false, main.getString(R.string.menu_gps_start), false, false));
GpxTest.clickAwayTip(device, main);

final CountDownLatch signal = new CountDownLatch(1);
main.getTracker().getTrack().reset(); // clear out anything saved
TestUtils.injectLocation(main, track.getTrackPoints(), Criteria.ACCURACY_FINE, 1000, new SignalHandler(signal));
try {
signal.await(TIMEOUT, TimeUnit.SECONDS);
} catch (InterruptedException e) {
fail(e.getMessage());
}
GpxTest.clickGpsButton(device);
assertTrue(TestUtils.clickText(device, false, main.getString(R.string.menu_gps_pause), true, false));

TrackPoint recorded = main.getTracker().getTrack().getTrackPoints().get(1);
assertTrue(recorded.hasAltitude());
assertEquals(-105f, recorded.getAltitude(), 1f);
}
}
53 changes: 23 additions & 30 deletions src/androidTest/java/de/blau/android/gpx/GpxTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import java.util.concurrent.TimeUnit;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
Expand Down Expand Up @@ -68,9 +67,6 @@ public class GpxTest {
MockWebServer tileServer = null;
Preferences prefs = null;

/**
* Manual start of activity so that we can set up the monitor for main
*/
@Rule
public ActivityTestRule<Main> mActivityRule = new ActivityTestRule<>(Main.class);

Expand All @@ -87,11 +83,12 @@ public void setup() {
main = mActivityRule.getActivity();

tileServer = MockTileServer.setupTileServer(main, "ersatz_background.mbt", true);
prefs = new Preferences(main);
prefs = App.getPreferences(main);
Logic logic = App.getLogic();
logic.setPrefs(prefs);
Map map = main.getMap();
map.setPrefs(main, prefs);
prefs.enableBarometricHeight(false);

App.getDelegator().reset(true);
try (AdvancedPrefDatabase db = new AdvancedPrefDatabase(main)) {
Expand Down Expand Up @@ -136,20 +133,7 @@ public void recordSaveAndImportGpx() {
TestUtils.setupMockLocation(main, Criteria.ACCURACY_FINE);
// wait for the trackerservice to start
// unluckily there doesn't seem to be any elegant way to do this
int retries = 0;
synchronized (device) {
while (main.getTracker() == null && retries < 60) {
try {
device.wait(1000);
} catch (InterruptedException e) {
// Ignore
}
retries++;
if (retries >= 60) {
fail("Tracker service didn't start");
}
}
}
checkTracker();
// set min distance to 1m
prefs.setGpsDistance(0);

Expand Down Expand Up @@ -181,7 +165,7 @@ public void recordSaveAndImportGpx() {
try {
signal.await(TIMEOUT, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Assert.fail(e.getMessage());
fail(e.getMessage());
}
clickGpsButton(device);
assertTrue(TestUtils.clickText(device, false, main.getString(R.string.menu_gps_pause), true, false));
Expand Down Expand Up @@ -234,14 +218,9 @@ public void recordSaveAndImportGpx() {
}

/**
* Start recording, pause resume, clear
* Wait until the tracker is available
*/
// @SdkSuppress(minSdkVersion = 26)
@Test
public void recordPauseAndResume() {
TestUtils.setupMockLocation(main, Criteria.ACCURACY_FINE);
// wait for the trackerservice to start
// unluckily there doesn't seem to be any elegant way to do this
private void checkTracker() {
int retries = 0;
synchronized (device) {
while (main.getTracker() == null && retries < 60) {
Expand All @@ -256,6 +235,19 @@ public void recordPauseAndResume() {
}
}
}
}

/**
* Start recording, pause resume, clear
*/
// @SdkSuppress(minSdkVersion = 26)
@Test
public void recordPauseAndResume() {
TestUtils.setupMockLocation(main, Criteria.ACCURACY_FINE);
// wait for the trackerservice to start
// unluckily there doesn't seem to be any elegant way to do this
int retries = 0;
checkTracker();
// set min distance to 1m
prefs.setGpsDistance(0);

Expand Down Expand Up @@ -287,7 +279,7 @@ public void recordPauseAndResume() {
try {
signal.await(TIMEOUT, TimeUnit.SECONDS);
} catch (InterruptedException e) {
Assert.fail(e.getMessage());
fail(e.getMessage());
}
clickGpsButton(device);
assertTrue(TestUtils.clickText(device, false, main.getString(R.string.menu_gps_pause), true, false));
Expand Down Expand Up @@ -358,11 +350,14 @@ public void importWayPoints() {
@Test
public void followNetworkLocation() {
TestUtils.setupMockLocation(main, Criteria.ACCURACY_COARSE);
checkTracker();
// set min distance to 1m
prefs.setGpsDistance(0);

TestUtils.zoomToLevel(device, main, 19);
TestUtils.clickButton(device, device.getCurrentPackageName() + ":id/follow", false);
assertTrue(main.getFollowGPS());

ClassLoader loader = Thread.currentThread().getContextClassLoader();
InputStream is = loader.getResourceAsStream("20110513_121244-tp.gpx");
Track track = new Track(main, false);
Expand All @@ -371,8 +366,6 @@ public void followNetworkLocation() {
final CountDownLatch signal = new CountDownLatch(1);
TestUtils.injectLocation(main, track.getTrackPoints(), Criteria.ACCURACY_COARSE, 1000, new SignalHandler(signal));
TestUtils.sleep(TIMEOUT * 1000L);
clickGpsButton(device);
assertTrue(TestUtils.clickText(device, false, "Pause GPX track", true, false));
// compare roughly with last location
TrackPoint lastPoint = track.getTrackPoints().get(track.getTrackPoints().size() - 1);
ViewBox box = main.getMap().getViewBox();
Expand Down
10 changes: 8 additions & 2 deletions src/main/java/de/blau/android/Main.java
Original file line number Diff line number Diff line change
Expand Up @@ -2160,17 +2160,21 @@ public void onError(String message) {
tipKeys.add(R.string.tip_gpx_no_elevation_key);
tipMessageIds.add(R.string.tip_gpx_no_elevation);
}
Tip.showDialog(Main.this, tipKeys, tipMessageIds);
if (haveTracker && haveLocationProvider(getEnabledLocationProviders(), LocationManager.GPS_PROVIDER)) {
getTracker().startTracking();
setFollowGPS(true);
}
addGpxLayer();
mapLayout.post(() -> {
triggerMenuInvalidation();
Tip.showDialog(Main.this, tipKeys, tipMessageIds);
});
return true;
case R.id.menu_gps_pause:
if (haveTracker && haveLocationProvider(getEnabledLocationProviders(), LocationManager.GPS_PROVIDER)) {
getTracker().stopTracking(false);
}
mapLayout.post(this::triggerMenuInvalidation);
return true;
case R.id.menu_gps_clear:
if (haveTracker) {
Expand Down Expand Up @@ -2745,7 +2749,6 @@ private void addGpxLayer() {
} else {
Log.e(DEBUG_TAG, "addGpxLayer tracker not available");
}
triggerMenuInvalidation();
}

/**
Expand Down Expand Up @@ -2928,6 +2931,7 @@ private List<String> getEnabledLocationProviders() {
* @param follow if true center on current location
*/
public synchronized void setFollowGPS(boolean follow) {
Log.d(DEBUG_TAG, "Set follow GPS " + follow);
if (followGPS != follow) {
followGPS = follow;
if (follow) {
Expand Down Expand Up @@ -4164,6 +4168,7 @@ public static void prepareRedownload() {
public void onServiceConnected(ComponentName name, IBinder service) {
Log.i(DEBUG_TAG, "Service " + name.getClassName() + " connected");
if (TrackerService.class.getCanonicalName().equals(name.getClassName())) {
Log.i(DEBUG_TAG, "Setting up tracker");
setTracker((((TrackerBinder) service).getService()));
map.setTracker(getTracker());
de.blau.android.layer.gpx.MapOverlay layer = (de.blau.android.layer.gpx.MapOverlay) map.getLayer(LayerType.GPX,
Expand Down Expand Up @@ -4193,6 +4198,7 @@ public void onServiceDisconnected(ComponentName name) {

@Override
public void onLocationChanged(Location location) {
Log.d(DEBUG_TAG, "follow " + followGPS + " " + location);
if (followGPS) {
ViewBox viewBox = map.getViewBox();
// ensure the view is zoomed in to at least the most zoomed-out
Expand Down
Loading