diff --git a/src/androidTest/java/de/dennisguse/opentracks/sensors/AltitudeSumManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/sensors/AltitudeSumManagerTest.java index fb8160c52..557d3ff71 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/AltitudeSumManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/AltitudeSumManagerTest.java @@ -1,33 +1,37 @@ package de.dennisguse.opentracks.sensors; +import static org.mockito.Mockito.when; + import org.junit.Assert; -import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; import de.dennisguse.opentracks.data.models.AtmosphericPressure; +import de.dennisguse.opentracks.sensors.driver.BarometerInternal; /** * NOTE: Test data is completely artificial. */ +@RunWith(MockitoJUnitRunner.class) public class AltitudeSumManagerTest { - private final AltitudeSumManager subject = new AltitudeSumManager(); - private static void addSensorValue(AltitudeSumManager altitudeSumManager, float[] values) { for (float f : values) { altitudeSumManager.onSensorValueChanged(AtmosphericPressure.ofHPA(f)); } } - @Before - public void setUp() { - subject.reset(); - } + @Mock + BarometerInternal driver; @Test public void getAltitudeGainLoss_downhill() { // given - subject.setConnected(true); + AltitudeSumManager subject = new AltitudeSumManager(driver); + + when(driver.isConnected()).thenReturn(true); // then addSensorValue(subject, new float[]{1015f, 1015.01f, 1015.02f, 1015.03f, 1015.04f, 1015.05f, 1015.06f, 1015.07f, 1015.08f, 1015.09f, 1015.10f, 1015.11f, 1015.12f, 1015.13f, 1018f, 1018.1f, 1018.1f, 1018.1f, 1018.1f}); @@ -40,7 +44,9 @@ public class AltitudeSumManagerTest { @Test public void sensorUnavailable() { // given - subject.setConnected(false); + AltitudeSumManager subject = new AltitudeSumManager(driver); + + when(driver.isConnected()).thenReturn(true); // then subject.onSensorValueChanged(AtmosphericPressure.ofHPA(999f)); diff --git a/src/main/java/de/dennisguse/opentracks/sensors/AltitudeSumManager.java b/src/main/java/de/dennisguse/opentracks/sensors/AltitudeSumManager.java index c44522405..c85ff9066 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/AltitudeSumManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/AltitudeSumManager.java @@ -1,10 +1,6 @@ package de.dennisguse.opentracks.sensors; import android.content.Context; -import android.hardware.Sensor; -import android.hardware.SensorEvent; -import android.hardware.SensorEventListener; -import android.hardware.SensorManager; import android.os.Handler; import android.util.Log; @@ -12,19 +8,18 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; -import java.util.concurrent.TimeUnit; - import de.dennisguse.opentracks.data.models.AtmosphericPressure; import de.dennisguse.opentracks.data.models.TrackPoint; +import de.dennisguse.opentracks.sensors.driver.BarometerInternal; /** * Estimates the altitude gain and altitude loss using the device's pressure sensor (i.e., barometer). */ -public class AltitudeSumManager implements SensorConnector, SensorEventListener { +public class AltitudeSumManager implements SensorConnector { private static final String TAG = AltitudeSumManager.class.getSimpleName(); - private boolean isConnected = false; + private final BarometerInternal driver; private AtmosphericPressure lastAcceptedSensorValue; @@ -33,16 +28,17 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener private Float altitudeGain_m; private Float altitudeLoss_m; - public void start(Context context, Handler handler) { - SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); + public AltitudeSumManager() { + driver = new BarometerInternal(); + } - Sensor pressureSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); - if (pressureSensor == null) { - Log.w(TAG, "No pressure sensor available."); - isConnected = false; - } else { - isConnected = sensorManager.registerListener(this, pressureSensor, (int) TimeUnit.SECONDS.toMicros(5), handler); - } + @VisibleForTesting + public AltitudeSumManager(BarometerInternal mock) { + this.driver = mock; + } + + public void start(Context context, Handler handler) { + driver.connect(context, handler, this); lastAcceptedSensorValue = null; reset(); @@ -51,18 +47,10 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener public void stop(Context context) { Log.d(TAG, "Stop"); - SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); - sensorManager.unregisterListener(this); - - isConnected = false; + driver.disconnect(context); reset(); } - @VisibleForTesting - public void setConnected(boolean isConnected) { - this.isConnected = isConnected; - } - public void fill(@NonNull TrackPoint trackPoint) { trackPoint.setAltitudeGain(altitudeGain_m); trackPoint.setAltitudeLoss(altitudeLoss_m); @@ -70,7 +58,7 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener @Nullable public Float getAltitudeGain_m() { - return isConnected ? altitudeGain_m : null; + return driver.isConnected() ? altitudeGain_m : null; } @VisibleForTesting @@ -78,21 +66,9 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener this.altitudeGain_m = altitudeGain_m; } - @VisibleForTesting - public void addAltitudeGain_m(float altitudeGain_m) { - this.altitudeGain_m = this.altitudeGain_m == null ? 0f : this.altitudeGain_m; - this.altitudeGain_m += altitudeGain_m; - } - - @VisibleForTesting - public void addAltitudeLoss_m(Float altitudeLoss_m) { - this.altitudeLoss_m = this.altitudeLoss_m == null ? 0f : this.altitudeLoss_m; - this.altitudeLoss_m += altitudeLoss_m; - } - @Nullable public Float getAltitudeLoss_m() { - return isConnected ? altitudeLoss_m : null; + return driver.isConnected() ? altitudeLoss_m : null; } @VisibleForTesting @@ -106,22 +82,7 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener altitudeLoss_m = null; } - @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) { - Log.w(TAG, "Sensor accuracy changes are (currently) ignored."); - } - - @Override - public void onSensorChanged(SensorEvent event) { - if (!isConnected) { - Log.w(TAG, "Not connected to sensor, cannot process data."); - return; - } - onSensorValueChanged(AtmosphericPressure.ofHPA(event.values[0])); - } - - @VisibleForTesting - void onSensorValueChanged(AtmosphericPressure currentSensorValue) { + public void onSensorValueChanged(AtmosphericPressure currentSensorValue) { if (lastAcceptedSensorValue == null) { lastAcceptedSensorValue = currentSensorValue; lastSeenSensorValue = currentSensorValue; diff --git a/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java b/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java new file mode 100644 index 000000000..8a405f720 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java @@ -0,0 +1,67 @@ +package de.dennisguse.opentracks.sensors.driver; + +import android.content.Context; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.os.Handler; +import android.util.Log; + +import java.util.concurrent.TimeUnit; + +import de.dennisguse.opentracks.data.models.AtmosphericPressure; +import de.dennisguse.opentracks.sensors.AltitudeSumManager; + +public class BarometerInternal { + + private static final String TAG = BarometerInternal.class.getSimpleName(); + + private static final int SAMPLING_PERIOD = (int) TimeUnit.SECONDS.toMicros(5); + + private AltitudeSumManager observer; + + private final SensorEventListener listener = new SensorEventListener() { + @Override + public void onSensorChanged(SensorEvent event) { + if (!isConnected()) { + Log.w(TAG, "Not connected to sensor, cannot process data."); + return; + } + + observer.onSensorValueChanged(AtmosphericPressure.ofHPA(event.values[0])); + } + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + Log.w(TAG, "Sensor accuracy changes are (currently) ignored."); + } + }; + + public void connect(Context context, Handler handler, AltitudeSumManager observer) { + this.observer = observer; + SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); + Sensor pressureSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE); + if (pressureSensor == null) { + Log.w(TAG, "No pressure sensor available."); + this.observer = null; + return; + } + + if (sensorManager.registerListener(listener, pressureSensor, SAMPLING_PERIOD, handler)) { + this.observer = observer; + return; + } + + disconnect(context); + } + + public void disconnect(Context context) { + SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE); + sensorManager.unregisterListener(listener); + } + + public boolean isConnected() { + return observer != null; + } +}