diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java
index bbbe58e7c..7ebc2bb5c 100644
--- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java
+++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTest.java
@@ -206,7 +206,7 @@ public class TrackRecordingServiceTest {
Assert.assertEquals(1, contentProviderUtils.getTrackPoints(trackId).size());
- //when
+ // when
service.resumeTrack(trackId);
insertLocation(service);
@@ -331,19 +331,28 @@ public class TrackRecordingServiceTest {
addTrack(dummyTrack, isRecording);
}
+ static void insertLocation(TrackRecordingServiceInterface trackRecordingService) throws InterruptedException {
+ insertLocation(trackRecordingService, 45.0f, 35f, 5, 10, System.currentTimeMillis());
+ }
+
+ static void insertLocation(TrackRecordingServiceInterface trackRecordingService, double latitude, double longitude, float accuracy, long speed) throws InterruptedException {
+ insertLocation(trackRecordingService, latitude, longitude, accuracy, speed, System.currentTimeMillis());
+ }
+
/**
* Inserts a location and waits for 200ms.
*/
- private void insertLocation(TrackRecordingServiceInterface trackRecordingService) throws InterruptedException {
+ static void insertLocation(TrackRecordingServiceInterface trackRecordingService, double latitude, double longitude, float accuracy, long speed, long time) throws InterruptedException {
Location location = new Location("gps");
- location.setLongitude(35.0f);
- location.setLatitude(45.0f);
- location.setAccuracy(5);
- location.setSpeed(10);
- location.setTime(System.currentTimeMillis());
+ location.setLongitude(longitude);
+ location.setLatitude(latitude);
+ location.setAccuracy(accuracy);
+ location.setSpeed(speed);
+ location.setTime(time);
location.setBearing(3.0f);
trackRecordingService.insertLocation(location);
+ //TODO Needed?
Thread.sleep(200);
}
}
diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLocation.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLocation.java
new file mode 100644
index 000000000..eaeda2d6c
--- /dev/null
+++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceTestLocation.java
@@ -0,0 +1,329 @@
+package de.dennisguse.opentracks.services;
+
+import android.content.ContentProvider;
+import android.content.Context;
+import android.content.SharedPreferences;
+import android.os.Looper;
+
+import androidx.test.core.app.ApplicationProvider;
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.MediumTest;
+import androidx.test.rule.GrantPermissionRule;
+import androidx.test.rule.ServiceTestRule;
+
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+import de.dennisguse.opentracks.content.data.TrackPoint;
+import de.dennisguse.opentracks.content.data.TrackPointsColumns;
+import de.dennisguse.opentracks.content.provider.ContentProviderUtils;
+import de.dennisguse.opentracks.content.provider.CustomContentProvider;
+import de.dennisguse.opentracks.content.sensor.SensorDataSet;
+import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
+import de.dennisguse.opentracks.util.PreferencesUtils;
+
+/**
+ * Tests insert location.
+ *
+ * //TODO ATTENTION: This tests deletes all stored tracks in the database.
+ * So, if it is executed on a real device, data might be lost.
+ */
+@RunWith(AndroidJUnit4.class)
+public class TrackRecordingServiceTestLocation {
+
+ @Rule
+ public final ServiceTestRule mServiceRule = ServiceTestRule.withTimeout(5, TimeUnit.SECONDS);
+
+ @Rule
+ public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);
+
+ private final Context context = ApplicationProvider.getApplicationContext();
+ private ContentProviderUtils contentProviderUtils;
+
+ private TrackRecordingServiceInterface service;
+
+ @BeforeClass
+ public static void preSetUp() {
+ // Prepare looper for Android's message queue
+ if (Looper.myLooper() == null) Looper.prepare();
+ }
+
+ @Before
+ public void setUp() throws TimeoutException {
+ // Set up the mock content resolver
+ ContentProvider customContentProvider = new CustomContentProvider() {
+ };
+ customContentProvider.attachInfo(context, null);
+
+ contentProviderUtils = new ContentProviderUtils(context);
+
+ // Let's use default values.
+ SharedPreferences sharedPreferences = PreferencesUtils.getSharedPreferences(context);
+ sharedPreferences.edit().clear().commit();
+
+ service = ((TrackRecordingServiceInterface) mServiceRule.bindService(TrackRecordingServiceTest.createStartIntent(context)));
+ //Disable executorService to not insert locations from GPS via LocationManager
+ service.enableLocationExecutor(false);
+ }
+
+ @After
+ public void tearDown() throws TimeoutException {
+ // Reset service (if some previous test failed)
+ service.enableLocationExecutor(true);
+ if (service.isRecording() || service.isPaused()) {
+ service.endCurrentTrack();
+ }
+
+ // Ensure that the database is empty after every test
+ contentProviderUtils.deleteAllTracks(context);
+ }
+
+ @MediumTest
+ @Test
+ public void testOnLocationChangedAsync_movingAccurate() throws Exception {
+ // given
+ long trackId = service.startNewTrack();
+
+ // when
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.0001, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.0002, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.0003, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.0004, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.0005, 35.0, 5, 15);
+
+ service.endCurrentTrack();
+
+ // then
+ Assert.assertFalse(service.isRecording());
+
+ List trackPoints = contentProviderUtils.getTrackPoints(trackId);
+ Assert.assertEquals(6, trackPoints.size());
+ Assert.assertEquals(45.0005, trackPoints.get(5).getLatitude(), 0.01);
+ }
+
+ @MediumTest
+ @Test
+ public void testOnLocationChangedAsync_movingInaccurate() throws Exception {
+ // given
+ long trackId = service.startNewTrack();
+
+ // when
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.1, 35.0, Long.MAX_VALUE, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.2, 35.0, Long.MAX_VALUE, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.3, 35.0, Long.MAX_VALUE, 15);
+ TrackRecordingServiceTest.insertLocation(service, 99.0, 35.0, Long.MAX_VALUE, 15);
+
+ service.endCurrentTrack();
+
+ // then
+ Assert.assertFalse(service.isRecording());
+
+ List trackPoints = contentProviderUtils.getTrackPoints(trackId);
+ Assert.assertEquals(1, trackPoints.size());
+ Assert.assertEquals(45.0, trackPoints.get(0).getLatitude(), 0.01);
+ }
+
+ @MediumTest
+ @Test
+ public void testOnLocationChangedAsync_slowMovingAccurate() throws Exception {
+ // given
+ long trackId = service.startNewTrack();
+
+ // when
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.000001, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.000002, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.000003, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.000004, 35.0, 5, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.000005, 35.0, 5, 15);
+
+ service.endCurrentTrack();
+
+ // then
+ Assert.assertFalse(service.isRecording());
+
+ List trackPoints = contentProviderUtils.getTrackPoints(trackId);
+ Assert.assertEquals(2, trackPoints.size());
+ Assert.assertEquals(45.000005, trackPoints.get(1).getLatitude(), 0.01);
+ }
+
+// @MediumTest
+// @Test
+// public void testOnLocationChangedAsync_repeatedTime() throws Exception {
+// // when
+// TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 5, 15, 5);
+// TrackRecordingServiceTest.insertLocation(service, 55.0, 35.0, 5, 15, 5);
+// TrackRecordingServiceTest.insertLocation(service, 65.0, 35.0, 5, 15, 5);
+//
+// service.endCurrentTrack();
+//
+// // then
+// Assert.assertFalse(service.isRecording());
+//
+// List trackPoints = contentProviderUtils.getTrackPoints(trackId);
+// Assert.assertEquals(1, trackPoints.size());
+// Assert.assertEquals(45.0, trackPoints.get(0).getLatitude(), 0.01);
+// }
+
+ @MediumTest
+ @Test
+ public void testOnLocationChangedAsync_idle() throws Exception {
+ // given
+ long trackId = service.startNewTrack();
+
+ // when
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 1, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 2, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 3, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 4, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 5, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 6, 0);
+
+ service.endCurrentTrack();
+
+ // then
+ Assert.assertFalse(service.isRecording());
+
+ List trackPoints = contentProviderUtils.getTrackPoints(trackId);
+ Assert.assertEquals(3, trackPoints.size());
+ Assert.assertEquals(1, trackPoints.get(0).getAccuracy(), 0.01);
+ Assert.assertEquals(2, trackPoints.get(1).getAccuracy(), 0.01);
+ Assert.assertEquals(6, trackPoints.get(2).getAccuracy(), 0.01);
+ }
+
+ @MediumTest
+ @Test
+ public void testOnLocationChangedAsync_idle_withMovement() throws Exception {
+ // given
+ long trackId = service.startNewTrack();
+
+ // when
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 1, 15);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 2, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 3, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 4, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 5, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 6, 15);
+
+ service.endCurrentTrack();
+
+ // then
+ Assert.assertFalse(service.isRecording());
+
+ List trackPoints = contentProviderUtils.getTrackPoints(trackId);
+ Assert.assertEquals(4, trackPoints.size());
+ Assert.assertEquals(1, trackPoints.get(0).getAccuracy(), 0.01);
+ Assert.assertEquals(2, trackPoints.get(1).getAccuracy(), 0.01);
+ Assert.assertEquals(5, trackPoints.get(2).getAccuracy(), 0.01); //TODO Check why this trackPoint is inserted.
+ Assert.assertEquals(6, trackPoints.get(3).getAccuracy(), 0.01);
+ }
+
+
+ @MediumTest
+ @Test
+ public void testOnLocationChangedAsync_idle_withSensorData() throws Exception {
+ // given
+ long trackId = service.startNewTrack();
+
+ service.setRemoteSensorManager(new BluetoothRemoteSensorManager(context) {
+
+ @Override
+ public boolean isEnabled() {
+ return true;
+ }
+
+ @Override
+ public boolean isSensorDataSetValid() {
+ return true;
+ }
+
+ @Override
+ public SensorDataSet getSensorDataSet() {
+ return new SensorDataSet(1, 2);
+ }
+ });
+
+ // when
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 0, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 1, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 2, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 3, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 4, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 5, 0);
+
+ service.endCurrentTrack();
+
+ // then
+ Assert.assertFalse(service.isRecording());
+
+ List trackPoints = contentProviderUtils.getTrackPoints(trackId);
+ Assert.assertEquals(6, trackPoints.size());
+ Assert.assertEquals(0, trackPoints.get(0).getAccuracy(), 0.01);
+ Assert.assertEquals(1, trackPoints.get(1).getAccuracy(), 0.01);
+ Assert.assertEquals(2, trackPoints.get(2).getAccuracy(), 0.01);
+ Assert.assertEquals(3, trackPoints.get(3).getAccuracy(), 0.01);
+ Assert.assertEquals(4, trackPoints.get(4).getAccuracy(), 0.01);
+ Assert.assertEquals(5, trackPoints.get(5).getAccuracy(), 0.01);
+ }
+
+ @MediumTest
+ @Test
+ public void testOnLocationChangedAsync_segment() throws Exception {
+ // given
+ long trackId = service.startNewTrack();
+
+ // when
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 1, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.1, 35.0, 2, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.1, 35.0, 3, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.2, 35.0, 4, 0);
+ TrackRecordingServiceTest.insertLocation(service, 45.2, 35.0, 5, 0);
+
+ service.endCurrentTrack();
+
+ // then
+ Assert.assertFalse(service.isRecording());
+
+ List trackPoints = contentProviderUtils.getTrackPoints(trackId);
+ Assert.assertEquals(7, trackPoints.size());
+ Assert.assertEquals(1, trackPoints.get(0).getAccuracy(), 0.01);
+ Assert.assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(1).getLatitude(), 0.01);
+ Assert.assertEquals(2, trackPoints.get(2).getAccuracy(), 0.01);
+ Assert.assertEquals(3, trackPoints.get(3).getAccuracy(), 0.01);
+ Assert.assertEquals(TrackPointsColumns.PAUSE_LATITUDE, trackPoints.get(4).getLatitude(), 0.01);
+ Assert.assertEquals(4, trackPoints.get(5).getAccuracy(), 0.01);
+ Assert.assertEquals(5, trackPoints.get(6).getAccuracy(), 0.01);
+ }
+
+ @MediumTest
+ @Test
+ public void testOnLocationChangedAsync_firstTrackPointInvalid() throws Exception {
+ // given
+ long trackId = service.startNewTrack();
+
+ // when
+ service.insertLocation(TrackPoint.createPause().getLocation());
+ TrackRecordingServiceTest.insertLocation(service, 45.0, 35.0, 0, 0);
+ service.insertLocation(TrackPoint.createPause().getLocation());
+
+ service.endCurrentTrack();
+
+ // then
+ Assert.assertFalse(service.isRecording());
+
+ List trackPoints = contentProviderUtils.getTrackPoints(trackId);
+ Assert.assertEquals(1, trackPoints.size());
+ Assert.assertEquals(0, trackPoints.get(0).getAccuracy(), 0.01);
+ }
+}
diff --git a/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java b/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java
index 9569bffca..a3f230bb8 100644
--- a/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java
+++ b/src/main/java/de/dennisguse/opentracks/content/data/TrackPoint.java
@@ -181,4 +181,10 @@ public class TrackPoint {
public float bearingTo(@NonNull Location dest) {
return location.bearingTo(dest);
}
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "time=" + getTime() + ": lat=" + getLatitude() + " lng=" + getLongitude() + " acc=" + getAccuracy();
+ }
}
diff --git a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java
index 971816de2..60b1677ca 100644
--- a/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java
+++ b/src/main/java/de/dennisguse/opentracks/content/sensor/SensorDataSet.java
@@ -1,5 +1,7 @@
package de.dennisguse.opentracks.content.sensor;
+import androidx.annotation.NonNull;
+
public final class SensorDataSet {
public static final float DATA_UNAVAILABLE = Float.NaN;
@@ -11,14 +13,14 @@ public final class SensorDataSet {
private float cadence;
private float power;
private float batteryLevel;
- private long creationTimestamp;
+ private long time;
- public SensorDataSet(float heartRate, float cadence, float power, float batteryLevel, long creationTimestamp) {
+ public SensorDataSet(float heartRate, float cadence, float power, float batteryLevel, long time) {
this.heartRate = heartRate;
this.cadence = cadence;
this.power = power;
this.batteryLevel = batteryLevel;
- this.creationTimestamp = creationTimestamp;
+ this.time = time;
}
public SensorDataSet(float heartRate, float cadence, float power, float batteryLevel) {
@@ -63,8 +65,8 @@ public final class SensorDataSet {
return power;
}
- public long getCreationTime() {
- return creationTimestamp;
+ public long getTime() {
+ return time;
}
/**
@@ -73,7 +75,7 @@ public final class SensorDataSet {
* @param maxAge the maximal age in milliseconds.
*/
public boolean isRecent(long maxAge) {
- return creationTimestamp + maxAge > System.currentTimeMillis();
+ return time + maxAge > System.currentTimeMillis();
}
public boolean hasBatteryLevel() {
@@ -91,4 +93,10 @@ public final class SensorDataSet {
public String getSensorAddress() {
return sensorAddress;
}
+
+ @NonNull
+ @Override
+ public String toString() {
+ return "time=" + getTime() + " sensor=" + getSensorAddress() + " heart=" + getHeartRate();
+ }
}
diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java
index 13ac70f86..8ce1ec2de 100644
--- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java
+++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java
@@ -34,6 +34,7 @@ import android.os.PowerManager.WakeLock;
import android.util.Log;
import androidx.annotation.NonNull;
+import androidx.annotation.VisibleForTesting;
import androidx.core.app.TaskStackBuilder;
import java.util.concurrent.ExecutorService;
@@ -75,7 +76,7 @@ public class TrackRecordingService extends Service {
// The following variables are set in onCreate:
@Deprecated //TODO Should not be necessary
- private ExecutorService executorService; // Enforces order of location changes.
+ private ExecutorService locationExecutorService; // Enforces order of location changes.
private ContentProviderUtils contentProviderUtils;
private LocationManager locationManager;
private PeriodicTaskExecutor voiceExecutor;
@@ -146,10 +147,10 @@ public class TrackRecordingService extends Service {
@Override
public void onLocationChanged(final Location location) {
- if (executorService == null || executorService.isShutdown() || executorService.isTerminated()) {
+ if (locationExecutorService == null || locationExecutorService.isShutdown() || locationExecutorService.isTerminated()) {
return;
}
- executorService.submit(new Runnable() {
+ locationExecutorService.submit(new Runnable() {
@Override
public void run() {
onLocationChangedAsync(location);
@@ -176,7 +177,7 @@ public class TrackRecordingService extends Service {
@Override
public void onCreate() {
super.onCreate();
- executorService = Executors.newSingleThreadExecutor();
+ locationExecutorService = Executors.newSingleThreadExecutor();
contentProviderUtils = new ContentProviderUtils(this);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
voiceExecutor = new PeriodicTaskExecutor(this, new AnnouncementPeriodicTaskFactory());
@@ -232,7 +233,7 @@ public class TrackRecordingService extends Service {
wakeLock = SystemUtils.releaseWakeLock(wakeLock);
// Shutdown the executorService last to avoid sending events to a dead executor.
- executorService.shutdown();
+ locationExecutorService.shutdown();
super.onDestroy();
}
@@ -763,4 +764,22 @@ public class TrackRecordingService extends Service {
notificationManager.cancelNotification();
}
}
+
+ /**
+ * Disables processing of location updates from {@link android.location.LocationManager}.
+ */
+ @VisibleForTesting
+ public void enableLocationExecutor(boolean enable) {
+ if (enable) {
+ locationExecutorService = Executors.newSingleThreadExecutor();
+ } else {
+ locationExecutorService.shutdownNow();
+ locationExecutorService = null;
+ }
+ }
+
+ @VisibleForTesting
+ public void setRemoteSensorManager(BluetoothRemoteSensorManager remoteSensorManager) {
+ this.remoteSensorManager = remoteSensorManager;
+ }
}
diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java
index 3836d05a0..f5ec8d004 100644
--- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java
+++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceBinder.java
@@ -5,6 +5,7 @@ import android.location.Location;
import androidx.annotation.VisibleForTesting;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
+import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
/**
* TODO: There is a bug in Android that leaks Binder instances. This bug is
@@ -92,6 +93,18 @@ class TrackRecordingServiceBinder extends android.os.Binder implements TrackReco
return trackRecordingService.getSensorDataSet();
}
+ @VisibleForTesting
+ @Override
+ public void enableLocationExecutor(boolean enable) {
+ trackRecordingService.enableLocationExecutor(enable);
+ }
+
+ @VisibleForTesting
+ @Override
+ public void setRemoteSensorManager(BluetoothRemoteSensorManager remoteSensorManager) {
+ trackRecordingService.setRemoteSensorManager(remoteSensorManager);
+ }
+
/**
* Detaches from the track recording service. Clears the reference to the
* outer class to minimize the leak.
diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java
index bc01c1dff..531206a4a 100644
--- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java
+++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceInterface.java
@@ -20,6 +20,7 @@ import android.location.Location;
import androidx.annotation.VisibleForTesting;
import de.dennisguse.opentracks.content.sensor.SensorDataSet;
+import de.dennisguse.opentracks.services.sensors.BluetoothRemoteSensorManager;
/**
* App's service.
@@ -112,4 +113,13 @@ public interface TrackRecordingServiceInterface {
* @return SensorDataSet object.
*/
SensorDataSet getSensorData();
+
+ /**
+ * Disables processing of location updates from {@link android.location.LocationManager}.
+ */
+ @VisibleForTesting
+ void enableLocationExecutor(boolean enable);
+
+ @VisibleForTesting
+ void setRemoteSensorManager(BluetoothRemoteSensorManager remoteSensorManager);
}