diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java index d5c8fa6606..1e7106e02a 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/ExportImportTest.java @@ -157,7 +157,7 @@ public void setUp() throws TimeoutException { contentProviderUtils.insertMarker(new Marker("Marker 2", "Marker 2 desc", "Marker 2 category", null, trackId, service.getLastStoredTrackPointWithLocation(), "")); trackPointCreator.setClock("2020-02-02T02:02:18Z"); - trackPointCreator.getSensorManager().sensorDataSet = new SensorDataSet(); + trackPointCreator.getSensorManager().sensorDataSet = new SensorDataSet(trackPointCreator); service.endCurrentTrack(); trackPointCreator.setClock("2020-02-02T02:03:20Z"); @@ -172,7 +172,7 @@ public void setUp() throws TimeoutException { sendLocation(trackPointCreator, "2020-02-02T02:03:50Z", 3, 16.001, 10, 27, 15, 10, 0f); - trackPointCreator.getSensorManager().sensorDataSet = new SensorDataSet(); + trackPointCreator.getSensorManager().sensorDataSet = new SensorDataSet(trackPointCreator); trackPointCreator.setClock("2020-02-02T02:04:00Z"); service.endCurrentTrack(); @@ -550,22 +550,22 @@ private void mockSensorData(TrackPointCreator trackPointCreator, Float speed, Di AggregatorCyclingPower cyclingPower = Mockito.mock(AggregatorCyclingPower.class); Mockito.when(cyclingPower.hasValue()).thenReturn(true); - Mockito.when(cyclingPower.getValue()).thenReturn(Power.of(power)); + Mockito.when(cyclingPower.getValue(Mockito.any())).thenReturn(Power.of(power)); sensorDataSet.add(cyclingPower); - AggregatorHeartRate agheartRate = Mockito.mock(AggregatorHeartRate.class); - Mockito.when(agheartRate.getValue()).thenReturn(HeartRate.of(heartRate)); - sensorDataSet.add(agheartRate); + AggregatorHeartRate avgHeartRate = Mockito.mock(AggregatorHeartRate.class); + Mockito.when(avgHeartRate.getValue(Mockito.any())).thenReturn(HeartRate.of(heartRate)); + sensorDataSet.add(avgHeartRate); AggregatorCyclingCadence cyclingCadence = Mockito.mock(AggregatorCyclingCadence.class); Mockito.when(cyclingCadence.hasValue()).thenReturn(true); - Mockito.when(cyclingCadence.getValue()).thenReturn(Cadence.of(cadence)); + Mockito.when(cyclingCadence.getValue(Mockito.any())).thenReturn(Cadence.of(cadence)); sensorDataSet.add(cyclingCadence); if (distance != null && speed != null) { AggregatorCyclingDistanceSpeed distanceSpeed = Mockito.mock(AggregatorCyclingDistanceSpeed.class); Mockito.when(distanceSpeed.hasValue()).thenReturn(true); - Mockito.when(distanceSpeed.getValue()).thenReturn(new AggregatorCyclingDistanceSpeed.Data(null, distance, Speed.of(speed))); + Mockito.when(distanceSpeed.getValue(Mockito.any())).thenReturn(new AggregatorCyclingDistanceSpeed.Data(null, distance, Speed.of(speed))); sensorDataSet.add(distanceSpeed); } else { sensorDataSet.add(new AggregatorCyclingDistanceSpeed("", "")); @@ -582,7 +582,7 @@ private void mockAltitudeChange(TrackPointCreator trackPointCreator, Float altit if (altitudeGain != null) { AggregatorBarometer barometer = Mockito.mock(AggregatorBarometer.class); Mockito.when(barometer.hasValue()).thenReturn(true); - Mockito.when(barometer.getValue()).thenReturn(new AltitudeGainLoss(altitudeGain, altitudeGain)); + Mockito.when(barometer.getValue(Mockito.any())).thenReturn(new AltitudeGainLoss(altitudeGain, altitudeGain)); sensorDataSet.add(barometer); } else { sensorDataSet.add(new AggregatorBarometer("test", null)); diff --git a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometerTest.java b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometerTest.java index 88db170fc6..7e8373c74c 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/AggregatorBarometerTest.java @@ -3,13 +3,15 @@ import org.junit.Assert; import org.junit.Test; +import java.time.Instant; + import de.dennisguse.opentracks.data.models.AtmosphericPressure; public class AggregatorBarometerTest { private static void addSensorValue(AggregatorBarometer aggregatorBarometer, float[] values) { for (float f : values) { - aggregatorBarometer.add(new Raw<>(AtmosphericPressure.ofHPA(f))); + aggregatorBarometer.add(new Raw<>(Instant.MIN, AtmosphericPressure.ofHPA(f))); } } diff --git a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java index ca3e18949f..161c04e8d5 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataCyclingTest.java @@ -9,6 +9,8 @@ import org.junit.Test; import org.junit.runner.RunWith; +import java.time.Instant; + import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.sensors.BluetoothHandlerCyclingCadence; @@ -23,11 +25,11 @@ public void compute_cadence_1() { AggregatorCyclingCadence current = new AggregatorCyclingCadence("", ""); // when - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 1024))); - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(2, 2048))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(1, 1024))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(2, 2048))); // then - assertEquals(60, current.getValue().getRPM(), 0.01); + assertEquals(60, current.getValue(Instant.MIN).getRPM(), 0.01); } @Test @@ -35,11 +37,11 @@ public void compute_cadence_2() { AggregatorCyclingCadence current = new AggregatorCyclingCadence("", ""); // when - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 6184))); - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(2, 8016))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(1, 6184))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(2, 8016))); // then - assertEquals(33.53, current.getValue().getRPM(), 0.01); + assertEquals(33.53, current.getValue(Instant.MIN).getRPM(), 0.01); } @Test @@ -47,11 +49,11 @@ public void compute_cadence_sameCount() { AggregatorCyclingCadence current = new AggregatorCyclingCadence("", ""); // when - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 1024))); - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 2048))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(1, 1024))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(1, 2048))); // then - assertEquals(Cadence.of(0), current.getValue()); + assertEquals(Cadence.of(0), current.getValue(Instant.MIN)); } @@ -60,8 +62,8 @@ public void compute_cadence_sameTime() { AggregatorCyclingCadence current = new AggregatorCyclingCadence("", ""); // when - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, 1024))); - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(2, 1024))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(1, 1024))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(2, 1024))); // then assertFalse(current.hasValue()); //TODO Cadence should be 0? @@ -72,11 +74,11 @@ public void compute_cadence_rollOverTime() { AggregatorCyclingCadence current = new AggregatorCyclingCadence("", ""); // when - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(1, UintUtils.UINT16_MAX - 1024))); - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(2, 0))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(1, UintUtils.UINT16_MAX - 1024))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(2, 0))); // then - assertEquals(60, current.getValue().getRPM(), 0.01); + assertEquals(60, current.getValue(Instant.MIN).getRPM(), 0.01); } @Test @@ -85,13 +87,13 @@ public void compute_cadence_rollOverCount() { AggregatorCyclingCadence current = new AggregatorCyclingCadence("", ""); // when - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(UintUtils.UINT32_MAX - 1, 1024))); - current.add(new Raw<>(new BluetoothHandlerCyclingCadence.CrankData(0, 2048))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(UintUtils.UINT32_MAX - 1, 1024))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingCadence.CrankData(0, 2048))); // then // TODO See #953 // assertEquals(60, current.getValue().getRPM(), 0.01); - assertNull(current.getValue()); + assertNull(current.getValue(Instant.MIN)); } @Test @@ -100,12 +102,12 @@ public void compute_speed() { current.setWheelCircumference(Distance.ofMM(2150)); // when - current.add(new Raw<>(new BluetoothHandlerCyclingDistanceSpeed.WheelData(1, 6184))); - current.add(new Raw<>(new BluetoothHandlerCyclingDistanceSpeed.WheelData(2, 8016))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingDistanceSpeed.WheelData(1, 6184))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingDistanceSpeed.WheelData(2, 8016))); // then - assertEquals(2.15, current.getValue().distance().toM(), 0.01); - assertEquals(1.20, current.getValue().speed().toMPS(), 0.01); + assertEquals(2.15, current.getValue(Instant.MIN).distance().toM(), 0.01); + assertEquals(1.20, current.getValue(Instant.MIN).speed().toMPS(), 0.01); } @Test @@ -115,14 +117,14 @@ public void compute_speed_rollOverCount() { current.setWheelCircumference(Distance.ofMM(2000)); // when - current.add(new Raw<>(new BluetoothHandlerCyclingDistanceSpeed.WheelData(UintUtils.UINT32_MAX - 1, 1024))); - current.add(new Raw<>(new BluetoothHandlerCyclingDistanceSpeed.WheelData(0, 2048))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingDistanceSpeed.WheelData(UintUtils.UINT32_MAX - 1, 1024))); + current.add(new Raw<>(Instant.MIN, new BluetoothHandlerCyclingDistanceSpeed.WheelData(0, 2048))); // then // TODO See #953 // assertEquals(2, current.getValue().getDistance().toM(), 0.01); // assertEquals(2, current.getValue().getSpeed().toMPS(), 0.01); - assertNull(current.getValue()); + assertNull(current.getValue(Instant.MIN)); } } \ No newline at end of file diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java index 831ac66228..63a3047232 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java @@ -304,11 +304,11 @@ public void testRecording_blesensor_only_no_distance() { String sensor1 = "2020-02-02T02:02:03Z"; trackPointCreator.setClock(sensor1); - sensorManager.onChanged(new Raw<>(HeartRate.of(5))); //Should be ignored + sensorManager.onChanged(new Raw<>(sensor1, HeartRate.of(5))); //Should be ignored String sensor3 = "2020-02-02T02:02:13Z"; trackPointCreator.setClock(sensor3); - sensorManager.onChanged(new Raw<>(HeartRate.of(7))); + sensorManager.onChanged(new Raw<>(sensor3, HeartRate.of(7))); String stopTime = "2020-02-02T02:02:15Z"; trackPointCreator.setClock(stopTime); @@ -646,12 +646,12 @@ public void testRecording_gpsAndSensor_gpsIdleMoving_sensorMoving() { // when String sensor1 = "2020-02-02T02:02:03Z"; trackPointCreator.setClock(sensor1); - sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(0)))); //Should be ignored + sensorManager.onChanged(new Raw<>(sensor1, new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(0)))); //Should be ignored // when String sensor2 = "2020-02-02T02:02:04Z"; trackPointCreator.setClock(sensor2); - sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(2)))); + sensorManager.onChanged(new Raw<>(sensor2, new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(2)))); // when String gps1 = "2020-02-02T02:02:05Z"; @@ -660,12 +660,12 @@ public void testRecording_gpsAndSensor_gpsIdleMoving_sensorMoving() { // when String sensor3 = "2020-02-02T02:02:06Z"; trackPointCreator.setClock(sensor3); - sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(12)))); + sensorManager.onChanged(new Raw<>(sensor3, new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(12)))); // when String sensor4 = "2020-02-02T02:02:07Z"; trackPointCreator.setClock(sensor4); - sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(14)))); //Should be ignored + sensorManager.onChanged(new Raw<>(sensor4, new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(14)))); //Should be ignored // when String gps2 = "2020-02-02T02:02:08Z"; @@ -674,7 +674,7 @@ public void testRecording_gpsAndSensor_gpsIdleMoving_sensorMoving() { // when String sensor5 = "2020-02-02T02:02:10Z"; trackPointCreator.setClock(sensor5); - sensorManager.onChanged(new Raw<>(new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(16)))); //Should be ignored + sensorManager.onChanged(new Raw<>(sensor5, new BluetoothHandlerRunningSpeedAndCadence.Data(Speed.of(5), null, Distance.of(16)))); //Should be ignored // when String gps3 = "2020-02-02T02:02:12Z"; @@ -730,7 +730,7 @@ public void testRecording_gpsAndSensor_gpsIdleMoving_sensorMoving() { private void mockAltitudeChange(TrackPointCreator trackPointCreator, float altitudeGain) { AggregatorBarometer barometer = Mockito.mock(AggregatorBarometer.class); Mockito.when(barometer.hasValue()).thenReturn(true); - Mockito.when(barometer.getValue()).thenReturn(new AltitudeGainLoss(altitudeGain, altitudeGain)); + Mockito.when(barometer.getValue(Mockito.any())).thenReturn(new AltitudeGainLoss(altitudeGain, altitudeGain)); trackPointCreator.getSensorManager().sensorDataSet.barometer = barometer; } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerBarometricPressure.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerBarometricPressure.java index d29e5ebbcf..a3ed9ba28b 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerBarometricPressure.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerBarometricPressure.java @@ -33,7 +33,7 @@ public void handlePayload(SensorManager.SensorDataChangedObserver observer, Serv AtmosphericPressure value = parseEnvironmentalSensing(characteristic); if (value == null) return; - observer.onChange(new Raw<>(value)); + observer.onChange(new Raw<>(observer.getNow(), value)); } /** diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingCadence.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingCadence.java index 2e8d8e48c7..9fee7dcca0 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingCadence.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingCadence.java @@ -33,7 +33,7 @@ public void handlePayload(SensorManager.SensorDataChangedObserver observer, Serv if (serviceMeasurementUUID.equals(BluetoothHandlerManagerCyclingPower.CYCLING_POWER)) { BluetoothHandlerManagerCyclingPower.Data data = BluetoothHandlerManagerCyclingPower.parseCyclingPower(characteristic); if (data != null && data.crank() != null) { - observer.onChange(new Raw<>(data.crank())); + observer.onChange(new Raw<>(observer.getNow(), data.crank())); } return; } @@ -42,7 +42,7 @@ public void handlePayload(SensorManager.SensorDataChangedObserver observer, Serv Pair data = BluetoothHandlerCyclingDistanceSpeed.parseCyclingCrankAndWheel(address, sensorName, characteristic); if (data != null && data.second != null) { - observer.onChange(new Raw<>(data.second)); + observer.onChange(new Raw<>(observer.getNow(), data.second)); } return; } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeed.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeed.java index f3d6ec9a4f..28219799fa 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeed.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerCyclingDistanceSpeed.java @@ -34,7 +34,7 @@ public AggregatorCyclingDistanceSpeed createEmptySensorData(String address, Stri public void handlePayload(SensorManager.SensorDataChangedObserver observer, ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { Pair data = parseCyclingCrankAndWheel(address, sensorName, characteristic); if (data.first != null) { - observer.onChange(new Raw<>(data.first)); + observer.onChange(new Raw<>(observer.getNow(), data.first)); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerCyclingPower.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerCyclingPower.java index 275f8dc600..8105a402be 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerCyclingPower.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerCyclingPower.java @@ -35,7 +35,7 @@ public void handlePayload(SensorManager.SensorDataChangedObserver observer, @Non Data cyclingPower = parseCyclingPower(characteristic); if (cyclingPower != null) { - observer.onChange(new Raw<>(cyclingPower)); + observer.onChange(new Raw<>(observer.getNow(), cyclingPower)); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerHeartRate.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerHeartRate.java index a9ff6e832b..76345b18f7 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerHeartRate.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerManagerHeartRate.java @@ -45,7 +45,7 @@ public void handlePayload(SensorManager.SensorDataChangedObserver observer, @Non HeartRate heartRate = parseHeartRate(characteristic); if (heartRate != null) { - observer.onChange(new Raw<>(heartRate)); + observer.onChange(new Raw<>(observer.getNow(), heartRate)); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadence.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadence.java index 962d43fbf2..fd147845ce 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadence.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothHandlerRunningSpeedAndCadence.java @@ -36,7 +36,7 @@ public AggregatorRunning createEmptySensorData(String address, String name) { @Override public void handlePayload(SensorManager.SensorDataChangedObserver observer, @NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, BluetoothGattCharacteristic characteristic) { Data data = parseRunningSpeedAndCadence(sensorName, characteristic); - observer.onChange(new Raw<>(data)); + observer.onChange(new Raw<>(observer.getNow(), data)); } @VisibleForTesting diff --git a/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java b/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java index 8a2908b24f..a50cb54bb4 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java @@ -8,6 +8,8 @@ import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; +import java.time.Instant; + import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.Aggregator; import de.dennisguse.opentracks.sensors.sensorData.Raw; @@ -21,7 +23,7 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange //TODO Should be final and not be visible for testing @VisibleForTesting - public SensorDataSet sensorDataSet = new SensorDataSet(); + public SensorDataSet sensorDataSet; private final TrackPointCreator observer; @@ -47,6 +49,11 @@ public void onDisconnect(Aggregator aggregator) { public void onRemove(Aggregator aggregator) { sensorDataSet.remove(aggregator); } + + @Override + public Instant getNow() { + return observer.createNow(); + } }; private BluetoothRemoteSensorManager bluetoothSensorManager; @@ -57,6 +64,7 @@ public void onRemove(Aggregator aggregator) { public SensorManager(TrackPointCreator observer) { this.observer = observer; + this.sensorDataSet = new SensorDataSet(observer); } public void start(Context context, Handler handler) { @@ -138,5 +146,7 @@ public interface SensorDataChangedObserver { void onDisconnect(Aggregator sensorData); void onRemove(Aggregator sensorData); + + Instant getNow(); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java b/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java index 74ef061f8c..0929e875cf 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/driver/BarometerInternal.java @@ -22,7 +22,7 @@ public class BarometerInternal implements Driver { private static final int SAMPLING_PERIOD = (int) TimeUnit.SECONDS.toMicros(5); - private final SensorManager.SensorDataChangedObserver listener; + private final SensorManager.SensorDataChangedObserver observer; private Context context; @@ -34,7 +34,7 @@ public void onSensorChanged(SensorEvent event) { return; } - listener.onChange(new Raw<>(AtmosphericPressure.ofHPA(event.values[0]))); + observer.onChange(new Raw<>(observer.getNow(), AtmosphericPressure.ofHPA(event.values[0]))); } @Override @@ -43,8 +43,8 @@ public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; - public BarometerInternal(@NonNull SensorManager.SensorDataChangedObserver listener) { - this.listener = listener; + public BarometerInternal(@NonNull SensorManager.SensorDataChangedObserver observer) { + this.observer = observer; } @@ -60,7 +60,7 @@ public void connect(Context context, Handler handler, String addressIgnored) { if (sensorManager.registerListener(sensorEventListener, pressureSensor, SAMPLING_PERIOD, handler)) { this.context = context; - listener.onConnect(new AggregatorBarometer("internal", null)); + observer.onConnect(new AggregatorBarometer("internal", null)); return; } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java index 3643b79763..06e4c1b893 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Aggregator.java @@ -42,11 +42,11 @@ public boolean hasValue() { @NonNull protected abstract Output getNoneValue(); - public Output getValue() { + public Output getValue(Instant now) { if (!hasValue()) { return null; //TODO Check if this is a good idea! } - if (isRecent()) { + if (isRecent(now)) { return value; } return getNoneValue(); @@ -62,12 +62,12 @@ public void reset() { /** * Is the data recent considering the current time. */ - private boolean isRecent() { + private boolean isRecent(Instant now) { if (previous == null) { return false; } - return Instant.now() + return now .isBefore(previous.time().plus(BluetoothRemoteSensorManager.MAX_SENSOR_DATE_SET_AGE)); } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Raw.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Raw.java index 125d2268fc..a946dca298 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Raw.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/Raw.java @@ -2,15 +2,21 @@ import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; +import java.time.Clock; import java.time.Instant; public record Raw( - @NonNull T value, - - @NonNull Instant time + @NonNull Instant time, + @NonNull T value ) { - public Raw(@NonNull T value) { - this(value, Instant.now()); //TODO We should be using the MonotonicClock + public Raw(@NonNull Clock clock, @NonNull T value) { + this(clock.instant(), value); + } + + @VisibleForTesting + public Raw(@NonNull String time, @NonNull T value) { + this(Instant.parse(time), value); } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java index 256ea50993..25f8630ad9 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java @@ -17,6 +17,7 @@ import de.dennisguse.opentracks.sensors.BluetoothHandlerCyclingDistanceSpeed; import de.dennisguse.opentracks.sensors.BluetoothHandlerManagerCyclingPower; import de.dennisguse.opentracks.sensors.BluetoothHandlerRunningSpeedAndCadence; +import de.dennisguse.opentracks.services.handlers.TrackPointCreator; import de.dennisguse.opentracks.settings.PreferencesUtils; public final class SensorDataSet { @@ -43,11 +44,15 @@ public final class SensorDataSet { public AggregatorGPS gps; - public SensorDataSet() { + private TrackPointCreator trackPointCreator; + + public SensorDataSet(TrackPointCreator trackPointCreator) { + this.trackPointCreator = trackPointCreator; } + @Deprecated //TODO This is not a copy constructor anymore, but it should be - aggregators are no value objects; best guess: can be removed public SensorDataSet(SensorDataSet toCopy) { - //TODO This is not a copy constructor anymore, but it should be - aggregators are no value objects + this.trackPointCreator = toCopy.trackPointCreator; this.heartRate = toCopy.heartRate; this.cyclingCadence = toCopy.cyclingCadence; this.cyclingDistanceSpeed = toCopy.cyclingDistanceSpeed; @@ -59,7 +64,7 @@ public SensorDataSet(SensorDataSet toCopy) { public Pair getHeartRate() { if (heartRate != null) { - return new Pair<>(heartRate.getValue(), heartRate.getSensorNameOrAddress()); + return new Pair<>(heartRate.getValue(trackPointCreator.createNow()), heartRate.getSensorNameOrAddress()); } return null; @@ -67,7 +72,7 @@ public Pair getHeartRate() { public Pair getCadence() { if (cyclingCadence != null) { - return new Pair<>(cyclingCadence.getValue(), cyclingCadence.getSensorNameOrAddress()); + return new Pair<>(cyclingCadence.getValue(trackPointCreator.createNow()), cyclingCadence.getSensorNameOrAddress()); } if (runningDistanceSpeedCadence != null && runningDistanceSpeedCadence.hasValue() && runningDistanceSpeedCadence.value.cadence() != null) { @@ -78,11 +83,11 @@ public Pair getCadence() { } public Pair getSpeed() { - if (cyclingDistanceSpeed != null && cyclingDistanceSpeed.hasValue() && cyclingDistanceSpeed.getValue().speed() != null) { - return new Pair<>(cyclingDistanceSpeed.getValue().speed(), cyclingDistanceSpeed.getSensorNameOrAddress()); + if (cyclingDistanceSpeed != null && cyclingDistanceSpeed.hasValue() && cyclingDistanceSpeed.getValue(trackPointCreator.createNow()).speed() != null) { + return new Pair<>(cyclingDistanceSpeed.getValue(trackPointCreator.createNow()).speed(), cyclingDistanceSpeed.getSensorNameOrAddress()); } - if (runningDistanceSpeedCadence != null && runningDistanceSpeedCadence.hasValue() && runningDistanceSpeedCadence.getValue().speed() != null) { + if (runningDistanceSpeedCadence != null && runningDistanceSpeedCadence.hasValue() && runningDistanceSpeedCadence.getValue(trackPointCreator.createNow()).speed() != null) { return new Pair<>(runningDistanceSpeedCadence.value.speed(), runningDistanceSpeedCadence.getSensorNameOrAddress()); } @@ -152,7 +157,7 @@ public void clear() { public void fillTrackPoint(TrackPoint trackPoint) { if (gps != null && gps.hasValue()) { - trackPoint.setPosition(gps.getValue()); + trackPoint.setPosition(gps.getValue(trackPointCreator.createNow())); } if (getHeartRate() != null) { @@ -168,20 +173,20 @@ public void fillTrackPoint(TrackPoint trackPoint) { } if (cyclingDistanceSpeed != null && cyclingDistanceSpeed.hasValue()) { - trackPoint.setSensorDistance(cyclingDistanceSpeed.getValue().distanceOverall()); + trackPoint.setSensorDistance(cyclingDistanceSpeed.getValue(trackPointCreator.createNow()).distanceOverall()); } if (cyclingPower != null && cyclingPower.hasValue()) { - trackPoint.setPower(cyclingPower.getValue()); + trackPoint.setPower(cyclingPower.getValue(trackPointCreator.createNow())); } if (runningDistanceSpeedCadence != null && runningDistanceSpeedCadence.hasValue()) { - trackPoint.setSensorDistance(runningDistanceSpeedCadence.getValue().distance()); + trackPoint.setSensorDistance(runningDistanceSpeedCadence.getValue(trackPointCreator.createNow()).distance()); } if (barometer != null && barometer.hasValue()) { - trackPoint.setAltitudeGain(barometer.getValue().gain_m()); - trackPoint.setAltitudeLoss(barometer.getValue().loss_m()); + trackPoint.setAltitudeGain(barometer.getValue(trackPointCreator.createNow()).gain_m()); + trackPoint.setAltitudeLoss(barometer.getValue(trackPointCreator.createNow()).loss_m()); } } diff --git a/src/main/java/de/dennisguse/opentracks/services/handlers/GPSManager.java b/src/main/java/de/dennisguse/opentracks/services/handlers/GPSManager.java index 8892a53f58..38fea710c0 100644 --- a/src/main/java/de/dennisguse/opentracks/services/handlers/GPSManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/handlers/GPSManager.java @@ -37,7 +37,7 @@ public class GPSManager implements SensorConnector, LocationListenerCompat, GpsS private TrackPointCreator trackPointCreator; - private SensorManager.SensorDataChangedObserver listener; + private SensorManager.SensorDataChangedObserver observer; private Context context; private Handler handler; @@ -46,9 +46,9 @@ public class GPSManager implements SensorConnector, LocationListenerCompat, GpsS private Duration gpsInterval; private Distance thresholdHorizontalAccuracy; - public GPSManager(TrackPointCreator trackPointCreator, SensorManager.SensorDataChangedObserver listener) { + public GPSManager(TrackPointCreator trackPointCreator, SensorManager.SensorDataChangedObserver observer) { this.trackPointCreator = trackPointCreator; - this.listener = listener; + this.observer = observer; } public void start(@NonNull Context context, @NonNull Handler handler) { @@ -60,7 +60,7 @@ public void start(@NonNull Context context, @NonNull Handler handler) { gpsStatusManager = new GpsStatusManager(context, this, handler); locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); - listener.onConnect(new AggregatorGPS("internal")); + observer.onConnect(new AggregatorGPS("internal")); registerLocationListener(); gpsStatusManager.start(); @@ -82,8 +82,8 @@ public void stop(Context context) { gpsStatusManager.stop(); gpsStatusManager = null; - listener.onDisconnect(new AggregatorGPS("internal")); - listener = null; + observer.onDisconnect(new AggregatorGPS("internal")); + observer = null; trackPointCreator = null; } @@ -139,7 +139,7 @@ public void onLocationChanged(@NonNull Location location) { return; } - listener.onChange(new Raw<>(Position.of(location))); + observer.onChange(new Raw<>(observer.getNow(), Position.of(location))); } @Override diff --git a/src/main/java/de/dennisguse/opentracks/services/handlers/TrackPointCreator.java b/src/main/java/de/dennisguse/opentracks/services/handlers/TrackPointCreator.java index 6e521404ad..e015247069 100644 --- a/src/main/java/de/dennisguse/opentracks/services/handlers/TrackPointCreator.java +++ b/src/main/java/de/dennisguse/opentracks/services/handlers/TrackPointCreator.java @@ -124,8 +124,7 @@ public Pair createCurrentTrackPoint(@Nullable TrackPo return new Pair<>(currentTrackPoint, sensorDataSet); } - @VisibleForTesting - Instant createNow() { + public Instant createNow() { return Instant.now(clock); } diff --git a/src/main/java/de/dennisguse/opentracks/viewmodels/SensorStatisticsViewHolder.java b/src/main/java/de/dennisguse/opentracks/viewmodels/SensorStatisticsViewHolder.java index eb26000500..66e3dbcd6b 100644 --- a/src/main/java/de/dennisguse/opentracks/viewmodels/SensorStatisticsViewHolder.java +++ b/src/main/java/de/dennisguse/opentracks/viewmodels/SensorStatisticsViewHolder.java @@ -3,6 +3,8 @@ import android.util.Pair; import android.view.LayoutInflater; +import java.time.Instant; + import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.models.HeartRateZones; import de.dennisguse.opentracks.databinding.StatsSensorItemBinding; @@ -92,7 +94,7 @@ public void onChanged(UnitSystem unitSystem, RecordingData data) { Pair valueAndUnit; if (sensorDataSet != null && sensorDataSet.getCyclingPower() != null) { - valueAndUnit = StringUtils.getPowerParts(getContext(), sensorDataSet.getCyclingPower().getValue()); + valueAndUnit = StringUtils.getPowerParts(getContext(), sensorDataSet.getCyclingPower().getValue(Instant.now())); //TODO Use MonotonicClock sensorName = sensorDataSet.getCyclingPower().getSensorNameOrAddress(); } else { valueAndUnit = StringUtils.getCadenceParts(getContext(), null);