mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 17:43:06 +02:00
Extract SensorHandler from GainManager for re-use.
This commit is contained in:
@@ -1,132 +1,69 @@
|
||||
package de.dennisguse.opentracks.sensors;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import de.dennisguse.opentracks.R;
|
||||
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.DriverObserver;
|
||||
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).
|
||||
*/
|
||||
//TODO Rename class
|
||||
public class GainManager implements DriverObserver<AtmosphericPressure> {
|
||||
|
||||
private static final String TAG = GainManager.class.getSimpleName();
|
||||
|
||||
|
||||
private final SensorManager sensorManager;
|
||||
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> connect();
|
||||
|
||||
private Context context;
|
||||
private Handler handler;
|
||||
private Driver driver;
|
||||
|
||||
private AggregatorBarometer aggregatorBarometer;
|
||||
public class GainManager extends SensorHandler<AtmosphericPressure> {
|
||||
|
||||
public GainManager(SensorManager sensorManager) {
|
||||
this.sensorManager = sensorManager;
|
||||
}
|
||||
|
||||
public void start(Context context, Handler handler) {
|
||||
this.context = context;
|
||||
this.handler = handler;
|
||||
PreferencesUtils.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
Log.d(TAG, "Stop");
|
||||
this.context = null;
|
||||
this.handler = null;
|
||||
PreferencesUtils.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
|
||||
disconnect();
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public AggregatorBarometer getAggregatorBarometer() {
|
||||
return aggregatorBarometer;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void setAggregatorBarometer(AggregatorBarometer aggregatorBarometer) {
|
||||
this.aggregatorBarometer = aggregatorBarometer;
|
||||
}
|
||||
|
||||
private void connect() {
|
||||
disconnect();
|
||||
|
||||
String address = PreferencesUtils.getBarometerSensorAddress();
|
||||
switch (PreferencesUtils.getSensorType(address)) {
|
||||
case NONE -> {
|
||||
return;
|
||||
}
|
||||
case INTERNAL -> driver = new BarometerInternal(this);
|
||||
case REMOTE -> driver =
|
||||
new BluetoothConnectionManager(
|
||||
BluetoothUtils.getAdapter(context),
|
||||
new DriverObserver0() {
|
||||
@Override
|
||||
public void onConnect(Aggregator<?, ?> emptySensorData) {
|
||||
GainManager.this.onConnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(Aggregator<?, ?> emptySensorData) {
|
||||
GainManager.this.onDisconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(Aggregator<?, ?> emptySensorData) {
|
||||
GainManager.this.onRemove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(Record value) {
|
||||
onData((AtmosphericPressure) value);
|
||||
}
|
||||
},
|
||||
new BluetoothHandlerBarometricPressure()
|
||||
);
|
||||
default -> throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
driver.connect(context, handler, address);
|
||||
}
|
||||
|
||||
private void disconnect() {
|
||||
if (driver == null) return;
|
||||
|
||||
driver.disconnect();
|
||||
driver = null;
|
||||
super(sensorManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConnect() {
|
||||
this.aggregatorBarometer = new AggregatorBarometer("", null);
|
||||
protected int getSensorPreferenceKey() {
|
||||
return R.string.settings_sensor_bluetooth_pressure_key;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public void onDisconnect() {
|
||||
this.aggregatorBarometer.resetAggregated();
|
||||
protected Driver createDriverInternal() {
|
||||
return new BarometerInternal(driverObserver);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public void onData(AtmosphericPressure value) {
|
||||
this.aggregatorBarometer.add(sensorManager.getNow(), value);
|
||||
protected Driver createDriverBluetooth(String address) {
|
||||
return new BluetoothConnectionManager(
|
||||
BluetoothUtils.getAdapter(getContext()),
|
||||
new DriverObserver0() {
|
||||
@Override
|
||||
public void onConnect(Aggregator<?, ?> emptySensorData) {
|
||||
driverObserver.onConnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect(Aggregator<?, ?> emptySensorData) {
|
||||
driverObserver.onDisconnect();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove(Aggregator<?, ?> emptySensorData) {
|
||||
driverObserver.onRemove();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onChange(Record value) {
|
||||
driverObserver.onData((AtmosphericPressure) value);
|
||||
}
|
||||
},
|
||||
new BluetoothHandlerBarometricPressure()
|
||||
);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public void onRemove() {
|
||||
this.aggregatorBarometer = null;
|
||||
public Aggregator<AtmosphericPressure, ?> createAggregator() {
|
||||
return new AggregatorBarometer("", null);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,126 @@
|
||||
package de.dennisguse.opentracks.sensors;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import de.dennisguse.opentracks.sensors.driver.Driver;
|
||||
import de.dennisguse.opentracks.sensors.driver.DriverObserver;
|
||||
import de.dennisguse.opentracks.sensors.sensorData.Aggregator;
|
||||
import de.dennisguse.opentracks.settings.PreferencesUtils;
|
||||
|
||||
|
||||
public abstract class SensorHandler<T> {
|
||||
|
||||
private final SensorManager sensorManager;
|
||||
|
||||
private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> connect();
|
||||
|
||||
private Context context;
|
||||
private Handler handler;
|
||||
private Driver driver;
|
||||
|
||||
private Aggregator<T, ?> aggregator;
|
||||
|
||||
protected final DriverObserver<T> driverObserver = new DriverObserver<T>() {
|
||||
@Override
|
||||
public void onConnect() {
|
||||
SensorHandler.this.aggregator = createAggregator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnect() {
|
||||
SensorHandler.this.aggregator.resetAggregated();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onData(T value) {
|
||||
SensorHandler.this.aggregator.add(sensorManager.getNow(), value);
|
||||
sensorManager.onChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemove() {
|
||||
SensorHandler.this.aggregator = null;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected SensorHandler(SensorManager sensorManager) {
|
||||
this.sensorManager = sensorManager;
|
||||
}
|
||||
|
||||
//TODO Do we really need start and stop?
|
||||
void start(Context context, Handler handler) {
|
||||
this.context = context;
|
||||
this.handler = handler;
|
||||
PreferencesUtils.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
}
|
||||
|
||||
void stop() {
|
||||
this.context = null;
|
||||
this.handler = null;
|
||||
PreferencesUtils.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener);
|
||||
|
||||
disconnect();
|
||||
}
|
||||
|
||||
void connect() {
|
||||
disconnect();
|
||||
|
||||
String address = PreferencesUtils.getString(getSensorPreferenceKey(), PreferencesUtils.getBluetoothSensorAddressNone());
|
||||
|
||||
switch (PreferencesUtils.getSensorType(address)) {
|
||||
case NONE -> {
|
||||
return;
|
||||
}
|
||||
case INTERNAL -> {
|
||||
driver = createDriverInternal();
|
||||
}
|
||||
case REMOTE -> {
|
||||
driver = createDriverBluetooth(address);
|
||||
}
|
||||
default -> throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
driver.connect(context, handler, address);
|
||||
}
|
||||
|
||||
void disconnect() {
|
||||
if (driver == null) return;
|
||||
|
||||
driver.disconnect();
|
||||
driver = null;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected Driver createDriverInternal() {
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected Driver createDriverBluetooth(String address) {
|
||||
throw new RuntimeException("Not implemented");
|
||||
}
|
||||
|
||||
@NonNull
|
||||
protected abstract Aggregator<T, ?> createAggregator();
|
||||
|
||||
protected Context getContext() {
|
||||
return context;
|
||||
}
|
||||
|
||||
//TODO Try to keep aggregator private.
|
||||
Aggregator<T, ?> getAggregator() {
|
||||
return aggregator;
|
||||
}
|
||||
|
||||
//TODO REMOVE
|
||||
@VisibleForTesting
|
||||
public void setAggregator(Aggregator<T, ?> aggregator) {
|
||||
this.aggregator = aggregator;
|
||||
}
|
||||
}
|
||||
@@ -84,10 +84,11 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
|
||||
this.cyclingPowerManager = new BluetoothConnectionManager(bluetoothAdapter, this, new BluetoothHandlerCyclingPower());
|
||||
this.runningSpeedAndCadenceManager = new BluetoothConnectionManager(bluetoothAdapter, this, new BluetoothHandlerRunningSpeedAndCadence());
|
||||
|
||||
altitudeSumManager.start(context, handler);
|
||||
|
||||
onSharedPreferenceChanged(null, null);
|
||||
|
||||
gpsManager.start(context, handler);
|
||||
altitudeSumManager.start(context, handler);
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
@@ -137,7 +138,7 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
|
||||
if (cyclingDistanceSpeed != null) cyclingDistanceSpeed.resetAggregated();
|
||||
if (cyclingPower != null) cyclingPower.resetAggregated();
|
||||
if (runningDistanceSpeedCadence != null) runningDistanceSpeedCadence.resetAggregated();
|
||||
if (altitudeSumManager.getAggregatorBarometer() != null) altitudeSumManager.getAggregatorBarometer().resetAggregated();
|
||||
if (altitudeSumManager.getAggregator() != null) altitudeSumManager.getAggregator().resetAggregated();
|
||||
if (gpsManager.getAggregatorGPS() != null) gpsManager.getAggregatorGPS().resetAggregated();
|
||||
}
|
||||
|
||||
@@ -355,7 +356,7 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
|
||||
|
||||
//TODO This is to ExportImportTest alive; refactor test.
|
||||
if (this.altitudeSumManager != null) {
|
||||
this.altitudeSumManager.setAggregatorBarometer(null);
|
||||
this.altitudeSumManager.setAggregator(null);
|
||||
}
|
||||
if (this.gpsManager != null) {
|
||||
this.gpsManager.setAggregatorGPS();
|
||||
@@ -364,7 +365,7 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
|
||||
|
||||
public SensorDataSet getSensorDataSet(Instant now) {
|
||||
AggregatorGPS gps = gpsManager.getAggregatorGPS();
|
||||
AggregatorBarometer barometer = altitudeSumManager.getAggregatorBarometer();
|
||||
AggregatorBarometer barometer = (AggregatorBarometer) altitudeSumManager.getAggregator();
|
||||
|
||||
return new SensorDataSet(
|
||||
gps != null && gps.hasReceivedData() ? gps.getAggregatedValueWithSensorName(now) : new SensorData<>(Position.of(now), ""),
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
package de.dennisguse.opentracks.sensors;
|
||||
|
||||
public enum SensorType {
|
||||
NONE("NONE"),
|
||||
INTERNAL("INTERNAL"),
|
||||
NONE("NONE"), //TODO Use R.string.sensor_type_value_none
|
||||
INTERNAL("INTERNAL"), //TODO Use R.string.sensor_type_value_none
|
||||
|
||||
//NOTE: preferenceValue of REMOTE should not be used anywhere.
|
||||
REMOTE("*");
|
||||
|
||||
@@ -4,6 +4,8 @@ import android.content.Context;
|
||||
import android.os.Handler;
|
||||
|
||||
public interface Driver {
|
||||
|
||||
//TODO Address is optional for internal drivers. Move address to driver instantiation.
|
||||
void connect(Context context, Handler handler, String address);
|
||||
|
||||
//TODO Remove from interface?
|
||||
|
||||
@@ -253,7 +253,7 @@ public class PreferencesUtils {
|
||||
return isReportSpeed(track.activityTypeLocalized());
|
||||
}
|
||||
|
||||
private static String getBluetoothSensorAddressNone() {
|
||||
public static String getBluetoothSensorAddressNone() {
|
||||
return SensorType.NONE.getPreferenceValue();
|
||||
}
|
||||
|
||||
@@ -264,10 +264,6 @@ public class PreferencesUtils {
|
||||
.orElse(SensorType.REMOTE);
|
||||
}
|
||||
|
||||
public static String getBarometerSensorAddress() {
|
||||
return getString(R.string.settings_sensor_bluetooth_pressure_key, getBluetoothSensorAddressNone());
|
||||
}
|
||||
|
||||
public static String getBluetoothHeartRateSensorAddress() {
|
||||
return getString(R.string.settings_sensor_bluetooth_heart_rate_key, getBluetoothSensorAddressNone());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user