forked from upstream-mirrors/OpenTracks
@@ -1,33 +1,37 @@
|
|||||||
package de.dennisguse.opentracks.sensors;
|
package de.dennisguse.opentracks.sensors;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
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.data.models.AtmosphericPressure;
|
||||||
|
import de.dennisguse.opentracks.sensors.driver.BarometerInternal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* NOTE: Test data is completely artificial.
|
* NOTE: Test data is completely artificial.
|
||||||
*/
|
*/
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class AltitudeSumManagerTest {
|
public class AltitudeSumManagerTest {
|
||||||
|
|
||||||
private final AltitudeSumManager subject = new AltitudeSumManager();
|
|
||||||
|
|
||||||
private static void addSensorValue(AltitudeSumManager altitudeSumManager, float[] values) {
|
private static void addSensorValue(AltitudeSumManager altitudeSumManager, float[] values) {
|
||||||
for (float f : values) {
|
for (float f : values) {
|
||||||
altitudeSumManager.onSensorValueChanged(AtmosphericPressure.ofHPA(f));
|
altitudeSumManager.onSensorValueChanged(AtmosphericPressure.ofHPA(f));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Before
|
@Mock
|
||||||
public void setUp() {
|
BarometerInternal driver;
|
||||||
subject.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void getAltitudeGainLoss_downhill() {
|
public void getAltitudeGainLoss_downhill() {
|
||||||
// given
|
// given
|
||||||
subject.setConnected(true);
|
AltitudeSumManager subject = new AltitudeSumManager(driver);
|
||||||
|
|
||||||
|
when(driver.isConnected()).thenReturn(true);
|
||||||
|
|
||||||
// then
|
// 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});
|
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
|
@Test
|
||||||
public void sensorUnavailable() {
|
public void sensorUnavailable() {
|
||||||
// given
|
// given
|
||||||
subject.setConnected(false);
|
AltitudeSumManager subject = new AltitudeSumManager(driver);
|
||||||
|
|
||||||
|
when(driver.isConnected()).thenReturn(true);
|
||||||
|
|
||||||
// then
|
// then
|
||||||
subject.onSensorValueChanged(AtmosphericPressure.ofHPA(999f));
|
subject.onSensorValueChanged(AtmosphericPressure.ofHPA(999f));
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
package de.dennisguse.opentracks.sensors;
|
package de.dennisguse.opentracks.sensors;
|
||||||
|
|
||||||
import android.content.Context;
|
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.os.Handler;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
@@ -12,19 +8,18 @@ import androidx.annotation.NonNull;
|
|||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.VisibleForTesting;
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
|
||||||
|
|
||||||
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
|
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
|
||||||
import de.dennisguse.opentracks.data.models.TrackPoint;
|
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).
|
* 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 static final String TAG = AltitudeSumManager.class.getSimpleName();
|
||||||
|
|
||||||
private boolean isConnected = false;
|
private final BarometerInternal driver;
|
||||||
|
|
||||||
private AtmosphericPressure lastAcceptedSensorValue;
|
private AtmosphericPressure lastAcceptedSensorValue;
|
||||||
|
|
||||||
@@ -33,16 +28,17 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener
|
|||||||
private Float altitudeGain_m;
|
private Float altitudeGain_m;
|
||||||
private Float altitudeLoss_m;
|
private Float altitudeLoss_m;
|
||||||
|
|
||||||
public void start(Context context, Handler handler) {
|
public AltitudeSumManager() {
|
||||||
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
driver = new BarometerInternal();
|
||||||
|
}
|
||||||
|
|
||||||
Sensor pressureSensor = sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE);
|
@VisibleForTesting
|
||||||
if (pressureSensor == null) {
|
public AltitudeSumManager(BarometerInternal mock) {
|
||||||
Log.w(TAG, "No pressure sensor available.");
|
this.driver = mock;
|
||||||
isConnected = false;
|
}
|
||||||
} else {
|
|
||||||
isConnected = sensorManager.registerListener(this, pressureSensor, (int) TimeUnit.SECONDS.toMicros(5), handler);
|
public void start(Context context, Handler handler) {
|
||||||
}
|
driver.connect(context, handler, this);
|
||||||
|
|
||||||
lastAcceptedSensorValue = null;
|
lastAcceptedSensorValue = null;
|
||||||
reset();
|
reset();
|
||||||
@@ -51,18 +47,10 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener
|
|||||||
public void stop(Context context) {
|
public void stop(Context context) {
|
||||||
Log.d(TAG, "Stop");
|
Log.d(TAG, "Stop");
|
||||||
|
|
||||||
SensorManager sensorManager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
|
driver.disconnect(context);
|
||||||
sensorManager.unregisterListener(this);
|
|
||||||
|
|
||||||
isConnected = false;
|
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
|
||||||
public void setConnected(boolean isConnected) {
|
|
||||||
this.isConnected = isConnected;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void fill(@NonNull TrackPoint trackPoint) {
|
public void fill(@NonNull TrackPoint trackPoint) {
|
||||||
trackPoint.setAltitudeGain(altitudeGain_m);
|
trackPoint.setAltitudeGain(altitudeGain_m);
|
||||||
trackPoint.setAltitudeLoss(altitudeLoss_m);
|
trackPoint.setAltitudeLoss(altitudeLoss_m);
|
||||||
@@ -70,7 +58,7 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener
|
|||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public Float getAltitudeGain_m() {
|
public Float getAltitudeGain_m() {
|
||||||
return isConnected ? altitudeGain_m : null;
|
return driver.isConnected() ? altitudeGain_m : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -78,21 +66,9 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener
|
|||||||
this.altitudeGain_m = altitudeGain_m;
|
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
|
@Nullable
|
||||||
public Float getAltitudeLoss_m() {
|
public Float getAltitudeLoss_m() {
|
||||||
return isConnected ? altitudeLoss_m : null;
|
return driver.isConnected() ? altitudeLoss_m : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
@@ -106,22 +82,7 @@ public class AltitudeSumManager implements SensorConnector, SensorEventListener
|
|||||||
altitudeLoss_m = null;
|
altitudeLoss_m = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public void onSensorValueChanged(AtmosphericPressure currentSensorValue) {
|
||||||
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) {
|
|
||||||
if (lastAcceptedSensorValue == null) {
|
if (lastAcceptedSensorValue == null) {
|
||||||
lastAcceptedSensorValue = currentSensorValue;
|
lastAcceptedSensorValue = currentSensorValue;
|
||||||
lastSeenSensorValue = currentSensorValue;
|
lastSeenSensorValue = currentSensorValue;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user