Cleanup: GainManager now processes AggregatorBarometer directly (instead of SensorManager).

This commit is contained in:
Dennis Guse
2026-01-27 22:23:39 +01:00
parent 289e93eb5d
commit 476f3a517b
17 changed files with 104 additions and 49 deletions
@@ -723,10 +723,9 @@ public class ExportImportTest {
private void mockAltitudeChange(TrackPointCreator trackPointCreator, Float altitudeGain) {
SensorManager sensorManager = trackPointCreator.getSensorManager();
sensorManager.reset();
if (altitudeGain == null) {
sensorManager.add(new AggregatorBarometer("test", null));
sensorManager.getAltitudeSumManager().setAggregatorBarometer(new AggregatorBarometer("test", null));
return;
}
@@ -742,7 +741,7 @@ public class ExportImportTest {
return true;
}
};
sensorManager.add(aggregatorBarometer);
sensorManager.getAltitudeSumManager().setAggregatorBarometer(aggregatorBarometer);
}
private void sendLocation(TrackPointCreator trackPointCreator, String time, double latitude, double longitude, float accuracy, float verticalAccuracy, float speed, double altitude, Float altitudeGain) {
@@ -810,7 +810,6 @@ public class TrackRecordingServiceRecordingTest {
SensorManager sensorManager = trackPointCreator.getSensorManager();
sensorManager.add(new AggregatorRunning("", ""));
sensorManager.barometer = null;
// when
String sensor1 = "2020-02-02T02:02:03Z";
@@ -965,7 +964,7 @@ public class TrackRecordingServiceRecordingTest {
}
private void mockAltitudeChange(TrackPointCreator trackPointCreator, float altitudeGain) {
trackPointCreator.getSensorManager().barometer = new AggregatorBarometer("", "") {
trackPointCreator.getSensorManager().getAltitudeSumManager().setAggregatorBarometer(new AggregatorBarometer("", "") {
@Override
public boolean hasReceivedData() {
return true;
@@ -976,7 +975,7 @@ public class TrackRecordingServiceRecordingTest {
public AltitudeGainLoss getAggregatedValue(Instant now) {
return new AltitudeGainLoss(altitudeGain, altitudeGain);
}
};
});
}
private static void sendGPSLocation(TrackPointCreator trackPointCreator, String time, double latitude, double longitude, float accuracy, long speed) {
@@ -35,6 +35,7 @@ import java.util.Optional;
import java.util.UUID;
import de.dennisguse.opentracks.sensors.driver.Driver;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface;
/**
@@ -45,7 +46,7 @@ public class BluetoothConnectionManager implements Driver {
private static final String TAG = BluetoothConnectionManager.class.getSimpleName();
private final SensorManager observer;
private final DriverObserver0 observer;
private final SensorHandlerInterface sensorHandler;
@@ -131,7 +132,7 @@ public class BluetoothConnectionManager implements Driver {
}
};
BluetoothConnectionManager(BluetoothAdapter bluetoothAdapter, SensorManager observer, SensorHandlerInterface sensorHandler) {
BluetoothConnectionManager(BluetoothAdapter bluetoothAdapter, DriverObserver0 observer, SensorHandlerInterface sensorHandler) {
this.bluetoothAdapter = bluetoothAdapter;
this.observer = observer;
this.sensorHandler = sensorHandler;
@@ -6,6 +6,7 @@ import java.util.List;
import java.util.UUID;
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.Aggregator;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer;
import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface;
@@ -28,7 +29,7 @@ public class BluetoothHandlerBarometricPressure implements SensorHandlerInterfac
}
@Override
public void handlePayload(SensorManager observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
public void handlePayload(DriverObserver0 observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
AtmosphericPressure value = parseEnvironmentalSensing(characteristic);
if (value == null) return;
@@ -6,6 +6,7 @@ import android.util.Pair;
import java.util.List;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingCadence;
import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface;
@@ -28,7 +29,7 @@ public class BluetoothHandlerCyclingCadence implements SensorHandlerInterface {
}
@Override
public void handlePayload(SensorManager observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
public void handlePayload(DriverObserver0 observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
if (serviceMeasurementUUID.equals(BluetoothHandlerCyclingPower.CYCLING_POWER)) {
BluetoothHandlerCyclingPower.Data data = BluetoothHandlerCyclingPower.parseCyclingPower(characteristic);
if (data != null && data.crank() != null) {
@@ -9,6 +9,7 @@ import androidx.annotation.VisibleForTesting;
import java.util.List;
import java.util.UUID;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingDistanceSpeed;
import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface;
@@ -30,7 +31,7 @@ public class BluetoothHandlerCyclingDistanceSpeed implements SensorHandlerInterf
}
@Override
public void handlePayload(SensorManager observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
public void handlePayload(DriverObserver0 observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
Pair<WheelData, BluetoothHandlerCyclingCadence.CrankData> data = parseCyclingCrankAndWheel(address, sensorName, characteristic);
if (data == null) return;
if (data.first == null) return;
@@ -9,6 +9,7 @@ import java.util.List;
import java.util.UUID;
import de.dennisguse.opentracks.data.models.Power;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingPower;
import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface;
@@ -30,7 +31,7 @@ public class BluetoothHandlerCyclingPower implements SensorHandlerInterface {
}
@Override
public void handlePayload(SensorManager observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
public void handlePayload(DriverObserver0 observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
Data cyclingPower = parseCyclingPower(characteristic);
if (cyclingPower == null) return;
@@ -9,6 +9,7 @@ import java.util.List;
import java.util.UUID;
import de.dennisguse.opentracks.data.models.HeartRate;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorHeartRate;
import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface;
@@ -40,7 +41,7 @@ public class BluetoothHandlerHeartRate implements SensorHandlerInterface {
}
@Override
public void handlePayload(SensorManager observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
public void handlePayload(DriverObserver0 observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
HeartRate heartRate = parseHeartRate(characteristic);
if (heartRate == null) return;
@@ -11,6 +11,7 @@ import java.util.UUID;
import de.dennisguse.opentracks.data.models.Cadence;
import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorRunning;
import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface;
@@ -33,7 +34,7 @@ public class BluetoothHandlerRunningSpeedAndCadence implements SensorHandlerInte
}
@Override
public void handlePayload(SensorManager observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
public void handlePayload(DriverObserver0 observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
Data data = parseRunningSpeedAndCadence(sensorName, characteristic);
if (data == null) return;
@@ -8,6 +8,7 @@ import java.util.List;
import java.util.UUID;
import de.dennisguse.opentracks.data.models.Temperature;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.Aggregator;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorTemperature;
import de.dennisguse.opentracks.sensors.sensorData.SensorHandlerInterface;
@@ -29,7 +30,7 @@ public class BluetoothHandlerTemperature implements SensorHandlerInterface {
}
@Override
public void handlePayload(SensorManager observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
public void handlePayload(DriverObserver0 observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
Temperature value = parseEnvironmentalSensing(characteristic);
if (value == null) return;
@@ -25,6 +25,7 @@ import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.settings.PreferencesUtils;
/**
@@ -34,6 +35,7 @@ import de.dennisguse.opentracks.settings.PreferencesUtils;
* TODO: listen for Bluetooth enabled/disabled events.
* @author Sandor Dornbush
*/
//TODO Merge into SensorManager
public class BluetoothRemoteSensorManager implements SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = BluetoothRemoteSensorManager.class.getSimpleName();
@@ -49,7 +51,7 @@ public class BluetoothRemoteSensorManager implements SharedPreferences.OnSharedP
private final BluetoothConnectionManager cyclingPower;
private final BluetoothConnectionManager runningSpeedAndCadence;
public BluetoothRemoteSensorManager(@NonNull Context context, @NonNull Handler handler, @Nullable SensorManager observer) {
public BluetoothRemoteSensorManager(@NonNull Context context, @NonNull Handler handler, @Nullable DriverObserver0 observer) {
this.context = context;
this.handler = handler;
@@ -5,20 +5,24 @@ import android.content.SharedPreferences;
import android.os.Handler;
import android.util.Log;
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.sensors.driver.BarometerInternal;
import de.dennisguse.opentracks.sensors.driver.Driver;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.Aggregator;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer;
import de.dennisguse.opentracks.settings.PreferencesUtils;
/**
* Estimates the altitude gain and altitude loss using the device's pressure sensor (i.e., barometer).
*/
public class GainManager {
//TODO Rename class
public class GainManager implements DriverObserver0 {
private static final String TAG = GainManager.class.getSimpleName();
private final SensorManager listener;
private final SensorManager sensorManager;
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> connect();
@@ -26,8 +30,10 @@ public class GainManager {
private Handler handler;
private Driver driver;
public GainManager(SensorManager listener) {
this.listener = listener;
private AggregatorBarometer aggregatorBarometer;
public GainManager(SensorManager sensorManager) {
this.sensorManager = sensorManager;
}
public void start(Context context, Handler handler) {
@@ -42,24 +48,32 @@ public class GainManager {
this.handler = null;
PreferencesUtils.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
onDisconnect();
disconnect();
}
@Deprecated
public AggregatorBarometer getAggregatorBarometer() {
return aggregatorBarometer;
}
@Deprecated
public void setAggregatorBarometer(AggregatorBarometer aggregatorBarometer) {
this.aggregatorBarometer = aggregatorBarometer;
}
private void connect() {
onDisconnect();
disconnect();
String address = PreferencesUtils.getBarometerSensorAddress();
switch (PreferencesUtils.getSensorType(address)) {
case NONE -> {
driver = null;
listener.onRemove(new AggregatorBarometer(null, null));
return;
}
case INTERNAL -> driver = new BarometerInternal(listener);
case INTERNAL -> driver = new BarometerInternal(this);
case REMOTE -> driver =
new BluetoothConnectionManager(
BluetoothUtils.getAdapter(context),
listener,
this,
new BluetoothHandlerBarometricPressure()
);
default -> throw new RuntimeException("Not implemented");
@@ -68,10 +82,31 @@ public class GainManager {
driver.connect(context, handler, address);
}
private void onDisconnect() {
private void disconnect() {
if (driver == null) return;
driver.disconnect();
listener.onDisconnect(new AggregatorBarometer("GainManager", null));
driver = null;
}
@Override
public void onRemove(Aggregator<?, ?> emptySensorData) {
this.aggregatorBarometer = null;
}
@Override
public void onConnect(Aggregator<?, ?> emptySensorData) {
//TODO Aggregator should be created here.
this.aggregatorBarometer = (AggregatorBarometer) emptySensorData;
}
@Override
public void onDisconnect(Aggregator<?, ?> emptySensorData) {
this.aggregatorBarometer.resetAggregated();
}
@Override
public void onChange(Record first) {
this.aggregatorBarometer.add(sensorManager.getNow(), (AtmosphericPressure) first);
}
}
@@ -12,13 +12,13 @@ import androidx.annotation.VisibleForTesting;
import java.time.Instant;
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.data.models.Cadence;
import de.dennisguse.opentracks.data.models.Distance;
import de.dennisguse.opentracks.data.models.HeartRate;
import de.dennisguse.opentracks.data.models.Position;
import de.dennisguse.opentracks.data.models.Speed;
import de.dennisguse.opentracks.data.models.Temperature;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
import de.dennisguse.opentracks.sensors.sensorData.Aggregator;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorCyclingCadence;
@@ -35,7 +35,8 @@ import de.dennisguse.opentracks.settings.PreferencesUtils;
import de.dennisguse.opentracks.util.SystemUtils;
//TODO provide context and handler for different Managers (not passing via start(), but similar to getNow()).
public class SensorManager implements SharedPreferences.OnSharedPreferenceChangeListener {
//TODO Remove DriverObserver from SensorManager
public class SensorManager implements SharedPreferences.OnSharedPreferenceChangeListener, DriverObserver0 {
private static final String TAG = SensorManager.class.getSimpleName();
@@ -100,7 +101,7 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
if (cyclingDistanceSpeed != null) cyclingDistanceSpeed.resetAggregated();
if (cyclingPower != null) cyclingPower.resetAggregated();
if (runningDistanceSpeedCadence != null) runningDistanceSpeedCadence.resetAggregated();
if (barometer != null) barometer.resetAggregated();
if (altitudeSumManager.getAggregatorBarometer() != null) altitudeSumManager.getAggregatorBarometer().resetAggregated();
if (gpsManager.getAggregatorGPS() != null) gpsManager.getAggregatorGPS().resetAggregated();
}
@@ -166,9 +167,6 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
@VisibleForTesting
public AggregatorRunning runningDistanceSpeedCadence;
@VisibleForTesting
public AggregatorBarometer barometer;
@VisibleForTesting
public SensorData<HeartRate> getHeartRate(Instant now) {
if (heartRate != null) {
@@ -264,10 +262,6 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
this.cyclingPower.add(now, (BluetoothHandlerCyclingPower.Data) value);
return;
}
if (value instanceof AtmosphericPressure) {
this.barometer.add(now, (AtmosphericPressure) value);
return;
}
throw new UnsupportedOperationException(value.getClass().getCanonicalName());
}
@@ -286,9 +280,11 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
this.cyclingDistanceSpeed = null;
this.cyclingPower = null;
this.runningDistanceSpeedCadence = null;
this.barometer = null;
//TODO This is to ExportImportTest alive; refactor test.
if (this.altitudeSumManager != null) {
this.altitudeSumManager.setAggregatorBarometer(null);
}
if (this.gpsManager != null) {
this.gpsManager.setAggregatorGPS();
}
@@ -296,6 +292,7 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
public SensorDataSet getSensorDataSet(Instant now) {
AggregatorGPS gps = gpsManager.getAggregatorGPS();
AggregatorBarometer barometer = altitudeSumManager.getAggregatorBarometer();
return new SensorDataSet(
gps != null && gps.hasReceivedData() ? gps.getAggregatedValueWithSensorName(now) : new SensorData<>(Position.of(now), ""),
@@ -337,10 +334,6 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
runningDistanceSpeedCadence = (AggregatorRunning) sensorData;
return;
}
if (type instanceof AggregatorBarometer) {
barometer = (AggregatorBarometer) sensorData;
return;
}
throw new UnsupportedOperationException(type.getClass().getCanonicalName());
}
@@ -12,7 +12,6 @@ import androidx.annotation.NonNull;
import java.util.concurrent.TimeUnit;
import de.dennisguse.opentracks.data.models.AtmosphericPressure;
import de.dennisguse.opentracks.sensors.SensorManager;
import de.dennisguse.opentracks.sensors.sensorData.AggregatorBarometer;
public class BarometerInternal implements Driver {
@@ -21,7 +20,7 @@ public class BarometerInternal implements Driver {
private static final int SAMPLING_PERIOD = (int) TimeUnit.SECONDS.toMicros(5);
private final SensorManager observer;
private final DriverObserver0 observer;
private Context context;
@@ -42,9 +41,8 @@ public class BarometerInternal implements Driver {
}
};
public BarometerInternal(@NonNull SensorManager observer) {
public BarometerInternal(@NonNull DriverObserver0 observer) {
this.observer = observer;
}
@Override
@@ -66,6 +64,7 @@ public class BarometerInternal implements Driver {
disconnect();
}
@Override
public boolean isConnected() {
return context != null;
}
@@ -6,6 +6,7 @@ import android.os.Handler;
public interface Driver {
void connect(Context context, Handler handler, String address);
//TODO Remove from interface?
boolean isConnected();
void disconnect();
@@ -0,0 +1,19 @@
package de.dennisguse.opentracks.sensors.driver;
import de.dennisguse.opentracks.sensors.sensorData.Aggregator;
//TODO Make onChange parametrized
public interface DriverObserver0 {
//TODO Pass SensorName as parameter only
void onConnect(Aggregator<?,?> emptySensorData);
//TODO Remove parameter
void onDisconnect(Aggregator<?,?> emptySensorData);
//TODO Remove parameter
void onRemove(Aggregator<?,?> emptySensorData);
void onChange(Record value);
}
@@ -4,8 +4,8 @@ import android.bluetooth.BluetoothGattCharacteristic;
import java.util.List;
import de.dennisguse.opentracks.sensors.SensorManager;
import de.dennisguse.opentracks.sensors.ServiceMeasurementUUID;
import de.dennisguse.opentracks.sensors.driver.DriverObserver0;
public interface SensorHandlerInterface {
@@ -13,5 +13,5 @@ public interface SensorHandlerInterface {
Aggregator<?, ?> createEmptySensorData(String address, String name);
void handlePayload(SensorManager observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic);
void handlePayload(DriverObserver0 observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic);
}