Sensor data: use monotonic clock.

Part of #1966.
This commit is contained in:
Dennis Guse
2024-12-15 17:57:04 +01:00
parent a2a9132658
commit 333bc6f31b
11 changed files with 33 additions and 25 deletions
@@ -33,7 +33,7 @@ public class BluetoothHandlerBarometricPressure implements SensorHandlerInterfac
AtmosphericPressure value = parseEnvironmentalSensing(characteristic); AtmosphericPressure value = parseEnvironmentalSensing(characteristic);
if (value == null) return; if (value == null) return;
observer.onChange(new Raw<>(value)); observer.onChange(new Raw<>(observer.getNow(), value));
} }
/** /**
@@ -33,7 +33,7 @@ public class BluetoothHandlerCyclingCadence implements SensorHandlerInterface {
if (serviceMeasurementUUID.equals(BluetoothHandlerManagerCyclingPower.CYCLING_POWER)) { if (serviceMeasurementUUID.equals(BluetoothHandlerManagerCyclingPower.CYCLING_POWER)) {
BluetoothHandlerManagerCyclingPower.Data data = BluetoothHandlerManagerCyclingPower.parseCyclingPower(characteristic); BluetoothHandlerManagerCyclingPower.Data data = BluetoothHandlerManagerCyclingPower.parseCyclingPower(characteristic);
if (data != null && data.crank() != null) { if (data != null && data.crank() != null) {
observer.onChange(new Raw<>(data.crank())); observer.onChange(new Raw<>(observer.getNow(), data.crank()));
} }
return; return;
} }
@@ -42,7 +42,7 @@ public class BluetoothHandlerCyclingCadence implements SensorHandlerInterface {
Pair<BluetoothHandlerCyclingDistanceSpeed.WheelData, CrankData> data = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel(address, sensorName, characteristic); Pair<BluetoothHandlerCyclingDistanceSpeed.WheelData, CrankData> data = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel(address, sensorName, characteristic);
if (data != null && data.second != null) { if (data != null && data.second != null) {
observer.onChange(new Raw<>(data.second)); observer.onChange(new Raw<>(observer.getNow(), data.second));
} }
return; return;
} }
@@ -34,7 +34,7 @@ public class BluetoothHandlerCyclingDistanceSpeed implements SensorHandlerInterf
public void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { public void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
Pair<WheelData, BluetoothHandlerCyclingCadence.CrankData> data = parseCyclingCrankAndWheel(address, sensorName, characteristic); Pair<WheelData, BluetoothHandlerCyclingCadence.CrankData> data = parseCyclingCrankAndWheel(address, sensorName, characteristic);
if (data.first != null) { if (data.first != null) {
observer.onChange(new Raw<>(data.first)); observer.onChange(new Raw<>(observer.getNow(), data.first));
} }
} }
@@ -35,7 +35,7 @@ public class BluetoothHandlerManagerCyclingPower implements SensorHandlerInterfa
Data cyclingPower = parseCyclingPower(characteristic); Data cyclingPower = parseCyclingPower(characteristic);
if (cyclingPower != null) { if (cyclingPower != null) {
observer.onChange(new Raw<>(cyclingPower)); observer.onChange(new Raw<>(observer.getNow(), cyclingPower));
} }
} }
@@ -45,7 +45,7 @@ public class BluetoothHandlerManagerHeartRate implements SensorHandlerInterface
HeartRate heartRate = parseHeartRate(characteristic); HeartRate heartRate = parseHeartRate(characteristic);
if (heartRate != null) { if (heartRate != null) {
observer.onChange(new Raw<>(heartRate)); observer.onChange(new Raw<>(observer.getNow(), heartRate));
} }
} }
@@ -36,7 +36,7 @@ public class BluetoothHandlerRunningSpeedAndCadence implements SensorHandlerInte
@Override @Override
public void handlePayload(SensorManager.SensorDataChangedObserver observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { public void handlePayload(SensorManager.SensorDataChangedObserver observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) {
Data data = parseRunningSpeedAndCadence(sensorName, characteristic); Data data = parseRunningSpeedAndCadence(sensorName, characteristic);
observer.onChange(new Raw<>(data)); observer.onChange(new Raw<>(observer.getNow(), data));
} }
@VisibleForTesting @VisibleForTesting
@@ -8,6 +8,8 @@ import android.util.Log;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting; import androidx.annotation.VisibleForTesting;
import java.time.Instant;
import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.data.models.TrackPoint;
import de.dennisguse.opentracks.sensors.sensorData.Aggregator; import de.dennisguse.opentracks.sensors.sensorData.Aggregator;
import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.Raw;
@@ -47,6 +49,11 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
public void onRemove(Aggregator<?, ?> aggregator) { public void onRemove(Aggregator<?, ?> aggregator) {
sensorDataSet.remove(aggregator); sensorDataSet.remove(aggregator);
} }
@Override
public Instant getNow() {
return observer.createNow();
}
}; };
private BluetoothRemoteSensorManager bluetoothSensorManager; private BluetoothRemoteSensorManager bluetoothSensorManager;
@@ -138,5 +145,7 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
void onDisconnect(Aggregator<?, ?> sensorData); void onDisconnect(Aggregator<?, ?> sensorData);
void onRemove(Aggregator<?, ?> sensorData); void onRemove(Aggregator<?, ?> sensorData);
Instant getNow();
} }
} }
@@ -22,7 +22,7 @@ public class BarometerInternal implements Driver {
private static final int SAMPLING_PERIOD = (int) TimeUnit.SECONDS.toMicros(5); private static final int SAMPLING_PERIOD = (int) TimeUnit.SECONDS.toMicros(5);
private final SensorManager.SensorDataChangedObserver listener; private final SensorManager.SensorDataChangedObserver observer;
private Context context; private Context context;
@@ -34,7 +34,7 @@ public class BarometerInternal implements Driver {
return; return;
} }
listener.onChange(new Raw<>(AtmosphericPressure.ofHPA(event.values[0]))); observer.onChange(new Raw<>(observer.getNow(), AtmosphericPressure.ofHPA(event.values[0])));
} }
@Override @Override
@@ -43,8 +43,8 @@ public class BarometerInternal implements Driver {
} }
}; };
public BarometerInternal(@NonNull SensorManager.SensorDataChangedObserver listener) { public BarometerInternal(@NonNull SensorManager.SensorDataChangedObserver observer) {
this.listener = listener; this.observer = observer;
} }
@@ -60,7 +60,7 @@ public class BarometerInternal implements Driver {
if (sensorManager.registerListener(sensorEventListener, pressureSensor, SAMPLING_PERIOD, handler)) { if (sensorManager.registerListener(sensorEventListener, pressureSensor, SAMPLING_PERIOD, handler)) {
this.context = context; this.context = context;
listener.onConnect(new AggregatorBarometer("internal", null)); observer.onConnect(new AggregatorBarometer("internal", null));
return; return;
} }
@@ -6,11 +6,11 @@ import androidx.annotation.NonNull;
import java.time.Instant; import java.time.Instant;
public record Raw<T>( public record Raw<T>(
@NonNull T value, @NonNull Instant time,
@NonNull T value
@NonNull Instant time
) { ) {
@Deprecated
public Raw(@NonNull T value) { public Raw(@NonNull T value) {
this(value, Instant.now()); //TODO We should be using the MonotonicClock this(Instant.now(), value); //TODO We should be using the MonotonicClock
} }
} }
@@ -37,7 +37,7 @@ public class GPSManager implements SensorConnector, LocationListenerCompat, GpsS
private TrackPointCreator trackPointCreator; private TrackPointCreator trackPointCreator;
private SensorManager.SensorDataChangedObserver listener; private SensorManager.SensorDataChangedObserver observer;
private Context context; private Context context;
private Handler handler; private Handler handler;
@@ -46,9 +46,9 @@ public class GPSManager implements SensorConnector, LocationListenerCompat, GpsS
private Duration gpsInterval; private Duration gpsInterval;
private Distance thresholdHorizontalAccuracy; private Distance thresholdHorizontalAccuracy;
public GPSManager(TrackPointCreator trackPointCreator, SensorManager.SensorDataChangedObserver listener) { public GPSManager(TrackPointCreator trackPointCreator, SensorManager.SensorDataChangedObserver observer) {
this.trackPointCreator = trackPointCreator; this.trackPointCreator = trackPointCreator;
this.listener = listener; this.observer = observer;
} }
public void start(@NonNull Context context, @NonNull Handler handler) { public void start(@NonNull Context context, @NonNull Handler handler) {
@@ -60,7 +60,7 @@ public class GPSManager implements SensorConnector, LocationListenerCompat, GpsS
gpsStatusManager = new GpsStatusManager(context, this, handler); gpsStatusManager = new GpsStatusManager(context, this, handler);
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
listener.onConnect(new AggregatorGPS("internal")); observer.onConnect(new AggregatorGPS("internal"));
registerLocationListener(); registerLocationListener();
gpsStatusManager.start(); gpsStatusManager.start();
@@ -82,8 +82,8 @@ public class GPSManager implements SensorConnector, LocationListenerCompat, GpsS
gpsStatusManager.stop(); gpsStatusManager.stop();
gpsStatusManager = null; gpsStatusManager = null;
listener.onDisconnect(new AggregatorGPS("internal")); observer.onDisconnect(new AggregatorGPS("internal"));
listener = null; observer = null;
trackPointCreator = null; trackPointCreator = null;
} }
@@ -139,7 +139,7 @@ public class GPSManager implements SensorConnector, LocationListenerCompat, GpsS
return; return;
} }
listener.onChange(new Raw<>(Position.of(location))); observer.onChange(new Raw<>(observer.getNow(), Position.of(location)));
} }
@Override @Override
@@ -124,8 +124,7 @@ public class TrackPointCreator implements SharedPreferences.OnSharedPreferenceCh
return new Pair<>(currentTrackPoint, sensorDataSet); return new Pair<>(currentTrackPoint, sensorDataSet);
} }
@VisibleForTesting public Instant createNow() {
Instant createNow() {
return Instant.now(clock); return Instant.now(clock);
} }