From fba08fe8dd315c9264b65d82da3127fe31892070 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Sun, 26 Oct 2025 19:26:56 +0100 Subject: [PATCH 01/30] Cleanup: rename TrackStatistics to SegmentStatisticsUpdater. --- .../opentracks/chart/ChartPointTest.java | 12 ++--- .../opentracks/content/data/TestDataUtil.java | 8 ++-- .../data/CustomContentProviderUtilsTest.java | 4 +- .../io/file/importer/ExportImportTest.java | 8 ++-- .../file/importer/GPXTrackImporterTest.java | 6 +-- ...cordingServiceNotificationManagerTest.java | 4 +- .../TrackRecordingServiceRecordingTest.java | 32 ++++++------- .../VoiceAnnouncementManagerTest.java | 6 +-- .../VoiceAnnouncementUtilsTest.java | 46 +++++++++---------- .../share/TrackShareSummaryGeneratorTest.java | 4 +- .../opentracks/stats/TrackStatisticsTest.java | 10 ++-- .../stats/TrackStatisticsUpdaterTest.java | 6 +-- .../AggregatedStatisticsTest.java | 22 ++++----- .../ui/intervals/IntervalStatisticsTest.java | 12 ++--- .../opentracks/chart/ChartFragment.java | 6 +-- .../opentracks/chart/ChartPoint.java | 4 +- .../opentracks/data/ContentProviderUtils.java | 10 ++-- .../opentracks/data/TrackDataHub.java | 6 +-- .../opentracks/data/models/Track.java | 8 ++-- .../fragments/StatisticsRecordedFragment.java | 4 +- .../io/file/exporter/GPXTrackExporter.java | 4 +- .../io/file/importer/GPXTrackImporter.java | 3 +- .../opentracks/services/RecordingData.java | 12 ++--- .../services/TrackRecordingManager.java | 6 +-- .../VoiceAnnouncementManager.java | 8 ++-- .../announcement/VoiceAnnouncementUtils.java | 4 +- .../share/TrackShareSummaryGenerator.java | 4 +- ...tics.java => SegmentStatisticUpdater.java} | 12 ++--- .../stats/TrackStatisticsUpdater.java | 32 ++++++------- .../AggregatedStatistics.java | 10 ++-- .../SettingsCustomLayoutEditAdapter.java | 4 +- .../ui/intervals/IntervalStatistics.java | 6 +-- 32 files changed, 162 insertions(+), 161 deletions(-) rename src/main/java/de/dennisguse/opentracks/stats/{TrackStatistics.java => SegmentStatisticUpdater.java} (96%) diff --git a/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java b/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java index 46dead9d5..f5539f0f3 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java @@ -15,7 +15,7 @@ import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; @RunWith(AndroidJUnit4.class) public class ChartPointTest { @@ -23,7 +23,7 @@ public class ChartPointTest { @Test public void create_by_time() { // given - TrackStatistics statistics = new TrackStatistics(); + SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); statistics.setTotalTime(Duration.ofSeconds(1000)); // when @@ -36,7 +36,7 @@ public class ChartPointTest { @Test public void create_by_distance() { // given - TrackStatistics statistics = new TrackStatistics(); + SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); statistics.setTotalDistance(Distance.of(1000)); // when @@ -49,7 +49,7 @@ public class ChartPointTest { @Test public void create_get_altitude_speed_and_pace() { // given - TrackStatistics statistics = new TrackStatistics(); + SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint() .setAltitude(Altitude.EGM2008.of(50)); @@ -65,7 +65,7 @@ public class ChartPointTest { @Test public void create_sensorNotAvailable() { // given - TrackStatistics statistics = new TrackStatistics(); + SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint() .setAltitude(Altitude.EGM2008.of(50)); // when @@ -86,7 +86,7 @@ public class ChartPointTest { .setCadence(101f) .setPower(102f); - TrackStatistics statistics = new TrackStatistics(); + SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); // when ChartPoint point = ChartPoint.create(statistics, trackPoint, Speed.of(10), false, UnitSystem.METRIC); diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java index e6c9e8343..bd9a28a62 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java @@ -20,7 +20,7 @@ import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; import de.dennisguse.opentracks.ui.markers.MarkerUtils; import de.dennisguse.opentracks.util.FileUtils; @@ -86,7 +86,7 @@ public class TestDataUtil { ); //TODO Use TrackStatisticsUpdater - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setTotalDistance(Distance.of(0)); stats.setTotalTime(Duration.ofMillis(0)); List markers = List.of( @@ -154,7 +154,7 @@ public class TestDataUtil { Uri photoUri = FileUtils.getUriForFile(context, dstFile); //TODO Use TrackStatisticsUpdater - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setTotalDistance(Distance.of(0)); stats.setTotalTime(Duration.ofMillis(0)); @@ -171,7 +171,7 @@ public class TestDataUtil { } } - public static Pair buildTrackWithTrackPoints(ContentProviderUtils contentProviderUtils, int numberOfPoints) { + public static Pair buildTrackWithTrackPoints(ContentProviderUtils contentProviderUtils, int numberOfPoints) { Track dummyTrack = new Track(); dummyTrack.setId(new Track.Id(System.currentTimeMillis())); dummyTrack.setName("Dummy Track"); diff --git a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java index 09d6a8112..3dad21cdf 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java @@ -62,7 +62,7 @@ import de.dennisguse.opentracks.data.tables.MarkerColumns; import de.dennisguse.opentracks.data.tables.TrackPointsColumns; import de.dennisguse.opentracks.data.tables.TracksColumns; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.util.FileUtils; /** @@ -406,7 +406,7 @@ public class CustomContentProviderUtilsTest { Pair> track = TestDataUtil.createTrack(trackId, 10); // AverageSpeed - TrackStatistics statistics = new TrackStatistics(); + SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); statistics.setStartTime(Instant.ofEpochMilli(1000)); statistics.setStopTime(Instant.ofEpochMilli(2500)); statistics.setTotalTime(Duration.ofMillis(1500)); 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 7d16c8ded..2bf4cb0d3 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 @@ -75,7 +75,7 @@ import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; /** * Export a track to {@link TrackFileFormat} and verify that the import is identical. @@ -203,7 +203,7 @@ public class ExportImportTest { setUp(); Track track = contentProviderUtils.getTrack(trackId); - TrackStatistics trackStatistics = track.getTrackStatistics(); + SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); assertEquals(ZoneOffset.of("+01:00"), track.getZoneOffset()); assertEquals(Instant.parse("2020-02-02T02:02:02Z"), trackStatistics.getStartTime()); @@ -334,7 +334,7 @@ public class ExportImportTest { a.assertEquals(trackPoints, actual); // 3. trackstatistics - TrackStatistics importedTrackStatistics = importedTrack.getTrackStatistics(); + SegmentStatisticUpdater importedTrackStatistics = importedTrack.getTrackStatistics(); // Time assertEquals(track.getZoneOffset(), importedTrack.getZoneOffset()); @@ -479,7 +479,7 @@ public class ExportImportTest { ), actual); // 3. trackstatistics - TrackStatistics importedTrackStatistics = importedTrack.getTrackStatistics(); + SegmentStatisticUpdater importedTrackStatistics = importedTrack.getTrackStatistics(); // Time assertEquals(track.getZoneOffset(), importedTrack.getZoneOffset()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java index 82488ecaf..df2b4db5b 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java @@ -34,7 +34,7 @@ import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.io.file.TrackFileFormat; import de.dennisguse.opentracks.io.file.exporter.TrackExporter; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; /** * Test that legacy KML/GPX formats can still be imported. @@ -149,7 +149,7 @@ public class GPXTrackImporterTest { assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType()); // 3. trackstatistics - TrackStatistics trackStatistics = importedTrack.getTrackStatistics(); + SegmentStatisticUpdater trackStatistics = importedTrack.getTrackStatistics(); assertEquals(0.75, trackStatistics.getMaxSpeed().toMPS(), 0.01); assertEquals(Duration.ofSeconds(101), trackStatistics.getMovingTime()); @@ -204,7 +204,7 @@ public class GPXTrackImporterTest { assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType()); // 3. trackstatistics - TrackStatistics trackStatistics = importedTrack.getTrackStatistics(); + SegmentStatisticUpdater trackStatistics = importedTrack.getTrackStatistics(); assertEquals(5.0, trackStatistics.getMaxSpeed().toMPS(), 0.01); assertEquals(Duration.ofSeconds(101), trackStatistics.getMovingTime()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java index badd4028e..2eab35723 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java @@ -21,7 +21,7 @@ import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; @RunWith(MockitoJUnitRunner.class) public class TrackRecordingServiceNotificationManagerTest { @@ -32,7 +32,7 @@ public class TrackRecordingServiceNotificationManagerTest { private TrackPoint trackPointMock; @Mock - private TrackStatistics trackStatisticsMock; + private SegmentStatisticUpdater trackStatisticsMock; @Mock private NotificationCompat.Builder notificationCompatBuilder; diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java index e6402a3c8..5d51a98e5 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java @@ -46,7 +46,7 @@ import de.dennisguse.opentracks.sensors.sensorData.AggregatorRunning; import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; import de.dennisguse.opentracks.settings.PreferencesUtils; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; /** * Tests insert location. @@ -106,7 +106,7 @@ public class TrackRecordingServiceRecordingTest { // then - assertEquals(new TrackStatistics(startTime, startTime, 0, 0, 0, 0, null, null) + assertEquals(new SegmentStatisticUpdater(startTime, startTime, 0, 0, 0, 0, null, null) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -120,7 +120,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new TrackStatistics(startTime, stopTime, 0, 1, 1, 0, 0f, 0f) + assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 0, 1, 1, 0, 0f, 0f) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -192,7 +192,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new TrackStatistics(startTime, pauseTime, 0, 1, 1, 0, 0f, 0f) + assertEquals(new SegmentStatisticUpdater(startTime, pauseTime, 0, 1, 1, 0, 0f, 0f) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -208,7 +208,7 @@ public class TrackRecordingServiceRecordingTest { service.resumeTrack(trackId); // then - assertEquals(new TrackStatistics(startTime, resumeTime, 0, 1, 1, 0, 0f, 0f) + assertEquals(new SegmentStatisticUpdater(startTime, resumeTime, 0, 1, 1, 0, 0f, 0f) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -341,7 +341,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - assertEquals(new TrackStatistics(startTime, gps1, 0, 1, 1, 15, 0f, 0f) + assertEquals(new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); // when @@ -349,7 +349,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.0001, 35.0, 1, 15); // then - assertEquals(new TrackStatistics(startTime, gps2, 11.113178253173828f, 4, 4, 15, 0f, 0f) + assertEquals(new SegmentStatisticUpdater(startTime, gps2, 11.113178253173828f, 4, 4, 15, 0f, 0f) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); // when @@ -357,7 +357,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps3, 45.0002, 35.0, 1, 15); // then - assertEquals(new TrackStatistics(startTime, gps3, 22.226356506347656, 6, 6, 15, 0f, 0f) + assertEquals(new SegmentStatisticUpdater(startTime, gps3, 22.226356506347656, 6, 6, 15, 0f, 0f) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); @@ -367,7 +367,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new TrackStatistics(startTime, stopTime, 22.226356506347656, 10, 10, 15, 0f, 0f) + assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 22.226356506347656, 10, 10, 15, 0f, 0f) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -420,7 +420,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - TrackStatistics gps1Statistics = new TrackStatistics(startTime, gps1, 0, 1, 1, 15, 0f, 0f); + SegmentStatisticUpdater gps1Statistics = new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f); assertEquals(gps1Statistics, contentProviderUtils.getTrack(trackId).getTrackStatistics()); // when @@ -443,7 +443,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new TrackStatistics(startTime, stopTime, 2.222635507583618, 10, 10, 15, 0f, 0f) + assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 2.222635507583618, 10, 10, 15, 0f, 0f) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -548,7 +548,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 100, 15); // then - TrackStatistics startStatistics = new TrackStatistics(startTime, startTime, 0, 0, 0, 0, null, null); + SegmentStatisticUpdater startStatistics = new SegmentStatisticUpdater(startTime, startTime, 0, 0, 0, 0, null, null); assertEquals(startStatistics, contentProviderUtils.getTrack(trackId).getTrackStatistics()); @@ -566,7 +566,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new TrackStatistics(startTime, stopTime, 0, 10, 10, 0, 0f, 0f) + assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 0, 10, 10, 0, 0f, 0f) , contentProviderUtils.getTrack(trackId).getTrackStatistics()); @@ -594,14 +594,14 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - assertEquals(new TrackStatistics(startTime, gps1, 0, 1, 1, 15, 0f, 0f), contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f), contentProviderUtils.getTrack(trackId).getTrackStatistics()); // when String gps2 = "2020-02-02T02:02:06Z"; TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.1, 35.0, 1, 15); // then - assertEquals(new TrackStatistics(startTime, gps2, 11113.275390625, 4, 4, 2778.31884765625f, 0f, 0f).toString(), contentProviderUtils.getTrack(trackId).getTrackStatistics().toString()); + assertEquals(new SegmentStatisticUpdater(startTime, gps2, 11113.275390625, 4, 4, 2778.31884765625f, 0f, 0f).toString(), contentProviderUtils.getTrack(trackId).getTrackStatistics().toString()); // when @@ -610,7 +610,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new TrackStatistics(startTime, stopTime, 11113.275390625, 10, 10, 1111.3275390625f, 0f, 0f).toString(), contentProviderUtils.getTrack(trackId).getTrackStatistics().toString()); + assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 11113.275390625, 10, 10, 1111.3275390625f, 0f, 0f).toString(), contentProviderUtils.getTrack(trackId).getTrackStatistics().toString()); // then diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManagerTest.java index 9e8db772b..178ed06af 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManagerTest.java @@ -22,7 +22,7 @@ import java.util.concurrent.TimeoutException; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.services.TrackRecordingService; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; @RunWith(AndroidJUnit4.class) public class VoiceAnnouncementManagerTest { @@ -54,7 +54,7 @@ public class VoiceAnnouncementManagerTest { voiceAnnouncementManager.setFrequency(Distance.ofKilometer(5)); // when - TrackStatistics statistics = new TrackStatistics(); + SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); statistics.setTotalDistance(Distance.ofKilometer(13)); voiceAnnouncementManager.start(statistics); assertEquals(Distance.of(15000), voiceAnnouncementManager.getNextTotalDistance()); @@ -74,7 +74,7 @@ public class VoiceAnnouncementManagerTest { voiceAnnouncementManager.setFrequency(Duration.ofSeconds(5)); // when - TrackStatistics statistics = new TrackStatistics(); + SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); statistics.setTotalTime(Duration.ofSeconds(91)); voiceAnnouncementManager.start(statistics); assertEquals(Duration.ofSeconds(95), voiceAnnouncementManager.getNextTotalTime()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java index 303132b77..7eead65b6 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java @@ -34,7 +34,7 @@ import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; @RunWith(AndroidJUnit4.class) @@ -66,7 +66,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_speed() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.of(20000)); stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); @@ -89,7 +89,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_speed_rounding_check() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.of(20000)); stats.setTotalTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); @@ -112,7 +112,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_distance_rounding_check() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.of(19999)); stats.setTotalTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); @@ -135,7 +135,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_distance_rounding_check_two() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.of(19900)); stats.setTotalTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); @@ -160,9 +160,9 @@ public class VoiceAnnouncementUtilsTest { public void getAnnouncement_withInterval_metric_speed() { // given int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - TrackStatistics stats = trackWithStats.second; + SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatistics.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); @@ -186,7 +186,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_pace() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.of(20000)); stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); @@ -211,9 +211,9 @@ public class VoiceAnnouncementUtilsTest { public void getAnnouncement_withInterval_metric_pace() { // given int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - TrackStatistics stats = trackWithStats.second; + SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatistics.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); @@ -237,7 +237,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_imperial_speed() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.of(20000)); stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); @@ -260,7 +260,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_imperial_speed_1() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.ofMile(1.1)); stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); @@ -281,7 +281,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_imperial_meter_speed_1() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.ofMile(1.1)); stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); @@ -302,7 +302,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_speed_1() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.ofKilometer(1.1)); stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); @@ -325,9 +325,9 @@ public class VoiceAnnouncementUtilsTest { public void getAnnouncement_withInterval_imperial_speed() { // given int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - TrackStatistics stats = trackWithStats.second; + SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatistics.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); @@ -351,7 +351,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_imperial_pace() { - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setStartTime(Instant.EPOCH); stats.setTotalDistance(Distance.of(20000)); stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); @@ -376,9 +376,9 @@ public class VoiceAnnouncementUtilsTest { public void getAnnouncement_withInterval_imperial_pace() { // given int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - TrackStatistics stats = trackWithStats.second; + SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatistics.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); @@ -406,9 +406,9 @@ public class VoiceAnnouncementUtilsTest { PreferencesUtils.setVoiceAnnounceLapHeartRate(true); int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - TrackStatistics stats = trackWithStats.second; + SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatistics.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); @@ -444,9 +444,9 @@ public class VoiceAnnouncementUtilsTest { PreferencesUtils.setVoiceAnnounceLapSpeedPace(false); int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - TrackStatistics stats = trackWithStats.second; + SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatistics.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java b/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java index 319a82e54..df92ea7ad 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java @@ -39,7 +39,7 @@ import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.util.StringUtils; /** @@ -66,7 +66,7 @@ public class TrackShareSummaryGeneratorTest { @Test public void testGenerateTrackDescription() { Track track = new Track(); - TrackStatistics stats = new TrackStatistics(); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); stats.setTotalDistance(Distance.of(20000)); stats.setTotalTime(Duration.ofMillis(600000)); stats.setMovingTime(Duration.ofMillis(300000)); diff --git a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsTest.java b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsTest.java index ba7df79e7..fc7708caa 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsTest.java @@ -32,7 +32,7 @@ import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Speed; /** - * Tests for {@link TrackStatistics}. + * Tests for {@link SegmentStatisticUpdater}. * This only tests non-trivial pieces of that class. * * @author Rodrigo Damazio @@ -40,17 +40,17 @@ import de.dennisguse.opentracks.data.models.Speed; @RunWith(AndroidJUnit4.class) public class TrackStatisticsTest { - private TrackStatistics statistics; + private SegmentStatisticUpdater statistics; @Before public void setUp() { - statistics = new TrackStatistics(); + statistics = new SegmentStatisticUpdater(); } @Test public void testMerge_no_data() { // given - TrackStatistics statistics2 = new TrackStatistics(); + SegmentStatisticUpdater statistics2 = new SegmentStatisticUpdater(); // when statistics.merge(statistics2); @@ -74,7 +74,7 @@ public class TrackStatisticsTest { @Test public void testMerge() { // given - TrackStatistics statistics2 = new TrackStatistics(); + SegmentStatisticUpdater statistics2 = new SegmentStatisticUpdater(); statistics.setStartTime(Instant.ofEpochMilli(1000)); // Resulting start time statistics.setStopTime(Instant.ofEpochMilli(2500)); statistics2.setStartTime(Instant.ofEpochMilli(3000)); diff --git a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java index 02b3885da..a28b48337 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java @@ -31,7 +31,7 @@ public class TrackStatisticsUpdaterTest { TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); // then - TrackStatistics statistics = subject.getTrackStatistics(); + SegmentStatisticUpdater statistics = subject.getTrackStatistics(); assertNull(statistics.getStartTime()); assertNull(statistics.getStopTime()); assertEquals(Duration.ZERO, statistics.getTotalTime()); @@ -58,7 +58,7 @@ public class TrackStatisticsUpdaterTest { subject.addTrackPoint(tp); // then - TrackStatistics statistics = subject.getTrackStatistics(); + SegmentStatisticUpdater statistics = subject.getTrackStatistics(); assertEquals(startTime, statistics.getStartTime()); assertEquals(startTime, statistics.getStopTime()); assertEquals(Duration.ZERO, statistics.getTotalTime()); @@ -83,7 +83,7 @@ public class TrackStatisticsUpdaterTest { data.trackPoints().forEach(subject::addTrackPoint); // then - TrackStatistics statistics = subject.getTrackStatistics(); + SegmentStatisticUpdater statistics = subject.getTrackStatistics(); assertEquals(142.26, statistics.getTotalDistance().toM(), 0.01); assertEquals(Duration.ofSeconds(12), statistics.getTotalTime()); assertEquals(Duration.ofSeconds(12), statistics.getMovingTime()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java index f6bbdee6c..463d7cc3c 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java @@ -20,7 +20,7 @@ import de.dennisguse.opentracks.data.models.ActivityType; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; @RunWith(JUnit4.class) public class AggregatedStatisticsTest { @@ -28,7 +28,7 @@ public class AggregatedStatisticsTest { private final Context context = ApplicationProvider.getApplicationContext(); private static Track createTrack(Context context, Distance totalDistance, Duration totalTime, String activityTypeLocalized) { - TrackStatistics statistics = new TrackStatistics(); + SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); statistics.setStartTime(Instant.ofEpochMilli(1000L)); // Resulting start time statistics.setStopTime(statistics.getStartTime().plus(totalTime)); statistics.setTotalTime(totalTime); @@ -63,7 +63,7 @@ public class AggregatedStatisticsTest { assertNotNull(aggregatedStatistics.get(biking)); assertEquals(1, aggregatedStatistics.get(biking).getCountTracks()); - TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); + SegmentStatisticUpdater statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); assertEquals(totalDistance, statistics2.getTotalDistance()); assertEquals(totalTime, statistics2.getMovingTime()); } @@ -117,7 +117,7 @@ public class AggregatedStatisticsTest { assertNotNull(aggregatedStatistics.get(biking)); assertEquals(2, aggregatedStatistics.get(biking).getCountTracks()); - TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); + SegmentStatisticUpdater statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); assertEquals(totalDistance.multipliedBy(2), statistics2.getTotalDistance()); assertEquals(totalTime.multipliedBy(2), statistics2.getMovingTime()); } @@ -151,19 +151,19 @@ public class AggregatedStatisticsTest { assertEquals(1, aggregatedStatistics.get(walking).getCountTracks()); { - TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); + SegmentStatisticUpdater statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); assertEquals(totalDistance, statistics2.getTotalDistance()); assertEquals(totalTime, statistics2.getMovingTime()); } { - TrackStatistics statistics2 = aggregatedStatistics.get(running).getTrackStatistics(); + SegmentStatisticUpdater statistics2 = aggregatedStatistics.get(running).getTrackStatistics(); assertEquals(totalDistance, statistics2.getTotalDistance()); assertEquals(totalTime, statistics2.getMovingTime()); } { - TrackStatistics statistics2 = aggregatedStatistics.get(walking).getTrackStatistics(); + SegmentStatisticUpdater statistics2 = aggregatedStatistics.get(walking).getTrackStatistics(); assertEquals(totalDistance, statistics2.getTotalDistance()); assertEquals(totalTime, statistics2.getMovingTime()); } @@ -214,28 +214,28 @@ public class AggregatedStatisticsTest { // Biking. { - TrackStatistics statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); + SegmentStatisticUpdater statistics2 = aggregatedStatistics.get(biking).getTrackStatistics(); assertEquals(totalDistance.multipliedBy(5), statistics2.getTotalDistance()); assertEquals(totalTime.multipliedBy(5), statistics2.getMovingTime()); } // Running. { - TrackStatistics statistics2 = aggregatedStatistics.get(running).getTrackStatistics(); + SegmentStatisticUpdater statistics2 = aggregatedStatistics.get(running).getTrackStatistics(); assertEquals(totalDistance.multipliedBy(2), statistics2.getTotalDistance()); assertEquals(totalTime.multipliedBy(2), statistics2.getMovingTime()); } // Walking. { - TrackStatistics statistics2 = aggregatedStatistics.get(walking).getTrackStatistics(); + SegmentStatisticUpdater statistics2 = aggregatedStatistics.get(walking).getTrackStatistics(); assertEquals(totalDistance.multipliedBy(2), statistics2.getTotalDistance()); assertEquals(totalTime.multipliedBy(2), statistics2.getMovingTime()); } // Driving. { - TrackStatistics statistics2 = aggregatedStatistics.get(driving).getTrackStatistics(); + SegmentStatisticUpdater statistics2 = aggregatedStatistics.get(driving).getTrackStatistics(); assertEquals(totalDistance, statistics2.getTotalDistance()); assertEquals(totalTime, statistics2.getMovingTime()); } diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsTest.java index 58b29f422..5a263c61c 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsTest.java @@ -21,7 +21,7 @@ import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; @RunWith(JUnit4.class) @@ -37,7 +37,7 @@ public class IntervalStatisticsTest { contentProviderUtils = new ContentProviderUtils(context); } - private TrackStatistics buildTrackStatistics(List trackPoints) { + private SegmentStatisticUpdater buildTrackStatistics(List trackPoints) { TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); for (TrackPoint tp : trackPoints) { trackStatisticsUpdater.addTrackPoint(tp); @@ -135,22 +135,22 @@ public class IntervalStatisticsTest { } dummyTrack.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics()); contentProviderUtils.updateTrack(dummyTrack); - Pair trackWithStats = new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getTrackStatistics()); + Pair trackWithStats = new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getTrackStatistics()); // when and then whenAndThen(trackWithStats, numberOfPoints, distanceInterval); } private void whenAndThen(int numberOfPoints, float distanceInterval) { - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); whenAndThen(trackWithStats, numberOfPoints, distanceInterval); } - private void whenAndThen(Pair trackWithStats, int numberOfPoints, float distanceInterval) { + private void whenAndThen(Pair trackWithStats, int numberOfPoints, float distanceInterval) { IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(distanceInterval)); Track.Id trackId = trackWithStats.first; - TrackStatistics trackStatistics = trackWithStats.second; + SegmentStatisticUpdater trackStatistics = trackWithStats.second; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(trackPointIterator.getCount(), numberOfPoints); intervalStatistics.addTrackPoints(trackPointIterator); diff --git a/src/main/java/de/dennisguse/opentracks/chart/ChartFragment.java b/src/main/java/de/dennisguse/opentracks/chart/ChartFragment.java index 11a735734..c1b9714a3 100644 --- a/src/main/java/de/dennisguse/opentracks/chart/ChartFragment.java +++ b/src/main/java/de/dennisguse/opentracks/chart/ChartFragment.java @@ -38,12 +38,12 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.databinding.ChartBinding; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; /** * A fragment to display track chart to the user. - * ChartFragment uses a {@link TrackStatisticsUpdater} internally and recomputes the {@link TrackStatistics} from the beginning. + * ChartFragment uses a {@link TrackStatisticsUpdater} internally and recomputes the {@link SegmentStatisticUpdater} from the beginning. * * @author Sandor Dornbush * @author Rodrigo Damazio @@ -202,7 +202,7 @@ public class ChartFragment extends Fragment implements TrackDataHub.Listener { } } - public void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics trackStatistics) { + public void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull SegmentStatisticUpdater trackStatistics) { if (isResumed()) { ChartPoint point = ChartPoint.create(trackStatistics, trackPoint, trackPoint.getSpeed(), chartByDistance, viewBinding.chartView.getUnitSystem()); pendingPoints.add(point); diff --git a/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java b/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java index 9ceb9003e..c90cb628c 100644 --- a/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java +++ b/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java @@ -6,7 +6,7 @@ import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; public record ChartPoint( //X-axis @@ -22,7 +22,7 @@ public record ChartPoint( ) { - public static ChartPoint create(@NonNull TrackStatistics trackStatistics, @NonNull TrackPoint trackPoint, Speed smoothedSpeed, boolean chartByDistance, UnitSystem unitSystem) { + public static ChartPoint create(@NonNull SegmentStatisticUpdater trackStatistics, @NonNull TrackPoint trackPoint, Speed smoothedSpeed, boolean chartByDistance, UnitSystem unitSystem) { return new ChartPoint( chartByDistance ? trackStatistics.getTotalDistance().toKM_Miles(unitSystem) diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index bb1f1bc6f..7f99680ec 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -54,7 +54,7 @@ import de.dennisguse.opentracks.data.tables.MarkerColumns; import de.dennisguse.opentracks.data.tables.TrackPointsColumns; import de.dennisguse.opentracks.data.tables.TracksColumns; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.ui.markers.MarkerUtils; import de.dennisguse.opentracks.util.FileUtils; @@ -116,7 +116,7 @@ public class ContentProviderUtils { int altitudeLossIndex = cursor.getColumnIndexOrThrow(TracksColumns.ALTITUDE_LOSS); Track track = new Track(ZoneOffset.ofTotalSeconds(cursor.getInt(startTimeOffsetIndex))); - TrackStatistics trackStatistics = track.getTrackStatistics(); + SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); if (!cursor.isNull(idIndex)) { track.setId(new Track.Id(cursor.getLong(idIndex))); } @@ -314,7 +314,7 @@ public class ContentProviderUtils { private ContentValues createContentValues(Track track) { ContentValues values = new ContentValues(); - TrackStatistics trackStatistics = track.getTrackStatistics(); + SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); if (track.getId() != null) { values.put(TracksColumns._ID, track.getId().id()); @@ -345,11 +345,11 @@ public class ContentProviderUtils { return values; } - public void updateTrackStatistics(@NonNull Track.Id trackId, @NonNull TrackStatistics trackStatistics) { + public void updateTrackStatistics(@NonNull Track.Id trackId, @NonNull SegmentStatisticUpdater trackStatistics) { contentResolver.update(TracksColumns.CONTENT_URI, createContentValues(trackStatistics), TracksColumns._ID + "=?", new String[]{Long.toString(trackId.id())}); } - private ContentValues createContentValues(TrackStatistics trackStatistics) { + private ContentValues createContentValues(SegmentStatisticUpdater trackStatistics) { ContentValues values = new ContentValues(); if (trackStatistics.getStartTime() != null) { values.put(TracksColumns.STARTTIME, trackStatistics.getStartTime().toEpochMilli()); diff --git a/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java b/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java index 3216e8512..0cf59b9be 100644 --- a/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java +++ b/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java @@ -40,7 +40,7 @@ import de.dennisguse.opentracks.data.tables.TracksColumns; import de.dennisguse.opentracks.services.RecordingStatus; import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.services.handlers.AltitudeCorrectionManager; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; /** @@ -428,7 +428,7 @@ public class TrackDataHub { * * @param trackPoint the trackPoint */ - default void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics trackStatistics) { + default void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull SegmentStatisticUpdater trackStatistics) { } /** @@ -436,7 +436,7 @@ public class TrackDataHub { * * @param trackPoint the trackPoint */ - default void onSampledOutTrackPoint(@NonNull TrackPoint trackPoint, @NonNull TrackStatistics trackStatistics) { + default void onSampledOutTrackPoint(@NonNull TrackPoint trackPoint, @NonNull SegmentStatisticUpdater trackStatistics) { } /** diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Track.java b/src/main/java/de/dennisguse/opentracks/data/models/Track.java index e0a2347c6..5b9138659 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Track.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Track.java @@ -29,7 +29,7 @@ import java.time.ZoneOffset; import java.util.Objects; import java.util.UUID; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; /** * A track. @@ -51,7 +51,7 @@ public class Track { private ZoneOffset zoneOffset; - private TrackStatistics trackStatistics = new TrackStatistics(); + private SegmentStatisticUpdater trackStatistics = new SegmentStatisticUpdater(); @VisibleForTesting public Track() { @@ -138,11 +138,11 @@ public class Track { } @NonNull - public TrackStatistics getTrackStatistics() { + public SegmentStatisticUpdater getTrackStatistics() { return trackStatistics; } - public void setTrackStatistics(@NonNull TrackStatistics trackStatistics) { + public void setTrackStatistics(@NonNull SegmentStatisticUpdater trackStatistics) { this.trackStatistics = trackStatistics; } diff --git a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java index bff91e239..96fe90427 100644 --- a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java +++ b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java @@ -39,7 +39,7 @@ import de.dennisguse.opentracks.databinding.StatisticsRecordedBinding; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.util.StringUtils; /** @@ -171,7 +171,7 @@ public class StatisticsRecordedFragment extends Fragment { } private void updateUI() { - TrackStatistics trackStatistics = track.getTrackStatistics(); + SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); // Set total distance { Pair parts = DistanceFormatter.Builder() diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java index aa7de9a02..e95c4dbdc 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java @@ -39,7 +39,7 @@ import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.util.StringUtils; /** @@ -279,7 +279,7 @@ public class GPXTrackExporter implements TrackExporter { printWriter.println("" + StringUtils.formatCData(track.getActivityTypeLocalized()) + ""); } - TrackStatistics trackStatistics = track.getTrackStatistics(); + SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); printWriter.println(""); printWriter.println("" + trackStatistics.getTotalDistance().toM() + ""); printWriter.println("" + trackStatistics.getTotalTime().getSeconds() + ""); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporter.java index 452231dfe..e7e258667 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporter.java @@ -38,6 +38,7 @@ import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.util.StringUtils; /** @@ -48,7 +49,7 @@ import de.dennisguse.opentracks.util.StringUtils; *

* {@link de.dennisguse.opentracks.io.file.exporter.GPXTrackExporter} does not export information if a segment was started automatic or manually. * Therefore, all segments starts are marked as SEGMENT_START_AUTOMATIC. - * Thus, the {@link de.dennisguse.opentracks.stats.TrackStatistics} cannot be restored correctly. + * Thus, the {@link SegmentStatisticUpdater} cannot be restored correctly. * * @author Jimmy Shih */ diff --git a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java index 92d9734a3..04fd36150 100644 --- a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java +++ b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java @@ -5,12 +5,12 @@ import androidx.annotation.NonNull; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; /** * {@link Track} and {@link TrackPoint} must be immutable (i.e., their content does not change). */ -public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorDataSet sensorDataSet, TrackStatistics currentSegment) { +public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorDataSet sensorDataSet, SegmentStatisticUpdater currentSegment) { public String getTrackCategory() { if (track == null) { return ""; @@ -19,18 +19,18 @@ public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorData } @NonNull - public TrackStatistics getStatisticsTrack() { + public SegmentStatisticUpdater getStatisticsTrack() { if (track == null) { - return new TrackStatistics(); + return new SegmentStatisticUpdater(); } return track.getTrackStatistics(); } @NonNull - public TrackStatistics getStatisticsCurrentSegment() { + public SegmentStatisticUpdater getStatisticsCurrentSegment() { if (currentSegment == null) { - return new TrackStatistics(); + return new SegmentStatisticUpdater(); } return currentSegment; diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java index a30bb330a..663a16596 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java @@ -23,7 +23,7 @@ import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.services.handlers.AltitudeCorrectionManager; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; import de.dennisguse.opentracks.settings.PreferencesUtils; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; import de.dennisguse.opentracks.util.TrackNameUtils; @@ -131,7 +131,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen } track.setTrackStatistics(tmpTrackStatisticsUpdater.getTrackStatistics()); - TrackStatistics currentSegment = tmpTrackStatisticsUpdater.getCurrentSegment(); + SegmentStatisticUpdater currentSegment = tmpTrackStatisticsUpdater.getCurrentSegment(); return new RecordingData(track, current.first, current.second, currentSegment); } @@ -225,7 +225,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen handler.postDelayed(ON_IDLE, idleDuration.toMillis()); } - TrackStatistics getTrackStatistics() { + SegmentStatisticUpdater getTrackStatistics() { return trackStatisticsUpdater == null ? null : trackStatisticsUpdater.getTrackStatistics(); } diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java index 322a1c611..6a6e363b0 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java @@ -37,7 +37,7 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; /** @@ -53,7 +53,7 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe private TTSManager voiceAnnouncement; - private TrackStatistics trackStatistics; + private SegmentStatisticUpdater trackStatistics; private static final Distance DISTANCE_OFF = Distance.of(Double.MAX_VALUE); private Distance distanceFrequency = DISTANCE_OFF; @@ -79,13 +79,13 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe intervalStatistics = new IntervalStatistics(intervalDistance); } - public void start(@Nullable TrackStatistics trackStatistics) { + public void start(@Nullable SegmentStatisticUpdater trackStatistics) { voiceAnnouncement = new TTSManager(context); voiceAnnouncement.start(); update(trackStatistics); } - void update(@Nullable TrackStatistics trackStatistics) { + void update(@Nullable SegmentStatisticUpdater trackStatistics) { this.trackStatistics = trackStatistics; updateNextDuration(); updateNextTaskDistance(); diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java index ab3be8785..03ab3fb5c 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java @@ -37,7 +37,7 @@ import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; import de.dennisguse.opentracks.util.StringUtils; @@ -52,7 +52,7 @@ class VoiceAnnouncementUtils { } static Spannable createStatistics(Context context, Track track, SensorDataSet sensorDataSet, UnitSystem unitSystem, boolean isReportSpeed, @Nullable IntervalStatistics.Interval currentInterval, @Nullable SensorStatistics sensorStatistics) { - TrackStatistics trackStatistics = track.getTrackStatistics(); + SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); SpannableStringBuilder builder = new SpannableStringBuilder(); diff --git a/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java b/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java index 1a1039162..071f23fff 100644 --- a/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java +++ b/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java @@ -31,7 +31,7 @@ import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.SpeedFormatter; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.util.StringUtils; /** @@ -78,7 +78,7 @@ public class TrackShareSummaryGenerator { builder.append(TrackShareSummaryGenerator.TEXT_LINE_BREAK); } - private String generateTrackStatisticsDescription(TrackStatistics stats) { + private String generateTrackStatisticsDescription(SegmentStatisticUpdater stats) { StringBuilder builder = new StringBuilder(); // Total distance diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatistics.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java similarity index 96% rename from src/main/java/de/dennisguse/opentracks/stats/TrackStatistics.java rename to src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 203219d39..5b1d7fc1a 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatistics.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -39,7 +39,7 @@ import de.dennisguse.opentracks.data.models.TrackPoint; */ //TODO Check that data ranges are valid (not less than zero etc.) //TODO Should be a Java record -public class TrackStatistics { +public class SegmentStatisticUpdater { // The min and max altitude (meters) seen on this track. private final ExtremityMonitor altitudeExtremities = new ExtremityMonitor(); @@ -64,7 +64,7 @@ public class TrackStatistics { private boolean isIdle; - public TrackStatistics() { + public SegmentStatisticUpdater() { reset(); } @@ -73,7 +73,7 @@ public class TrackStatistics { * * @param other another statistics data object to copy from */ - public TrackStatistics(TrackStatistics other) { + public SegmentStatisticUpdater(SegmentStatisticUpdater other) { startTime = other.startTime; stopTime = other.stopTime; totalDistance = other.totalDistance; @@ -89,7 +89,7 @@ public class TrackStatistics { } @VisibleForTesting - public TrackStatistics(String startTime, String stopTime, double totalDistance_m, int totalTime_s, int movingTime_s, float maxSpeed_mps, Float totalAltitudeGain_m, Float totalAltitudeLoss_m) { + public SegmentStatisticUpdater(String startTime, String stopTime, double totalDistance_m, int totalTime_s, int movingTime_s, float maxSpeed_mps, Float totalAltitudeGain_m, Float totalAltitudeLoss_m) { this.startTime = Instant.parse(startTime); this.stopTime = Instant.parse(stopTime); this.totalDistance = Distance.of(totalDistance_m); @@ -107,7 +107,7 @@ public class TrackStatistics { * @param other another statistics data object */ //TODO Should be refactored to append only [mainly due to isIdle] (NOTE: This requires to use a custom value object for AggregatedStatistics; this is anyhow recommended). - public void merge(TrackStatistics other) { + public void merge(SegmentStatisticUpdater other) { if (startTime == null) { startTime = other.startTime; } else { @@ -407,7 +407,7 @@ public class TrackStatistics { @Override public boolean equals(Object o) { if (this == o) return true; - if (!(o instanceof TrackStatistics)) return false; + if (!(o instanceof SegmentStatisticUpdater)) return false; return toString().equals(o.toString()); } diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index 9e84fbfca..f0558e06d 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -29,8 +29,8 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.PreferencesUtils; /** - * Updater for {@link TrackStatistics}. - * For updating track {@link TrackStatistics} as new {@link TrackPoint}s are added. + * Updater for {@link SegmentStatisticUpdater}. + * For updating track {@link SegmentStatisticUpdater} as new {@link TrackPoint}s are added. * NOTE: Some of the locations represent pause/resume separator. * NOTE: Has still support for segments (at the moment unused). * @@ -41,7 +41,7 @@ public class TrackStatisticsUpdater { private static final String TAG = TrackStatisticsUpdater.class.getSimpleName(); - private final TrackStatistics trackStatistics; + private final SegmentStatisticUpdater segmentStatisticUpdater; private float averageHeartRateBPM; private Duration totalHeartRateDuration = Duration.ZERO; @@ -49,38 +49,38 @@ public class TrackStatisticsUpdater { private Duration totalPowerDuration = Duration.ZERO; // The current segment's statistics - private final TrackStatistics currentSegment; + private final SegmentStatisticUpdater currentSegment; // Current segment's last trackPoint private TrackPoint lastTrackPoint; public TrackStatisticsUpdater() { - this(new TrackStatistics()); + this(new SegmentStatisticUpdater()); } - public TrackStatisticsUpdater(TrackStatistics trackStatistics) { - this.trackStatistics = trackStatistics; - this.currentSegment = new TrackStatistics(); + public TrackStatisticsUpdater(SegmentStatisticUpdater segmentStatisticUpdater) { + this.segmentStatisticUpdater = segmentStatisticUpdater; + this.currentSegment = new SegmentStatisticUpdater(); resetAverageHeartRate(); } public TrackStatisticsUpdater(TrackStatisticsUpdater toCopy) { - this.currentSegment = new TrackStatistics(toCopy.currentSegment); - this.trackStatistics = new TrackStatistics(toCopy.trackStatistics); + this.currentSegment = new SegmentStatisticUpdater(toCopy.currentSegment); + this.segmentStatisticUpdater = new SegmentStatisticUpdater(toCopy.segmentStatisticUpdater); this.lastTrackPoint = toCopy.lastTrackPoint; resetAverageHeartRate(); } - public TrackStatistics getTrackStatistics() { + public SegmentStatisticUpdater getTrackStatistics() { // Take a snapshot - we don't want anyone messing with our trackStatistics - TrackStatistics stats = new TrackStatistics(trackStatistics); + SegmentStatisticUpdater stats = new SegmentStatisticUpdater(segmentStatisticUpdater); stats.merge(currentSegment); return stats; } - public TrackStatistics getCurrentSegment() { + public SegmentStatisticUpdater getCurrentSegment() { // Take a snapshot - we don't want anyone messing with our currentSegment - return new TrackStatistics(currentSegment); + return new SegmentStatisticUpdater(currentSegment); } public void addTrackPoints(List trackPoints) { @@ -182,7 +182,7 @@ public class TrackStatisticsUpdater { private void reset(TrackPoint trackPoint) { if (currentSegment.isInitialized()) { - trackStatistics.merge(currentSegment); + segmentStatisticUpdater.merge(currentSegment); } currentSegment.reset(trackPoint.getTime()); @@ -209,7 +209,7 @@ public class TrackStatisticsUpdater { @Override public String toString() { return "TrackStatisticsUpdater{" + - "trackStatistics=" + trackStatistics + + "trackStatistics=" + segmentStatisticUpdater + '}'; } } diff --git a/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatistics.java b/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatistics.java index 8de17659d..40e8bffcb 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatistics.java +++ b/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatistics.java @@ -9,7 +9,7 @@ import java.util.List; import java.util.Map; import de.dennisguse.opentracks.data.models.Track; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; public class AggregatedStatistics { @@ -55,10 +55,10 @@ public class AggregatedStatistics { public static class AggregatedStatistic { private final String activityTypeLocalized; - private final TrackStatistics trackStatistics; + private final SegmentStatisticUpdater trackStatistics; private int countTracks = 1; - public AggregatedStatistic(String activityTypeLocalized, TrackStatistics trackStatistics) { + public AggregatedStatistic(String activityTypeLocalized, SegmentStatisticUpdater trackStatistics) { this.activityTypeLocalized = activityTypeLocalized; this.trackStatistics = trackStatistics; } @@ -67,7 +67,7 @@ public class AggregatedStatistics { return activityTypeLocalized; } - public TrackStatistics getTrackStatistics() { + public SegmentStatisticUpdater getTrackStatistics() { return trackStatistics; } @@ -75,7 +75,7 @@ public class AggregatedStatistics { return countTracks; } - void add(TrackStatistics statistics) { + void add(SegmentStatisticUpdater statistics) { trackStatistics.merge(statistics); countTracks++; } diff --git a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java index 45d19a368..0c8a12fe3 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java +++ b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java @@ -27,7 +27,7 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.databinding.CustomStatsItemBinding; import de.dennisguse.opentracks.services.RecordingData; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.TrackStatistics; +import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.viewmodels.Mapping; import de.dennisguse.opentracks.viewmodels.StatisticViewHolder; @@ -38,7 +38,7 @@ public class SettingsCustomLayoutEditAdapter extends RecyclerView.Adapter Date: Sun, 26 Oct 2025 20:23:39 +0100 Subject: [PATCH 02/30] Introduced Statistics as a value object. --- .../opentracks/data/models/Track.java | 15 +++++++ .../opentracks/services/RecordingData.java | 14 ++---- .../services/TrackRecordingManager.java | 3 +- .../stats/SegmentStatisticUpdater.java | 19 ++++++++ .../opentracks/stats/Statistics.java | 43 +++++++++++++++++++ .../stats/TrackStatisticsUpdater.java | 6 +-- .../SettingsCustomLayoutEditAdapter.java | 30 ++++++++----- .../GenericStatisticsViewHolder.java | 4 +- 8 files changed, 105 insertions(+), 29 deletions(-) create mode 100644 src/main/java/de/dennisguse/opentracks/stats/Statistics.java diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Track.java b/src/main/java/de/dennisguse/opentracks/data/models/Track.java index 5b9138659..7057762bb 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Track.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Track.java @@ -30,6 +30,7 @@ import java.util.Objects; import java.util.UUID; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; /** * A track. @@ -51,6 +52,7 @@ public class Track { private ZoneOffset zoneOffset; + @Deprecated // TODO Replace with Statistic private SegmentStatisticUpdater trackStatistics = new SegmentStatisticUpdater(); @VisibleForTesting @@ -137,15 +139,26 @@ public class Track { .getStopTime().atOffset(zoneOffset); } + public Statistics getStatistics() { + return trackStatistics.getStatistics(); + } + + public Statistics setStatistics() { + throw new RuntimeException("TODO"); + } + + @Deprecated @NonNull public SegmentStatisticUpdater getTrackStatistics() { return trackStatistics; } + @Deprecated public void setTrackStatistics(@NonNull SegmentStatisticUpdater trackStatistics) { this.trackStatistics = trackStatistics; } + @NonNull @Override public String toString() { return "Track{" + @@ -156,6 +169,7 @@ public class Track { '}'; } + @Deprecated //TODO Remove: should not be used. @Override public boolean equals(Object o) { if (this == o) return true; @@ -164,6 +178,7 @@ public class Track { return id.equals(track.id); } + @Deprecated //TODO Remove: should not be used. @Override public int hashCode() { return Objects.hash(id); diff --git a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java index 04fd36150..49383afe5 100644 --- a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java +++ b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java @@ -6,11 +6,13 @@ import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; /** * {@link Track} and {@link TrackPoint} must be immutable (i.e., their content does not change). */ -public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorDataSet sensorDataSet, SegmentStatisticUpdater currentSegment) { +public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorDataSet sensorDataSet, + Statistics currentSegment) { public String getTrackCategory() { if (track == null) { return ""; @@ -26,14 +28,4 @@ public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorData return track.getTrackStatistics(); } - - @NonNull - public SegmentStatisticUpdater getStatisticsCurrentSegment() { - if (currentSegment == null) { - return new SegmentStatisticUpdater(); - } - - return currentSegment; - } - } diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java index 663a16596..87ab306e4 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java @@ -131,9 +131,8 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen } track.setTrackStatistics(tmpTrackStatisticsUpdater.getTrackStatistics()); - SegmentStatisticUpdater currentSegment = tmpTrackStatisticsUpdater.getCurrentSegment(); - return new RecordingData(track, current.first, current.second, currentSegment); + return new RecordingData(track, current.first, current.second, tmpTrackStatisticsUpdater.getCurrentSegment()); } @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 5b1d7fc1a..9fb1ef587 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -24,6 +24,7 @@ import java.time.Duration; import java.time.Instant; import de.dennisguse.opentracks.data.models.Altitude; +import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Power; @@ -198,6 +199,24 @@ public class SegmentStatisticUpdater { setStartTime(startTime); } + public Statistics getStatistics() { + return new Statistics( + startTime, + stopTime, + totalTime, + movingTime, + + totalDistance, + isIdle, + getMaxSpeed(), + altitudeExtremities.hasData() ? altitudeExtremities.getMin() : null, + altitudeExtremities.hasData() ? altitudeExtremities.getMax() : null, + totalAltitudeGain_m != null && totalAltitudeLoss_m != null ? new AltitudeGainLoss(totalAltitudeGain_m, totalAltitudeLoss_m) : null, + avgHeartRate, + avgPower + ); + } + public Instant getStartTime() { return startTime; } diff --git a/src/main/java/de/dennisguse/opentracks/stats/Statistics.java b/src/main/java/de/dennisguse/opentracks/stats/Statistics.java new file mode 100644 index 000000000..b27ddd716 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/stats/Statistics.java @@ -0,0 +1,43 @@ +package de.dennisguse.opentracks.stats; + +import androidx.annotation.Nullable; + +import java.time.Duration; +import java.time.Instant; + +import de.dennisguse.opentracks.data.models.AltitudeGainLoss; +import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.HeartRate; +import de.dennisguse.opentracks.data.models.Power; +import de.dennisguse.opentracks.data.models.Speed; + +public record Statistics( + Instant startTime, + Instant stopTime, + //TODO Rename to totalDuration + Duration totalTime, + //TODO Rename to movingDuration + Duration movingTime, // Based on when we believe the user is traveling + + Distance totalDistance, + boolean isIdle, //TODO Check if this is persisted; if not: remove + Speed maxSpeed, + + //TODO Create record for min/max altitude + @Nullable + Double altitudeMin_m, + @Nullable + Double altitudeMax_m, + + @Nullable + AltitudeGainLoss altitudeGainLoss, + @Nullable + HeartRate avgHeartRate, + @Nullable + Power avgPower +) { + + public Speed getAverageMovingSpeed() { + return Speed.of(totalDistance, movingTime); + } +} diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index f0558e06d..f1b075b53 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -78,9 +78,9 @@ public class TrackStatisticsUpdater { stats.merge(currentSegment); return stats; } - public SegmentStatisticUpdater getCurrentSegment() { - // Take a snapshot - we don't want anyone messing with our currentSegment - return new SegmentStatisticUpdater(currentSegment); + + public Statistics getCurrentSegment() { + return currentSegment.getStatistics(); } public void addTrackPoints(List trackPoints) { diff --git a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java index 0c8a12fe3..438d0b4f0 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java +++ b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java @@ -19,6 +19,7 @@ import java.util.concurrent.Callable; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.models.Altitude; +import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Speed; @@ -27,7 +28,7 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.databinding.CustomStatsItemBinding; import de.dennisguse.opentracks.services.RecordingData; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.viewmodels.Mapping; import de.dennisguse.opentracks.viewmodels.StatisticViewHolder; @@ -38,17 +39,24 @@ public class SettingsCustomLayoutEditAdapter extends RecyclerView.Adapter valueAndUnit = speedFormatterSpeed.getSpeedParts(data.getStatisticsCurrentSegment().getAverageMovingSpeed()); + Pair valueAndUnit = speedFormatterSpeed.getSpeedParts(data.currentSegment().getAverageMovingSpeed()); getBinding().statsValue.setText(valueAndUnit.first); getBinding().statsUnit.setText(valueAndUnit.second); @@ -220,7 +220,7 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder Date: Mon, 27 Oct 2025 19:26:22 +0100 Subject: [PATCH 03/30] Statistics: used when only the data is needed (instead of passing SegmentStatisticUpdater). --- .../io/file/importer/ExportImportTest.java | 56 +++++++++---------- .../file/importer/GPXTrackImporterTest.java | 14 ++--- ...cordingServiceNotificationManagerTest.java | 20 ++++++- .../TrackRecordingServiceRecordingTest.java | 43 +++++++------- .../VoiceAnnouncementManagerTest.java | 8 +-- .../opentracks/TrackStoppedActivity.java | 6 +- .../opentracks/data/ContentProviderUtils.java | 37 +++++++----- .../opentracks/data/models/Speed.java | 1 + .../fragments/StatisticsRecordedFragment.java | 16 +++--- .../io/file/exporter/GPXTrackExporter.java | 20 +++---- .../opentracks/services/RecordingData.java | 7 ++- .../services/TrackRecordingManager.java | 2 +- .../services/TrackRecordingService.java | 2 +- ...ckRecordingServiceNotificationManager.java | 2 +- .../VoiceAnnouncementManager.java | 21 ++++--- .../announcement/VoiceAnnouncementUtils.java | 8 +-- .../share/TrackShareSummaryGenerator.java | 36 ++++++------ .../stats/SegmentStatisticUpdater.java | 6 +- .../opentracks/stats/Statistics.java | 25 +++++++++ .../stats/TrackStatisticsUpdater.java | 1 + .../GenericStatisticsViewHolder.java | 16 +++--- 21 files changed, 197 insertions(+), 150 deletions(-) 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 2bf4cb0d3..11231b5f0 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 @@ -75,7 +75,7 @@ import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; /** * Export a track to {@link TrackFileFormat} and verify that the import is identical. @@ -203,20 +203,20 @@ public class ExportImportTest { setUp(); Track track = contentProviderUtils.getTrack(trackId); - SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); + Statistics trackStatistics = track.getStatistics(); assertEquals(ZoneOffset.of("+01:00"), track.getZoneOffset()); - assertEquals(Instant.parse("2020-02-02T02:02:02Z"), trackStatistics.getStartTime()); - assertEquals(Instant.parse("2020-02-02T02:04:00Z"), trackStatistics.getStopTime()); + assertEquals(Instant.parse("2020-02-02T02:02:02Z"), trackStatistics.startTime()); + assertEquals(Instant.parse("2020-02-02T02:04:00Z"), trackStatistics.stopTime()); - assertEquals(Duration.ofSeconds(56), trackStatistics.getTotalTime()); - assertEquals(Duration.ofSeconds(26), trackStatistics.getMovingTime()); //TODO Likely too low + assertEquals(Duration.ofSeconds(56), trackStatistics.totalTime()); + assertEquals(Duration.ofSeconds(26), trackStatistics.movingTime()); //TODO Likely too low // Distance - assertEquals(222049.34375, trackStatistics.getTotalDistance().toM(), 0.01); //TODO Too low + assertEquals(222049.34375, trackStatistics.totalDistance().toM(), 0.01); //TODO Too low // Speed - assertEquals(8540.359, trackStatistics.getMaxSpeed().toMPS(), 0.01); + assertEquals(8540.359, trackStatistics.maxSpeed().toMPS(), 0.01); assertEquals(3965.166, trackStatistics.getAverageSpeed().toMPS(), 0.01); assertEquals(8540.359, trackStatistics.getAverageMovingSpeed().toMPS(), 0.01); @@ -224,8 +224,8 @@ public class ExportImportTest { assertEquals(999.122, trackStatistics.getMinAltitude(), 0.01); assertEquals(1020.25, trackStatistics.getMaxAltitude(), 0.01); - assertEquals(2, trackStatistics.getTotalAltitudeGain(), 0.01); - assertEquals(2, trackStatistics.getTotalAltitudeLoss(), 0.01); + assertEquals(2, trackStatistics.altitudeGainLoss().gain_m(), 0.01); + assertEquals(2, trackStatistics.altitudeGainLoss().loss_m(), 0.01); List actual = TestDataUtil.getTrackPoints(contentProviderUtils, trackId); new TrackPointAssert().assertEquals(List.of( @@ -334,29 +334,29 @@ public class ExportImportTest { a.assertEquals(trackPoints, actual); // 3. trackstatistics - SegmentStatisticUpdater importedTrackStatistics = importedTrack.getTrackStatistics(); + Statistics importedTrackStatistics = importedTrack.getStatistics(); // Time assertEquals(track.getZoneOffset(), importedTrack.getZoneOffset()); - assertEquals(Instant.parse("2020-02-02T02:02:02Z"), importedTrackStatistics.getStartTime()); - assertEquals(Instant.parse("2020-02-02T02:04:00Z"), importedTrackStatistics.getStopTime()); + assertEquals(Instant.parse("2020-02-02T02:02:02Z"), importedTrackStatistics.startTime()); + assertEquals(Instant.parse("2020-02-02T02:04:00Z"), importedTrackStatistics.stopTime()); - assertEquals(Duration.ofSeconds(56), importedTrackStatistics.getTotalTime()); - assertEquals(Duration.ofSeconds(26), importedTrackStatistics.getMovingTime()); + assertEquals(Duration.ofSeconds(56), importedTrackStatistics.totalTime()); + assertEquals(Duration.ofSeconds(26), importedTrackStatistics.movingTime()); // Distance - assertEquals(222049.421, importedTrackStatistics.getTotalDistance().toM(), 0.01); + assertEquals(222049.421, importedTrackStatistics.totalDistance().toM(), 0.01); // Speed - assertEquals(8540.362, importedTrackStatistics.getMaxSpeed().toMPS(), 0.01); + assertEquals(8540.362, importedTrackStatistics.maxSpeed().toMPS(), 0.01); assertEquals(3965.168, importedTrackStatistics.getAverageSpeed().toMPS(), 0.01); assertEquals(8540.362, importedTrackStatistics.getAverageMovingSpeed().toMPS(), 0.01); // Altitude assertEquals(999.122, importedTrackStatistics.getMinAltitude(), 0.01); assertEquals(1020.25, importedTrackStatistics.getMaxAltitude(), 0.01); - assertEquals(2, importedTrackStatistics.getTotalAltitudeGain(), 0.01); - assertEquals(2, importedTrackStatistics.getTotalAltitudeLoss(), 0.01); + assertEquals(2, importedTrackStatistics.altitudeGainLoss().gain_m(), 0.01); + assertEquals(2, importedTrackStatistics.altitudeGainLoss().loss_m(), 0.01); // 4. markers @@ -479,29 +479,29 @@ public class ExportImportTest { ), actual); // 3. trackstatistics - SegmentStatisticUpdater importedTrackStatistics = importedTrack.getTrackStatistics(); + Statistics importedTrackStatistics = importedTrack.getStatistics(); // Time assertEquals(track.getZoneOffset(), importedTrack.getZoneOffset()); - assertEquals(Instant.parse("2020-02-02T02:02:03Z"), importedTrackStatistics.getStartTime()); - assertEquals(Instant.parse("2020-02-02T02:03:50Z"), importedTrackStatistics.getStopTime()); + assertEquals(Instant.parse("2020-02-02T02:02:03Z"), importedTrackStatistics.startTime()); + assertEquals(Instant.parse("2020-02-02T02:03:50Z"), importedTrackStatistics.stopTime()); - assertEquals(Duration.ofSeconds(107), importedTrackStatistics.getTotalTime()); - assertEquals(Duration.ofSeconds(107), importedTrackStatistics.getMovingTime()); + assertEquals(Duration.ofSeconds(107), importedTrackStatistics.totalTime()); + assertEquals(Duration.ofSeconds(107), importedTrackStatistics.movingTime()); // Distance - assertEquals(222271.734, importedTrackStatistics.getTotalDistance().toM(), 0.01); + assertEquals(222271.734, importedTrackStatistics.totalDistance().toM(), 0.01); // Speed - assertEquals(2077.305, importedTrackStatistics.getMaxSpeed().toMPS(), 0.01); + assertEquals(2077.305, importedTrackStatistics.maxSpeed().toMPS(), 0.01); assertEquals(2077.305, importedTrackStatistics.getAverageSpeed().toMPS(), 0.01); assertEquals(2077.305, importedTrackStatistics.getAverageMovingSpeed().toMPS(), 0.01); // Altitude assertEquals(999.099, importedTrackStatistics.getMinAltitude(), 0.01); assertEquals(1020.2, importedTrackStatistics.getMaxAltitude(), 0.01); - assertEquals(2, importedTrackStatistics.getTotalAltitudeGain(), 0.01); - assertEquals(2, importedTrackStatistics.getTotalAltitudeLoss(), 0.01); + assertEquals(2, importedTrackStatistics.altitudeGainLoss().gain_m(), 0.01); + assertEquals(2, importedTrackStatistics.altitudeGainLoss().loss_m(), 0.01); // 4. markers assertMarkers(); diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java index df2b4db5b..05dac22bb 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java @@ -34,7 +34,7 @@ import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.io.file.TrackFileFormat; import de.dennisguse.opentracks.io.file.exporter.TrackExporter; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; /** * Test that legacy KML/GPX formats can still be imported. @@ -149,9 +149,9 @@ public class GPXTrackImporterTest { assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType()); // 3. trackstatistics - SegmentStatisticUpdater trackStatistics = importedTrack.getTrackStatistics(); - assertEquals(0.75, trackStatistics.getMaxSpeed().toMPS(), 0.01); - assertEquals(Duration.ofSeconds(101), trackStatistics.getMovingTime()); + Statistics trackStatistics = importedTrack.getStatistics(); + assertEquals(0.75, trackStatistics.maxSpeed().toMPS(), 0.01); + assertEquals(Duration.ofSeconds(101), trackStatistics.movingTime()); // 4. trackpoints List importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId); @@ -204,9 +204,9 @@ public class GPXTrackImporterTest { assertEquals(ActivityType.UNKNOWN, importedTrack.getActivityType()); // 3. trackstatistics - SegmentStatisticUpdater trackStatistics = importedTrack.getTrackStatistics(); - assertEquals(5.0, trackStatistics.getMaxSpeed().toMPS(), 0.01); - assertEquals(Duration.ofSeconds(101), trackStatistics.getMovingTime()); + Statistics trackStatistics = importedTrack.getStatistics(); + assertEquals(5.0, trackStatistics.maxSpeed().toMPS(), 0.01); + assertEquals(Duration.ofSeconds(101), trackStatistics.movingTime()); // 4. trackpoints List importedTrackPoints = TestDataUtil.getTrackPoints(contentProviderUtils, importTrackId); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java index 2eab35723..05b4a7d3d 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java @@ -22,6 +22,7 @@ import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; @RunWith(MockitoJUnitRunner.class) public class TrackRecordingServiceNotificationManagerTest { @@ -29,10 +30,10 @@ public class TrackRecordingServiceNotificationManagerTest { private final Context context = ApplicationProvider.getApplicationContext(); @Mock - private TrackPoint trackPointMock; + private TrackPoint trackPointMock; //TODO No mock @Mock - private SegmentStatisticUpdater trackStatisticsMock; + private SegmentStatisticUpdater trackStatisticsMock; //TODO only use Statistic (not mock) @Mock private NotificationCompat.Builder notificationCompatBuilder; @@ -45,7 +46,20 @@ public class TrackRecordingServiceNotificationManagerTest { when(trackPointMock.hasHorizontalAccuracy()).thenReturn(true); when(trackPointMock.getHorizontalAccuracy()).thenReturn(Distance.of(999f)); when(trackPointMock.getSpeed()).thenReturn(Speed.of(0)); - when(trackStatisticsMock.getTotalDistance()).thenReturn(Distance.of(0)); + when(trackStatisticsMock.getStatistics()).thenReturn(new Statistics( + null, + null, + null, + null, + Distance.of(0), + false, + null, + null, + null, + null, + null, + null + )); when(notificationCompatBuilder.setOnlyAlertOnce(anyBoolean())) .thenReturn(notificationCompatBuilder); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java index 5d51a98e5..f08460df1 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java @@ -192,8 +192,8 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, pauseTime, 0, 1, 1, 0, 0f, 0f) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new SegmentStatisticUpdater(startTime, pauseTime, 0, 1, 1, 0, 0f, 0f).getStatistics() + , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), @@ -208,8 +208,8 @@ public class TrackRecordingServiceRecordingTest { service.resumeTrack(trackId); // then - assertEquals(new SegmentStatisticUpdater(startTime, resumeTime, 0, 1, 1, 0, 0f, 0f) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new SegmentStatisticUpdater(startTime, resumeTime, 0, 1, 1, 0, 0f, 0f).getStatistics() + , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), @@ -341,24 +341,24 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f).getStatistics() + , contentProviderUtils.getTrack(trackId).getStatistics()); // when String gps2 = "2020-02-02T02:02:06Z"; TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.0001, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps2, 11.113178253173828f, 4, 4, 15, 0f, 0f) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new SegmentStatisticUpdater(startTime, gps2, 11.113178253173828f, 4, 4, 15, 0f, 0f).getStatistics() + , contentProviderUtils.getTrack(trackId).getStatistics()); // when String gps3 = "2020-02-02T02:02:08Z"; TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps3, 45.0002, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps3, 22.226356506347656, 6, 6, 15, 0f, 0f) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new SegmentStatisticUpdater(startTime, gps3, 22.226356506347656, 6, 6, 15, 0f, 0f).getStatistics() + , contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -367,8 +367,8 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 22.226356506347656, 10, 10, 15, 0f, 0f) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 22.226356506347656, 10, 10, 15, 0f, 0f).getStatistics() + , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), @@ -421,21 +421,21 @@ public class TrackRecordingServiceRecordingTest { // then SegmentStatisticUpdater gps1Statistics = new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f); - assertEquals(gps1Statistics, contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(gps1Statistics.getStatistics(), contentProviderUtils.getTrack(trackId).getStatistics()); // when String gps2 = "2020-02-02T02:02:06Z"; TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.00001, 35.0, 1, 15); // then - assertEquals(gps1Statistics, contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(gps1Statistics.getStatistics(), contentProviderUtils.getTrack(trackId).getStatistics()); // when String gps3 = "2020-02-02T02:02:08Z"; TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps3, 45.00002, 35.0, 1, 15); // then - assertEquals(gps1Statistics, contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(gps1Statistics.getStatistics(), contentProviderUtils.getTrack(trackId).getStatistics()); // when String stopTime = "2020-02-02T02:02:12Z"; @@ -443,8 +443,8 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 2.222635507583618, 10, 10, 15, 0f, 0f) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 2.222635507583618, 10, 10, 15, 0f, 0f).getStatistics() + , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), @@ -594,14 +594,16 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f), contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f).getStatistics(), + contentProviderUtils.getTrack(trackId).getStatistics()); // when String gps2 = "2020-02-02T02:02:06Z"; TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.1, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps2, 11113.275390625, 4, 4, 2778.31884765625f, 0f, 0f).toString(), contentProviderUtils.getTrack(trackId).getTrackStatistics().toString()); + assertEquals(new SegmentStatisticUpdater(startTime, gps2, 11113.275390625, 4, 4, 2778.31884765625f, 0f, 0f).getStatistics(), + contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -610,7 +612,8 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 11113.275390625, 10, 10, 1111.3275390625f, 0f, 0f).toString(), contentProviderUtils.getTrack(trackId).getTrackStatistics().toString()); + assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 11113.275390625, 10, 10, 1111.3275390625f, 0f, 0f).getStatistics() + , contentProviderUtils.getTrack(trackId).getStatistics()); // then diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManagerTest.java index 178ed06af..9b2098d34 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManagerTest.java @@ -56,11 +56,11 @@ public class VoiceAnnouncementManagerTest { // when SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); statistics.setTotalDistance(Distance.ofKilometer(13)); - voiceAnnouncementManager.start(statistics); + voiceAnnouncementManager.start(statistics.getStatistics()); assertEquals(Distance.of(15000), voiceAnnouncementManager.getNextTotalDistance()); statistics.setTotalDistance(Distance.of(15100)); - voiceAnnouncementManager.start(statistics); + voiceAnnouncementManager.start(statistics.getStatistics()); assertEquals(Distance.of(20000), voiceAnnouncementManager.getNextTotalDistance()); } @@ -76,11 +76,11 @@ public class VoiceAnnouncementManagerTest { // when SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); statistics.setTotalTime(Duration.ofSeconds(91)); - voiceAnnouncementManager.start(statistics); + voiceAnnouncementManager.start(statistics.getStatistics()); assertEquals(Duration.ofSeconds(95), voiceAnnouncementManager.getNextTotalTime()); statistics.setTotalTime(Duration.ofSeconds(95)); - voiceAnnouncementManager.start(statistics); + voiceAnnouncementManager.start(statistics.getStatistics()); assertEquals(Duration.ofSeconds(100), voiceAnnouncementManager.getNextTotalTime()); } diff --git a/src/main/java/de/dennisguse/opentracks/TrackStoppedActivity.java b/src/main/java/de/dennisguse/opentracks/TrackStoppedActivity.java index 34fbfa441..3d65d59b3 100644 --- a/src/main/java/de/dennisguse/opentracks/TrackStoppedActivity.java +++ b/src/main/java/de/dennisguse/opentracks/TrackStoppedActivity.java @@ -68,14 +68,14 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements viewBinding.trackEditDescription.setText(track.getDescription()); - viewBinding.time.setText(StringUtils.formatElapsedTime(track.getTrackStatistics().getMovingTime())); + viewBinding.time.setText(StringUtils.formatElapsedTime(track.getStatistics().movingTime())); { Pair parts = SpeedFormatter.Builder() .setUnit(PreferencesUtils.getUnitSystem()) .setReportSpeedOrPace(PreferencesUtils.isReportSpeed(track)) .build(this) - .getSpeedParts(track.getTrackStatistics().getAverageMovingSpeed()); + .getSpeedParts(track.getStatistics().getAverageMovingSpeed()); viewBinding.speed.setText(parts.first); viewBinding.speedUnit.setText(parts.second); } @@ -84,7 +84,7 @@ public class TrackStoppedActivity extends AbstractTrackDeleteActivity implements Pair parts = DistanceFormatter.Builder() .setUnit(PreferencesUtils.getUnitSystem()) .build(this) - .getDistanceParts(track.getTrackStatistics().getTotalDistance()); + .getDistanceParts(track.getStatistics().totalDistance()); viewBinding.distance.setText(parts.first); viewBinding.distanceUnit.setText(parts.second); } diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index 7f99680ec..7e7c87130 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -53,8 +53,9 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.data.tables.MarkerColumns; import de.dennisguse.opentracks.data.tables.TrackPointsColumns; import de.dennisguse.opentracks.data.tables.TracksColumns; -import de.dennisguse.opentracks.stats.SensorStatistics; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.SensorStatistics; +import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.ui.markers.MarkerUtils; import de.dennisguse.opentracks.util.FileUtils; @@ -314,7 +315,7 @@ public class ContentProviderUtils { private ContentValues createContentValues(Track track) { ContentValues values = new ContentValues(); - SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); + Statistics trackStatistics = track.getStatistics(); if (track.getId() != null) { values.put(TracksColumns._ID, track.getId().id()); @@ -325,30 +326,38 @@ public class ContentProviderUtils { values.put(TracksColumns.ACTIVITY_TYPE, track.getActivityType() != null ? track.getActivityType().getId() : null); values.put(TracksColumns.ACTIVITY_TYPE_LOCALIZED, track.getActivityTypeLocalized()); values.put(TracksColumns.STARTTIME_OFFSET, track.getZoneOffset().getTotalSeconds()); - if (trackStatistics.getStartTime() != null) { - values.put(TracksColumns.STARTTIME, trackStatistics.getStartTime().toEpochMilli()); + if (trackStatistics.startTime() != null) { + values.put(TracksColumns.STARTTIME, trackStatistics.startTime().toEpochMilli()); } - if (trackStatistics.getStopTime() != null) { - values.put(TracksColumns.STOPTIME, trackStatistics.getStopTime().toEpochMilli()); + if (trackStatistics.stopTime() != null) { + values.put(TracksColumns.STOPTIME, trackStatistics.stopTime().toEpochMilli()); } - values.put(TracksColumns.TOTALDISTANCE, trackStatistics.getTotalDistance().toM()); - values.put(TracksColumns.TOTALTIME, trackStatistics.getTotalTime().toMillis()); - values.put(TracksColumns.MOVINGTIME, trackStatistics.getMovingTime().toMillis()); + values.put(TracksColumns.TOTALDISTANCE, trackStatistics.totalDistance().toM()); + values.put(TracksColumns.TOTALTIME, trackStatistics.totalTime().toMillis()); + values.put(TracksColumns.MOVINGTIME, trackStatistics.movingTime().toMillis()); values.put(TracksColumns.AVGSPEED, trackStatistics.getAverageSpeed().toMPS()); values.put(TracksColumns.AVGMOVINGSPEED, trackStatistics.getAverageMovingSpeed().toMPS()); - values.put(TracksColumns.MAXSPEED, trackStatistics.getMaxSpeed().toMPS()); - values.put(TracksColumns.MIN_ALTITUDE, trackStatistics.getMinAltitude()); - values.put(TracksColumns.MAX_ALTITUDE, trackStatistics.getMaxAltitude()); - values.put(TracksColumns.ALTITUDE_GAIN, trackStatistics.getTotalAltitudeGain()); - values.put(TracksColumns.ALTITUDE_LOSS, trackStatistics.getTotalAltitudeLoss()); + values.put(TracksColumns.MAXSPEED, trackStatistics.maxSpeed().toMPS()); + + if (track.getTrackStatistics().hasAltitudeExtremities()) { + values.put(TracksColumns.MIN_ALTITUDE, trackStatistics.getMinAltitude()); + values.put(TracksColumns.MAX_ALTITUDE, trackStatistics.getMaxAltitude()); + } + + if (trackStatistics.altitudeGainLoss() != null) { + values.put(TracksColumns.ALTITUDE_GAIN, trackStatistics.altitudeGainLoss().gain_m()); + values.put(TracksColumns.ALTITUDE_LOSS, trackStatistics.altitudeGainLoss().loss_m()); + } return values; } + //TODO Use Statistics public void updateTrackStatistics(@NonNull Track.Id trackId, @NonNull SegmentStatisticUpdater trackStatistics) { contentResolver.update(TracksColumns.CONTENT_URI, createContentValues(trackStatistics), TracksColumns._ID + "=?", new String[]{Long.toString(trackId.id())}); } + //TODO Use Statistics private ContentValues createContentValues(SegmentStatisticUpdater trackStatistics) { ContentValues values = new ContentValues(); if (trackStatistics.getStartTime() != null) { diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Speed.java b/src/main/java/de/dennisguse/opentracks/data/models/Speed.java index 1e24ca0cd..f03c3f0f3 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Speed.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Speed.java @@ -26,6 +26,7 @@ public record Speed(double speed_mps) { return of(Distance.ofKilometer(speed_kmh), Duration.ofHours(1)); } + //TODO Like Duration.ZERO public static Speed zero() { return of(0.0); } diff --git a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java index 96fe90427..c9343cdd2 100644 --- a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java +++ b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java @@ -39,7 +39,7 @@ import de.dennisguse.opentracks.databinding.StatisticsRecordedBinding; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.util.StringUtils; /** @@ -171,12 +171,12 @@ public class StatisticsRecordedFragment extends Fragment { } private void updateUI() { - SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); + Statistics trackStatistics = track.getStatistics(); // Set total distance { Pair parts = DistanceFormatter.Builder() .setUnit(unitSystem) - .build(getContext()).getDistanceParts(trackStatistics.getTotalDistance()); + .build(getContext()).getDistanceParts(trackStatistics.totalDistance()); viewBinding.statsDistanceValue.setText(parts.first); viewBinding.statsDistanceUnit.setText(parts.second); @@ -187,8 +187,8 @@ public class StatisticsRecordedFragment extends Fragment { // Set time and start datetime { - viewBinding.statsMovingTimeValue.setText(StringUtils.formatElapsedTime(trackStatistics.getMovingTime())); - viewBinding.statsTotalTimeValue.setText(StringUtils.formatElapsedTime(trackStatistics.getTotalTime())); + viewBinding.statsMovingTimeValue.setText(StringUtils.formatElapsedTime(trackStatistics.movingTime())); + viewBinding.statsTotalTimeValue.setText(StringUtils.formatElapsedTime(trackStatistics.totalTime())); } SpeedFormatter formatter = SpeedFormatter.Builder().setUnit(unitSystem).setReportSpeedOrPace(preferenceReportSpeed).build(getContext()); @@ -205,7 +205,7 @@ public class StatisticsRecordedFragment extends Fragment { { viewBinding.statsMaxSpeedLabel.setText(preferenceReportSpeed ? R.string.stats_max_speed : R.string.stats_fastest_pace); - Pair parts = formatter.getSpeedParts(trackStatistics.getMaxSpeed()); + Pair parts = formatter.getSpeedParts(trackStatistics.maxSpeed()); viewBinding.statsMaxSpeedValue.setText(parts.first); viewBinding.statsMaxSpeedUnit.setText(parts.second); } @@ -221,8 +221,8 @@ public class StatisticsRecordedFragment extends Fragment { // Set altitude gain and loss { - Float altitudeGain_m = trackStatistics.getTotalAltitudeGain(); - Float altitudeLoss_m = trackStatistics.getTotalAltitudeLoss(); + Float altitudeGain_m = trackStatistics.altitudeGainLoss() != null ? trackStatistics.altitudeGainLoss().gain_m() : null; + Float altitudeLoss_m = trackStatistics.altitudeGainLoss() != null ? trackStatistics.altitudeGainLoss().loss_m() : null; Pair parts; diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java index e95c4dbdc..a805b3f09 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java @@ -39,7 +39,7 @@ import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.util.StringUtils; /** @@ -279,18 +279,16 @@ public class GPXTrackExporter implements TrackExporter { printWriter.println("" + StringUtils.formatCData(track.getActivityTypeLocalized()) + ""); } - SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); + Statistics trackStatistics = track.getStatistics(); printWriter.println(""); - printWriter.println("" + trackStatistics.getTotalDistance().toM() + ""); - printWriter.println("" + trackStatistics.getTotalTime().getSeconds() + ""); - printWriter.println("" + trackStatistics.getMovingTime().getSeconds() + ""); + printWriter.println("" + trackStatistics.totalDistance().toM() + ""); + printWriter.println("" + trackStatistics.totalTime().getSeconds() + ""); + printWriter.println("" + trackStatistics.movingTime().getSeconds() + ""); printWriter.println("" + trackStatistics.getStoppedTime().getSeconds() + ""); - printWriter.println("" + trackStatistics.getMaxSpeed().toMPS() + ""); - if (trackStatistics.hasTotalAltitudeGain()) { - printWriter.println("" + trackStatistics.getTotalAltitudeGain() + ""); - } - if (trackStatistics.hasTotalAltitudeLoss()) { - printWriter.println("" + trackStatistics.getTotalAltitudeLoss() + ""); + printWriter.println("" + trackStatistics.maxSpeed().toMPS() + ""); + if (trackStatistics.altitudeGainLoss() != null) { + printWriter.println("" + trackStatistics.altitudeGainLoss().gain_m() + ""); + printWriter.println("" + trackStatistics.altitudeGainLoss().loss_m() + ""); } printWriter.println(""); diff --git a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java index 49383afe5..5b94986df 100644 --- a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java +++ b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java @@ -20,12 +20,13 @@ public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorData return track.getActivityTypeLocalized(); } + @Deprecated @NonNull - public SegmentStatisticUpdater getStatisticsTrack() { + public Statistics getStatisticsTrack() { if (track == null) { - return new SegmentStatisticUpdater(); + return new SegmentStatisticUpdater().getStatistics(); } - return track.getTrackStatistics(); + return track.getTrackStatistics().getStatistics(); } } diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java index 87ab306e4..2f085a27e 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java @@ -124,7 +124,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen ALTITUDE_CORRECTION_MANAGER.correctAltitude(context, current.first); - Track track = contentProviderUtils.getTrack(trackId); //Get copy + Track track = contentProviderUtils.getTrack(trackId); //Get copy TODO: Avoid re-loading data from DB if (track == null) { Log.w(TAG, "Requesting data if not recording is taking place, should not be done."); return null; diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java index 3a04ae1aa..a6f1e97d6 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java @@ -194,7 +194,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator. startSensors(); - voiceAnnouncementManager.start(trackRecordingManager.getTrackStatistics()); + voiceAnnouncementManager.start(trackRecordingManager.getTrackStatistics().getStatistics()); notificationManager.onRecordingStarted(this, recordingStatus.trackId()); } diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java index 37bc03217..7e085a70a 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java @@ -118,7 +118,7 @@ class TrackRecordingServiceNotificationManager implements SharedPreferences.OnSh previousLocationWasAccurate = currentLocationWasAccurate; } - notificationBuilder.setContentTitle(context.getString(R.string.track_distance_notification, formatter.formatDistance(recordingData.getStatisticsTrack().getTotalDistance()))); + notificationBuilder.setContentTitle(context.getString(R.string.track_distance_notification, formatter.formatDistance(recordingData.getStatisticsTrack().totalDistance()))); String formattedSpeed = SpeedFormatter.Builder().setUnit(unitSystem).setReportSpeedOrPace(true).build(context).formatSpeed(recordingData.latestTrackPoint().getSpeed()); notificationBuilder.setContentText(context.getString(R.string.track_speed_notification, formattedSpeed)); notificationBuilder.setSubText(context.getString(R.string.track_recording_notification_accuracy, formattedAccuracy)); diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java index 6a6e363b0..5d4147e6d 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java @@ -37,7 +37,7 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; /** @@ -53,7 +53,7 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe private TTSManager voiceAnnouncement; - private SegmentStatisticUpdater trackStatistics; + private Statistics trackStatistics; private static final Distance DISTANCE_OFF = Distance.of(Double.MAX_VALUE); private Distance distanceFrequency = DISTANCE_OFF; @@ -79,13 +79,13 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe intervalStatistics = new IntervalStatistics(intervalDistance); } - public void start(@Nullable SegmentStatisticUpdater trackStatistics) { + public void start(@Nullable Statistics trackStatistics) { voiceAnnouncement = new TTSManager(context); voiceAnnouncement.start(); update(trackStatistics); } - void update(@Nullable SegmentStatisticUpdater trackStatistics) { + void update(@Nullable Statistics trackStatistics) { this.trackStatistics = trackStatistics; updateNextDuration(); updateNextTaskDistance(); @@ -126,12 +126,12 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe } boolean announce = false; - this.trackStatistics = track.getTrackStatistics(); - if (trackStatistics.getTotalDistance().greaterThan(nextTotalDistance)) { + this.trackStatistics = track.getStatistics(); + if (trackStatistics.totalDistance().greaterThan(nextTotalDistance)) { updateNextTaskDistance(); announce = true; } - if (!trackStatistics.getTotalTime().minus(nextTotalTime).isNegative()) { + if (!trackStatistics.totalTime().minus(nextTotalTime).isNegative()) { updateNextDuration(); announce = true; } @@ -182,7 +182,7 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe nextTotalDistance = DISTANCE_OFF; } else { - Distance distance = trackStatistics.getTotalDistance(); + Distance distance = trackStatistics.totalDistance(); int index = (int) (distance.dividedBy(distanceFrequency)); nextTotalDistance = distanceFrequency.multipliedBy(index + 1); @@ -195,10 +195,9 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe nextTotalTime = TOTALTIME_OFF; } else { - Duration totalTime = trackStatistics.getTotalTime(); - Duration intervalMod = Duration.ofMillis(trackStatistics.getTotalTime().toMillis() % totalTimeFrequency.toMillis()); + Duration intervalMod = Duration.ofMillis(trackStatistics.totalTime().toMillis() % totalTimeFrequency.toMillis()); - nextTotalTime = totalTime.plus(totalTimeFrequency.minus(intervalMod)); + nextTotalTime = trackStatistics.totalTime().plus(totalTimeFrequency.minus(intervalMod)); } } diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java index 03ab3fb5c..f201824b6 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java @@ -37,7 +37,7 @@ import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; import de.dennisguse.opentracks.util.StringUtils; @@ -52,7 +52,7 @@ class VoiceAnnouncementUtils { } static Spannable createStatistics(Context context, Track track, SensorDataSet sensorDataSet, UnitSystem unitSystem, boolean isReportSpeed, @Nullable IntervalStatistics.Interval currentInterval, @Nullable SensorStatistics sensorStatistics) { - SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); + Statistics trackStatistics = track.getStatistics(); SpannableStringBuilder builder = new SpannableStringBuilder(); @@ -60,7 +60,7 @@ class VoiceAnnouncementUtils { appendTime(builder, track.getStopTime()); } - Distance totalDistance = trackStatistics.getTotalDistance(); + Distance totalDistance = trackStatistics.totalDistance(); Speed averageMovingSpeed = trackStatistics.getAverageMovingSpeed(); Speed currentDistancePerTime = currentInterval != null ? currentInterval.getSpeed() : null; @@ -112,7 +112,7 @@ class VoiceAnnouncementUtils { boolean hasTravelledDistance = !totalDistance.isZero(); // Announce time - Duration movingTime = trackStatistics.getMovingTime(); + Duration movingTime = trackStatistics.movingTime(); if (shouldVoiceAnnounceMovingTime() && hasTravelledDistance && !movingTime.isZero()) { appendDuration(context, builder, movingTime); builder.append("."); diff --git a/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java b/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java index 071f23fff..42ebaeaab 100644 --- a/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java +++ b/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java @@ -31,7 +31,7 @@ import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.SpeedFormatter; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.util.StringUtils; /** @@ -65,7 +65,7 @@ public class TrackShareSummaryGenerator { writeString(track.getName(), builder, R.string.generic_name_line); writeString(track.getActivityTypeLocalized(), builder, R.string.description_activity_type); writeString(track.getDescription(), builder, R.string.generic_description_line); - builder.append(generateTrackStatisticsDescription(track.getTrackStatistics())); + builder.append(generateTrackStatisticsDescription(track.getStatistics())); return builder.toString(); } @@ -78,17 +78,17 @@ public class TrackShareSummaryGenerator { builder.append(TrackShareSummaryGenerator.TEXT_LINE_BREAK); } - private String generateTrackStatisticsDescription(SegmentStatisticUpdater stats) { + private String generateTrackStatisticsDescription(Statistics stats) { StringBuilder builder = new StringBuilder(); // Total distance - writeDistance(stats.getTotalDistance(), builder, R.string.description_total_distance); + writeDistance(stats.totalDistance(), builder, R.string.description_total_distance); // Total time - writeTime(stats.getTotalTime(), builder, R.string.description_total_time); + writeTime(stats.totalTime(), builder, R.string.description_total_time); // Moving time - writeTime(stats.getMovingTime(), builder, R.string.description_moving_time); + writeTime(stats.movingTime(), builder, R.string.description_moving_time); // Average speed writeSpeed(stats.getAverageSpeed(), builder, R.string.description_average_speed); @@ -97,7 +97,7 @@ public class TrackShareSummaryGenerator { writeSpeed(stats.getAverageMovingSpeed(), builder, R.string.description_average_moving_speed); // Max speed - writeSpeed(stats.getMaxSpeed(), builder, R.string.description_max_speed); + writeSpeed(stats.maxSpeed(), builder, R.string.description_max_speed); // Average pace writePace(stats.getAverageSpeed(), builder, R.string.description_average_pace_in_minute); @@ -106,26 +106,22 @@ public class TrackShareSummaryGenerator { writePace(stats.getAverageMovingSpeed(), builder, R.string.description_average_moving_pace_in_minute); // Fastest pace - writePace(stats.getMaxSpeed(), builder, R.string.description_fastest_pace_in_minute); + writePace(stats.maxSpeed(), builder, R.string.description_fastest_pace_in_minute); // Min and Max altitude - if (stats.hasAltitudeExtremities()) { - writeAltitude(stats.getMaxAltitude(), builder, R.string.description_max_altitude); - writeAltitude(stats.getMinAltitude(), builder, R.string.description_min_altitude); + if (stats.altitudeMax_m() != null & stats.altitudeMin_m() != null) { + writeAltitude(stats.altitudeMax_m(), builder, R.string.description_max_altitude); + writeAltitude(stats.altitudeMin_m(), builder, R.string.description_min_altitude); } - // Altitude gain - if (stats.hasTotalAltitudeGain()) { - writeAltitude(stats.getTotalAltitudeGain(), builder, R.string.description_altitude_gain); - } - - // Altitude loss - if (stats.hasTotalAltitudeLoss()) { - writeAltitude(stats.getTotalAltitudeLoss(), builder, R.string.description_altitude_loss); + // Altitude gain & loss + if (stats.altitudeGainLoss() != null) { + writeAltitude(stats.altitudeGainLoss().gain_m(), builder, R.string.description_altitude_gain); + writeAltitude(stats.altitudeGainLoss().loss_m(), builder, R.string.description_altitude_loss); } // Recorded time - builder.append(context.getString(R.string.description_recorded_time, StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(stats.getStartTime(), ZoneId.systemDefault())))); + builder.append(context.getString(R.string.description_recorded_time, StringUtils.formatDateTimeWithOffset(OffsetDateTime.ofInstant(stats.startTime(), ZoneId.systemDefault())))); builder.append(TEXT_LINE_BREAK); return builder.toString(); diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 9fb1ef587..519353f97 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -89,6 +89,7 @@ public class SegmentStatisticUpdater { isIdle = other.isIdle; } + @Deprecated //TODO Remove @VisibleForTesting public SegmentStatisticUpdater(String startTime, String stopTime, double totalDistance_m, int totalTime_s, int movingTime_s, float maxSpeed_mps, Float totalAltitudeGain_m, Float totalAltitudeLoss_m) { this.startTime = Instant.parse(startTime); @@ -286,10 +287,6 @@ public class SegmentStatisticUpdater { movingTime = movingTime.plus(time); } - public Duration getStoppedTime() { - return totalTime.minus(movingTime); - } - public boolean isIdle() { return isIdle; } @@ -423,6 +420,7 @@ public class SegmentStatisticUpdater { totalAltitudeLoss_m += loss_m; } + @Deprecated //TODO Remove as it should (a) not be necessary and (b) toString is not complete? @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/src/main/java/de/dennisguse/opentracks/stats/Statistics.java b/src/main/java/de/dennisguse/opentracks/stats/Statistics.java index b27ddd716..4fa841dff 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/Statistics.java +++ b/src/main/java/de/dennisguse/opentracks/stats/Statistics.java @@ -37,7 +37,32 @@ public record Statistics( Power avgPower ) { + public Duration getStoppedTime() { + return totalTime.minus(movingTime); + } + + public Speed getAverageSpeed() { + if (totalTime.isZero()) { + return Speed.of(0); + } + return Speed.of(totalDistance, totalTime); + } + public Speed getAverageMovingSpeed() { return Speed.of(totalDistance, movingTime); } + + @Deprecated + //TODO null should be return (need adjusting ContentPtoviderUtils.createContentValues() + public double getMinAltitude() { + if (altitudeMin_m == null) return 0; + return altitudeMin_m; + } + + @Deprecated + //TODO null should be return (need adjusting ContentPtoviderUtils.createContentValues() + public double getMaxAltitude() { + if (altitudeMax_m == null) return 0; + return altitudeMax_m; + } } diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index f1b075b53..8551087bf 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -72,6 +72,7 @@ public class TrackStatisticsUpdater { resetAverageHeartRate(); } + //TODO Return Statistic? public SegmentStatisticUpdater getTrackStatistics() { // Take a snapshot - we don't want anyone messing with our trackStatistics SegmentStatisticUpdater stats = new SegmentStatisticUpdater(segmentStatisticUpdater); diff --git a/src/main/java/de/dennisguse/opentracks/viewmodels/GenericStatisticsViewHolder.java b/src/main/java/de/dennisguse/opentracks/viewmodels/GenericStatisticsViewHolder.java index f4159e0c4..ffea4bbf7 100644 --- a/src/main/java/de/dennisguse/opentracks/viewmodels/GenericStatisticsViewHolder.java +++ b/src/main/java/de/dennisguse/opentracks/viewmodels/GenericStatisticsViewHolder.java @@ -34,7 +34,7 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder valueAndUnit = DistanceFormatter.Builder() .setUnit(unitSystem) - .build(getContext()).getDistanceParts(data.getStatisticsTrack().getTotalDistance()); + .build(getContext()).getDistanceParts(data.getStatisticsTrack().totalDistance()); getBinding().statsValue.setText(valueAndUnit.first); getBinding().statsUnit.setText(valueAndUnit.second); @@ -46,7 +46,7 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder valueAndUnit = new Pair<>(StringUtils.formatElapsedTime(data.getStatisticsTrack().getTotalTime()), null); + Pair valueAndUnit = new Pair<>(StringUtils.formatElapsedTime(data.getStatisticsTrack().totalTime()), null); getBinding().statsValue.setText(valueAndUnit.first); getBinding().statsUnit.setText(valueAndUnit.second); @@ -58,7 +58,7 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder valueAndUnit = speedFormatterSpeed.getSpeedParts(data.getStatisticsTrack().getMaxSpeed()); + Pair valueAndUnit = speedFormatterSpeed.getSpeedParts(data.getStatisticsTrack().maxSpeed()); getBinding().statsValue.setText(valueAndUnit.first); getBinding().statsUnit.setText(valueAndUnit.second); @@ -236,7 +236,7 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder valueAndUnit = speedFormatterSpeed.getSpeedParts(data.getStatisticsTrack().getMaxSpeed()); + Pair valueAndUnit = speedFormatterSpeed.getSpeedParts(data.getStatisticsTrack().maxSpeed()); getBinding().statsValue.setText(valueAndUnit.first); getBinding().statsUnit.setText(valueAndUnit.second); @@ -264,8 +264,9 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder valueAndUnit = StringUtils.getAltitudeParts(getContext(), data.getStatisticsTrack().getTotalAltitudeGain(), unitSystem); + Pair valueAndUnit = StringUtils.getAltitudeParts(getContext(), gain, unitSystem); getBinding().statsValue.setText(valueAndUnit.first); getBinding().statsUnit.setText(valueAndUnit.second); @@ -277,8 +278,9 @@ public abstract class GenericStatisticsViewHolder extends StatisticViewHolder valueAndUnit = StringUtils.getAltitudeParts(getContext(), data.getStatisticsTrack().getTotalAltitudeLoss(), unitSystem); + Pair valueAndUnit = StringUtils.getAltitudeParts(getContext(), loss, unitSystem); getBinding().statsValue.setText(valueAndUnit.first); getBinding().statsUnit.setText(valueAndUnit.second); From 5dd56892fb2e23eda2d8df5eda44e975efe988f0 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Mon, 27 Oct 2025 22:19:10 +0100 Subject: [PATCH 04/30] Cleanup: move Statistics to package models. --- .../opentracks/io/file/importer/ExportImportTest.java | 2 +- .../opentracks/io/file/importer/GPXTrackImporterTest.java | 2 +- .../TrackRecordingServiceNotificationManagerTest.java | 2 +- .../dennisguse/opentracks/data/ContentProviderUtils.java | 2 +- .../opentracks/{stats => data/models}/Statistics.java | 8 +------- .../java/de/dennisguse/opentracks/data/models/Track.java | 1 - .../opentracks/fragments/StatisticsRecordedFragment.java | 2 +- .../opentracks/io/file/exporter/GPXTrackExporter.java | 2 +- .../de/dennisguse/opentracks/services/RecordingData.java | 2 +- .../services/announcement/VoiceAnnouncementManager.java | 2 +- .../services/announcement/VoiceAnnouncementUtils.java | 2 +- .../opentracks/share/TrackShareSummaryGenerator.java | 2 +- .../opentracks/stats/SegmentStatisticUpdater.java | 1 + .../opentracks/stats/TrackStatisticsUpdater.java | 1 + .../SettingsCustomLayoutEditAdapter.java | 2 +- 15 files changed, 14 insertions(+), 19 deletions(-) rename src/main/java/de/dennisguse/opentracks/{stats => data/models}/Statistics.java (83%) 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 11231b5f0..6c4ce1010 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 @@ -60,6 +60,7 @@ import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.io.file.TrackFileFormat; @@ -75,7 +76,6 @@ import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; -import de.dennisguse.opentracks.stats.Statistics; /** * Export a track to {@link TrackFileFormat} and verify that the import is identical. diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java index 05dac22bb..8cbb7025c 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java @@ -30,11 +30,11 @@ import de.dennisguse.opentracks.data.models.Altitude; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.io.file.TrackFileFormat; import de.dennisguse.opentracks.io.file.exporter.TrackExporter; -import de.dennisguse.opentracks.stats.Statistics; /** * Test that legacy KML/GPX formats can still be imported. diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java index 05b4a7d3d..450f4c53a 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java @@ -18,11 +18,11 @@ import org.mockito.junit.MockitoJUnitRunner; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; -import de.dennisguse.opentracks.stats.Statistics; @RunWith(MockitoJUnitRunner.class) public class TrackRecordingServiceNotificationManagerTest { diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index 7e7c87130..cae09abbb 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -48,6 +48,7 @@ import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.data.tables.MarkerColumns; @@ -55,7 +56,6 @@ import de.dennisguse.opentracks.data.tables.TrackPointsColumns; import de.dennisguse.opentracks.data.tables.TracksColumns; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.ui.markers.MarkerUtils; import de.dennisguse.opentracks.util.FileUtils; diff --git a/src/main/java/de/dennisguse/opentracks/stats/Statistics.java b/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java similarity index 83% rename from src/main/java/de/dennisguse/opentracks/stats/Statistics.java rename to src/main/java/de/dennisguse/opentracks/data/models/Statistics.java index 4fa841dff..1b284f4a3 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/Statistics.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java @@ -1,16 +1,10 @@ -package de.dennisguse.opentracks.stats; +package de.dennisguse.opentracks.data.models; import androidx.annotation.Nullable; import java.time.Duration; import java.time.Instant; -import de.dennisguse.opentracks.data.models.AltitudeGainLoss; -import de.dennisguse.opentracks.data.models.Distance; -import de.dennisguse.opentracks.data.models.HeartRate; -import de.dennisguse.opentracks.data.models.Power; -import de.dennisguse.opentracks.data.models.Speed; - public record Statistics( Instant startTime, Instant stopTime, diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Track.java b/src/main/java/de/dennisguse/opentracks/data/models/Track.java index 7057762bb..5ee9fb646 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Track.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Track.java @@ -30,7 +30,6 @@ import java.util.Objects; import java.util.UUID; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; -import de.dennisguse.opentracks.stats.Statistics; /** * A track. diff --git a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java index c9343cdd2..6ecc48678 100644 --- a/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java +++ b/src/main/java/de/dennisguse/opentracks/fragments/StatisticsRecordedFragment.java @@ -34,12 +34,12 @@ import de.dennisguse.opentracks.TrackRecordedActivity; import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.models.DistanceFormatter; import de.dennisguse.opentracks.data.models.SpeedFormatter; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.databinding.StatisticsRecordedBinding; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.util.StringUtils; /** diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java index a805b3f09..9df2a08a0 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java @@ -37,9 +37,9 @@ import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Position; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; -import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.util.StringUtils; /** diff --git a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java index 5b94986df..f132823d7 100644 --- a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java +++ b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java @@ -2,11 +2,11 @@ package de.dennisguse.opentracks.services; import androidx.annotation.NonNull; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; -import de.dennisguse.opentracks.stats.Statistics; /** * {@link Track} and {@link TrackPoint} must be immutable (i.e., their content does not change). diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java index 5d4147e6d..0382bdee5 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java @@ -32,12 +32,12 @@ import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; /** diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java index f201824b6..7cb22c33b 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java @@ -33,11 +33,11 @@ import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; import de.dennisguse.opentracks.util.StringUtils; diff --git a/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java b/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java index 42ebaeaab..1699cac82 100644 --- a/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java +++ b/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java @@ -29,9 +29,9 @@ import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.SpeedFormatter; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.util.StringUtils; /** diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 519353f97..6af611081 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -29,6 +29,7 @@ import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index 8551087bf..de68b9d41 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -25,6 +25,7 @@ import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.PreferencesUtils; diff --git a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java index 438d0b4f0..138c866bb 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java +++ b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java @@ -23,12 +23,12 @@ import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.databinding.CustomStatsItemBinding; import de.dennisguse.opentracks.services.RecordingData; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.Statistics; import de.dennisguse.opentracks.viewmodels.Mapping; import de.dennisguse.opentracks.viewmodels.StatisticViewHolder; From 4580f2a7bbaa5e0046140a1c7bb11932162c54f1 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Mon, 27 Oct 2025 22:40:50 +0100 Subject: [PATCH 05/30] ContentProviderUtils use Statistics for saving. --- .../opentracks/data/ContentProviderUtils.java | 28 ++++++++-------- .../opentracks/services/RecordingData.java | 2 +- .../services/TrackRecordingManager.java | 2 +- .../opentracks/stats/ExtremityMonitor.java | 9 +++--- .../stats/SegmentStatisticUpdater.java | 32 +++++++++++-------- 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index cae09abbb..c5aba8275 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -352,30 +352,30 @@ public class ContentProviderUtils { return values; } - //TODO Use Statistics - public void updateTrackStatistics(@NonNull Track.Id trackId, @NonNull SegmentStatisticUpdater trackStatistics) { + public void updateTrackStatistics(@NonNull Track.Id trackId, @NonNull Statistics trackStatistics) { contentResolver.update(TracksColumns.CONTENT_URI, createContentValues(trackStatistics), TracksColumns._ID + "=?", new String[]{Long.toString(trackId.id())}); } - //TODO Use Statistics - private ContentValues createContentValues(SegmentStatisticUpdater trackStatistics) { + private ContentValues createContentValues(Statistics trackStatistics) { ContentValues values = new ContentValues(); - if (trackStatistics.getStartTime() != null) { - values.put(TracksColumns.STARTTIME, trackStatistics.getStartTime().toEpochMilli()); + if (trackStatistics.startTime() != null) { + values.put(TracksColumns.STARTTIME, trackStatistics.startTime().toEpochMilli()); } - if (trackStatistics.getStopTime() != null) { - values.put(TracksColumns.STOPTIME, trackStatistics.getStopTime().toEpochMilli()); + if (trackStatistics.stopTime() != null) { + values.put(TracksColumns.STOPTIME, trackStatistics.stopTime().toEpochMilli()); } - values.put(TracksColumns.TOTALDISTANCE, trackStatistics.getTotalDistance().toM()); - values.put(TracksColumns.TOTALTIME, trackStatistics.getTotalTime().toMillis()); - values.put(TracksColumns.MOVINGTIME, trackStatistics.getMovingTime().toMillis()); + values.put(TracksColumns.TOTALDISTANCE, trackStatistics.totalDistance().toM()); + values.put(TracksColumns.TOTALTIME, trackStatistics.totalTime().toMillis()); + values.put(TracksColumns.MOVINGTIME, trackStatistics.movingTime().toMillis()); values.put(TracksColumns.AVGSPEED, trackStatistics.getAverageSpeed().toMPS()); values.put(TracksColumns.AVGMOVINGSPEED, trackStatistics.getAverageMovingSpeed().toMPS()); - values.put(TracksColumns.MAXSPEED, trackStatistics.getMaxSpeed().toMPS()); + values.put(TracksColumns.MAXSPEED, trackStatistics.maxSpeed().toMPS()); values.put(TracksColumns.MIN_ALTITUDE, trackStatistics.getMinAltitude()); values.put(TracksColumns.MAX_ALTITUDE, trackStatistics.getMaxAltitude()); - values.put(TracksColumns.ALTITUDE_GAIN, trackStatistics.getTotalAltitudeGain()); - values.put(TracksColumns.ALTITUDE_LOSS, trackStatistics.getTotalAltitudeLoss()); + if (trackStatistics.altitudeGainLoss() != null) { + values.put(TracksColumns.ALTITUDE_GAIN, trackStatistics.altitudeGainLoss().gain_m()); + values.put(TracksColumns.ALTITUDE_LOSS, trackStatistics.altitudeGainLoss().loss_m()); + } return values; } diff --git a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java index f132823d7..d3b5e679e 100644 --- a/src/main/java/de/dennisguse/opentracks/services/RecordingData.java +++ b/src/main/java/de/dennisguse/opentracks/services/RecordingData.java @@ -27,6 +27,6 @@ public record RecordingData(Track track, TrackPoint latestTrackPoint, SensorData return new SegmentStatisticUpdater().getStatistics(); } - return track.getTrackStatistics().getStatistics(); + return track.getStatistics(); } } diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java index 2f085a27e..294ab8f10 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java @@ -249,7 +249,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen contentProviderUtils.insertTrackPoint(trackPoint, trackId); trackStatisticsUpdater.addTrackPoint(trackPoint); - contentProviderUtils.updateTrackStatistics(trackId, trackStatisticsUpdater.getTrackStatistics()); + contentProviderUtils.updateTrackStatistics(trackId, trackStatisticsUpdater.getTrackStatistics().getStatistics()); lastStoredTrackPoint = trackPoint; if (trackPoint.hasLocation()) { lastStoredTrackPointWithLocation = lastStoredTrackPoint; diff --git a/src/main/java/de/dennisguse/opentracks/stats/ExtremityMonitor.java b/src/main/java/de/dennisguse/opentracks/stats/ExtremityMonitor.java index eda982ce9..e26c5fd37 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/ExtremityMonitor.java +++ b/src/main/java/de/dennisguse/opentracks/stats/ExtremityMonitor.java @@ -100,14 +100,15 @@ public class ExtremityMonitor { * @param min the minimum value * @param max the maximum value */ - public void set(double min, double max) { + public void set(Double min, Double max) { + if (min == null || max == null) { + reset(); + return; + } this.min = min; this.max = max; } - /** - * Returns true if has data. - */ public boolean hasData() { return min != Double.POSITIVE_INFINITY && max != Double.NEGATIVE_INFINITY; } diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 6af611081..0b394ae9f 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -40,7 +40,6 @@ import de.dennisguse.opentracks.data.models.TrackPoint; * @author Rodrigo Damazio */ //TODO Check that data ranges are valid (not less than zero etc.) -//TODO Should be a Java record public class SegmentStatisticUpdater { // The min and max altitude (meters) seen on this track. @@ -76,18 +75,24 @@ public class SegmentStatisticUpdater { * @param other another statistics data object to copy from */ public SegmentStatisticUpdater(SegmentStatisticUpdater other) { - startTime = other.startTime; - stopTime = other.stopTime; - totalDistance = other.totalDistance; - totalTime = other.totalTime; - movingTime = other.movingTime; - maxSpeed = other.maxSpeed; - altitudeExtremities.set(other.altitudeExtremities.getMin(), other.altitudeExtremities.getMax()); - totalAltitudeGain_m = other.totalAltitudeGain_m; - totalAltitudeLoss_m = other.totalAltitudeLoss_m; - avgHeartRate = other.avgHeartRate; - avgPower = other.avgPower; - isIdle = other.isIdle; + this(other.getStatistics()); + } + + public SegmentStatisticUpdater(Statistics statistics) { + startTime = statistics.startTime(); + stopTime = statistics.stopTime(); + totalDistance = statistics.totalDistance(); + totalTime = statistics.totalTime(); + movingTime = statistics.movingTime(); + maxSpeed = statistics.maxSpeed(); + altitudeExtremities.set(statistics.altitudeMin_m(), statistics.altitudeMax_m()); + if (statistics.altitudeGainLoss() != null) { + totalAltitudeGain_m = statistics.altitudeGainLoss().gain_m(); + totalAltitudeLoss_m = statistics.altitudeGainLoss().loss_m(); + } + avgHeartRate = statistics.avgHeartRate(); + avgPower = statistics.avgPower(); + isIdle = statistics.isIdle(); } @Deprecated //TODO Remove @@ -101,6 +106,7 @@ public class SegmentStatisticUpdater { this.maxSpeed = Speed.of(maxSpeed_mps); this.totalAltitudeGain_m = totalAltitudeGain_m; this.totalAltitudeLoss_m = totalAltitudeLoss_m; + altitudeExtremities.set(0.0, 0.0); } /** From be653b73eefaaae15146990f278078afdc635f6e Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Tue, 28 Oct 2025 08:31:43 +0100 Subject: [PATCH 06/30] Added value object: AltitudeExtremities. --- ...rackRecordingServiceNotificationManagerTest.java | 1 - .../opentracks/data/ContentProviderUtils.java | 2 +- .../opentracks/data/models/AltitudeExtremities.java | 4 ++++ .../opentracks/data/models/Statistics.java | 13 +++++-------- .../share/TrackShareSummaryGenerator.java | 6 +++--- .../opentracks/stats/SegmentStatisticUpdater.java | 12 +++++------- .../SettingsCustomLayoutEditAdapter.java | 1 - 7 files changed, 18 insertions(+), 21 deletions(-) create mode 100644 src/main/java/de/dennisguse/opentracks/data/models/AltitudeExtremities.java diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java index 450f4c53a..97a03e161 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java @@ -57,7 +57,6 @@ public class TrackRecordingServiceNotificationManagerTest { null, null, null, - null, null )); when(notificationCompatBuilder.setOnlyAlertOnce(anyBoolean())) diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index c5aba8275..65601f833 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -339,7 +339,7 @@ public class ContentProviderUtils { values.put(TracksColumns.AVGMOVINGSPEED, trackStatistics.getAverageMovingSpeed().toMPS()); values.put(TracksColumns.MAXSPEED, trackStatistics.maxSpeed().toMPS()); - if (track.getTrackStatistics().hasAltitudeExtremities()) { + if (trackStatistics.altitudeExtremities() != null) { values.put(TracksColumns.MIN_ALTITUDE, trackStatistics.getMinAltitude()); values.put(TracksColumns.MAX_ALTITUDE, trackStatistics.getMaxAltitude()); } diff --git a/src/main/java/de/dennisguse/opentracks/data/models/AltitudeExtremities.java b/src/main/java/de/dennisguse/opentracks/data/models/AltitudeExtremities.java new file mode 100644 index 000000000..605e0a10f --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/data/models/AltitudeExtremities.java @@ -0,0 +1,4 @@ +package de.dennisguse.opentracks.data.models; + +public record AltitudeExtremities(double min_m, double max_m) { +} diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java b/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java index 1b284f4a3..4ca059629 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java @@ -17,11 +17,8 @@ public record Statistics( boolean isIdle, //TODO Check if this is persisted; if not: remove Speed maxSpeed, - //TODO Create record for min/max altitude @Nullable - Double altitudeMin_m, - @Nullable - Double altitudeMax_m, + AltitudeExtremities altitudeExtremities, @Nullable AltitudeGainLoss altitudeGainLoss, @@ -49,14 +46,14 @@ public record Statistics( @Deprecated //TODO null should be return (need adjusting ContentPtoviderUtils.createContentValues() public double getMinAltitude() { - if (altitudeMin_m == null) return 0; - return altitudeMin_m; + if (altitudeExtremities == null) return 0; + return altitudeExtremities.min_m(); } @Deprecated //TODO null should be return (need adjusting ContentPtoviderUtils.createContentValues() public double getMaxAltitude() { - if (altitudeMax_m == null) return 0; - return altitudeMax_m; + if (altitudeExtremities == null) return 0; + return altitudeExtremities.max_m(); } } diff --git a/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java b/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java index 1699cac82..355d28956 100644 --- a/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java +++ b/src/main/java/de/dennisguse/opentracks/share/TrackShareSummaryGenerator.java @@ -109,9 +109,9 @@ public class TrackShareSummaryGenerator { writePace(stats.maxSpeed(), builder, R.string.description_fastest_pace_in_minute); // Min and Max altitude - if (stats.altitudeMax_m() != null & stats.altitudeMin_m() != null) { - writeAltitude(stats.altitudeMax_m(), builder, R.string.description_max_altitude); - writeAltitude(stats.altitudeMin_m(), builder, R.string.description_min_altitude); + if (stats.altitudeExtremities() != null) { + writeAltitude(stats.altitudeExtremities().max_m(), builder, R.string.description_max_altitude); + writeAltitude(stats.altitudeExtremities().min_m(), builder, R.string.description_min_altitude); } // Altitude gain & loss diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 0b394ae9f..1a719131c 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -24,6 +24,7 @@ import java.time.Duration; import java.time.Instant; import de.dennisguse.opentracks.data.models.Altitude; +import de.dennisguse.opentracks.data.models.AltitudeExtremities; import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; @@ -85,7 +86,9 @@ public class SegmentStatisticUpdater { totalTime = statistics.totalTime(); movingTime = statistics.movingTime(); maxSpeed = statistics.maxSpeed(); - altitudeExtremities.set(statistics.altitudeMin_m(), statistics.altitudeMax_m()); + if (statistics.altitudeExtremities() != null) { + altitudeExtremities.set(statistics.altitudeExtremities().min_m(), statistics.altitudeExtremities().max_m()); + } if (statistics.altitudeGainLoss() != null) { totalAltitudeGain_m = statistics.altitudeGainLoss().gain_m(); totalAltitudeLoss_m = statistics.altitudeGainLoss().loss_m(); @@ -217,8 +220,7 @@ public class SegmentStatisticUpdater { totalDistance, isIdle, getMaxSpeed(), - altitudeExtremities.hasData() ? altitudeExtremities.getMin() : null, - altitudeExtremities.hasData() ? altitudeExtremities.getMax() : null, + altitudeExtremities.hasData() ? new AltitudeExtremities(altitudeExtremities.getMin(), altitudeExtremities.getMax()) : null, totalAltitudeGain_m != null && totalAltitudeLoss_m != null ? new AltitudeGainLoss(totalAltitudeGain_m, totalAltitudeLoss_m) : null, avgHeartRate, avgPower @@ -343,10 +345,6 @@ public class SegmentStatisticUpdater { this.maxSpeed = maxSpeed; } - public boolean hasAltitudeExtremities() { - return altitudeExtremities.hasData(); - } - public double getMinAltitude() { return altitudeExtremities.getMin(); } diff --git a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java index 138c866bb..a1a8f66ee 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java +++ b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java @@ -49,7 +49,6 @@ public class SettingsCustomLayoutEditAdapter extends RecyclerView.Adapter Date: Tue, 28 Oct 2025 18:03:30 +0100 Subject: [PATCH 07/30] Create SegmentStatisticUpdater by passing Statistics (1/2). --- .../TrackRecordingServiceRecordingTest.java | 56 +++++++++---------- .../opentracks/data/models/TrackPoint.java | 1 + .../stats/SegmentStatisticUpdater.java | 14 ----- 3 files changed, 28 insertions(+), 43 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java index f08460df1..6be534a51 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java @@ -30,11 +30,13 @@ import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.TestUtil; import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.data.ContentProviderUtils; +import de.dennisguse.opentracks.data.models.AltitudeExtremities; import de.dennisguse.opentracks.data.models.AltitudeGainLoss; 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.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.io.file.importer.TrackPointAssert; @@ -46,7 +48,6 @@ import de.dennisguse.opentracks.sensors.sensorData.AggregatorRunning; import de.dennisguse.opentracks.sensors.sensorData.Raw; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; import de.dennisguse.opentracks.settings.PreferencesUtils; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; /** * Tests insert location. @@ -106,8 +107,8 @@ public class TrackRecordingServiceRecordingTest { // then - assertEquals(new SegmentStatisticUpdater(startTime, startTime, 0, 0, 0, 0, null, null) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(startTime), Duration.ZERO, Duration.ZERO, Distance.of(0), false, Speed.zero(), new AltitudeExtremities(0.0, 0.0), null, null, null) + , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)) @@ -120,8 +121,8 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 0, 1, 1, 0, 0f, 0f) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.zero(), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), @@ -192,7 +193,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, pauseTime, 0, 1, 1, 0, 0f, 0f).getStatistics() + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(pauseTime), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.zero(), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -208,7 +209,7 @@ public class TrackRecordingServiceRecordingTest { service.resumeTrack(trackId); // then - assertEquals(new SegmentStatisticUpdater(startTime, resumeTime, 0, 1, 1, 0, 0f, 0f).getStatistics() + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(resumeTime), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.zero(), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -341,7 +342,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f).getStatistics() + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps1), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -349,7 +350,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.0001, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps2, 11.113178253173828f, 4, 4, 15, 0f, 0f).getStatistics() + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps2), Duration.ofSeconds(4), Duration.ofSeconds(4), Distance.of(11.113178253173828), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -357,17 +358,16 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps3, 45.0002, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps3, 22.226356506347656, 6, 6, 15, 0f, 0f).getStatistics() + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps3), Duration.ofSeconds(6), Duration.ofSeconds(6), Distance.of(22.226356506347656), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); - // when String stopTime = "2020-02-02T02:02:12Z"; trackPointCreator.setClock(stopTime); service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 22.226356506347656, 10, 10, 15, 0f, 0f).getStatistics() + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(22.226356506347656), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -420,22 +420,22 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - SegmentStatisticUpdater gps1Statistics = new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f); - assertEquals(gps1Statistics.getStatistics(), contentProviderUtils.getTrack(trackId).getStatistics()); + Statistics gps1Statistics = new Statistics(Instant.parse(startTime), Instant.parse(gps1), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null); + assertEquals(gps1Statistics, contentProviderUtils.getTrack(trackId).getStatistics()); // when String gps2 = "2020-02-02T02:02:06Z"; TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.00001, 35.0, 1, 15); // then - assertEquals(gps1Statistics.getStatistics(), contentProviderUtils.getTrack(trackId).getStatistics()); + assertEquals(gps1Statistics, contentProviderUtils.getTrack(trackId).getStatistics()); // when String gps3 = "2020-02-02T02:02:08Z"; TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps3, 45.00002, 35.0, 1, 15); // then - assertEquals(gps1Statistics.getStatistics(), contentProviderUtils.getTrack(trackId).getStatistics()); + assertEquals(gps1Statistics, contentProviderUtils.getTrack(trackId).getStatistics()); // when String stopTime = "2020-02-02T02:02:12Z"; @@ -443,7 +443,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 2.222635507583618, 10, 10, 15, 0f, 0f).getStatistics() + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(2.222635507583618), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -548,8 +548,8 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 100, 15); // then - SegmentStatisticUpdater startStatistics = new SegmentStatisticUpdater(startTime, startTime, 0, 0, 0, 0, null, null); - assertEquals(startStatistics, contentProviderUtils.getTrack(trackId).getTrackStatistics()); + Statistics startStatistics = new Statistics(Instant.parse(startTime), Instant.parse(startTime), Duration.ofSeconds(0), Duration.ofSeconds(0), Distance.of(0), false, Speed.of(0), new AltitudeExtremities(0.0, 0.0), null, null, null); + assertEquals(startStatistics, contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -557,7 +557,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.1, 35.0, 100, 15); // then - assertEquals(startStatistics, contentProviderUtils.getTrack(trackId).getTrackStatistics()); + assertEquals(startStatistics, contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -566,9 +566,8 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 0, 10, 10, 0, 0f, 0f) - , contentProviderUtils.getTrack(trackId).getTrackStatistics()); - + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(0), false, Speed.of(0), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + , contentProviderUtils.getTrack(trackId).getStatistics()); // then new TrackPointAssert().assertEquals(List.of( @@ -594,17 +593,16 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps1, 0, 1, 1, 15, 0f, 0f).getStatistics(), - contentProviderUtils.getTrack(trackId).getStatistics()); + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps1), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + , contentProviderUtils.getTrack(trackId).getStatistics()); // when String gps2 = "2020-02-02T02:02:06Z"; TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.1, 35.0, 1, 15); // then - assertEquals(new SegmentStatisticUpdater(startTime, gps2, 11113.275390625, 4, 4, 2778.31884765625f, 0f, 0f).getStatistics(), - contentProviderUtils.getTrack(trackId).getStatistics()); - + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps2), Duration.ofSeconds(4), Duration.ofSeconds(4), Distance.of(11113.275390625), false, Speed.of(2778.31884765625f), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + , contentProviderUtils.getTrack(trackId).getStatistics()); // when String stopTime = "2020-02-02T02:02:12Z"; @@ -612,7 +610,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new SegmentStatisticUpdater(startTime, stopTime, 11113.275390625, 10, 10, 1111.3275390625f, 0f, 0f).getStatistics() + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(4), Duration.ofSeconds(4), Distance.of(11113.275390625), false, Speed.of(1111.3275390625), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); diff --git a/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java b/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java index 393d49176..0536701cd 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java @@ -83,6 +83,7 @@ public class TrackPoint { private HeartRate heartRate = null; private Cadence cadence = null; private Power power = null; + //TODO Use AltitudeGainLoss private Float altitudeGain_m = null; private Float altitudeLoss_m = null; diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 1a719131c..1d5aa5ac4 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -98,20 +98,6 @@ public class SegmentStatisticUpdater { isIdle = statistics.isIdle(); } - @Deprecated //TODO Remove - @VisibleForTesting - public SegmentStatisticUpdater(String startTime, String stopTime, double totalDistance_m, int totalTime_s, int movingTime_s, float maxSpeed_mps, Float totalAltitudeGain_m, Float totalAltitudeLoss_m) { - this.startTime = Instant.parse(startTime); - this.stopTime = Instant.parse(stopTime); - this.totalDistance = Distance.of(totalDistance_m); - this.totalTime = Duration.ofSeconds(totalTime_s); - this.movingTime = Duration.ofSeconds(movingTime_s); - this.maxSpeed = Speed.of(maxSpeed_mps); - this.totalAltitudeGain_m = totalAltitudeGain_m; - this.totalAltitudeLoss_m = totalAltitudeLoss_m; - altitudeExtremities.set(0.0, 0.0); - } - /** * Combines these statistics with those from another object. * This assumes that the time periods covered by each do not intersect. From 0ad32f676c137bb3289479545a897395178ee0b6 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Tue, 28 Oct 2025 18:19:14 +0100 Subject: [PATCH 08/30] Create SegmentStatisticUpdater by passing Statistics (2/2). --- .../io/file/TrackFilenameGenerator2Test.java | 5 +++-- .../io/file/TrackFilenameGeneratorTest.java | 3 ++- .../TrackRecordingServiceRecordingTest.java | 2 +- .../de/dennisguse/opentracks/data/models/Track.java | 5 +++-- .../opentracks/io/file/TrackFilenameGenerator.java | 3 ++- .../aggregatedStatistics/AggregatedStatistics.java | 13 +++++++------ 6 files changed, 18 insertions(+), 13 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator2Test.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator2Test.java index fbc88f67f..9c86f1471 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator2Test.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator2Test.java @@ -9,6 +9,7 @@ import java.util.Collection; import java.util.List; import java.util.UUID; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; //TODO Merge with TrackFilenameGeneratorTest whenever Junit5 gets available. @@ -36,9 +37,9 @@ public class TrackFilenameGenerator2Test { Track track = new Track(); track.setName("Best Track"); track.setUuid(UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6")); - track.getTrackStatistics().setStartTime(Instant.parse("2020-02-02T02:02:02Z")); + track.setStatistics(new Statistics(Instant.parse("2020-02-02T02:02:02Z"), null, null, null, null, false, null, null, null, null, null)); // when - String filename = subject.format(track, TrackFileFormat.GPX); + subject.format(track, TrackFileFormat.GPX); } } \ No newline at end of file diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest.java index d31c874fa..0e014f107 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest.java @@ -17,6 +17,7 @@ import java.util.UUID; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.TimezoneRule; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; @RunWith(Parameterized.class) @@ -50,7 +51,7 @@ public class TrackFilenameGeneratorTest { Track track = new Track(); track.setName("Best Track"); track.setUuid(UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb")); - track.getTrackStatistics().setStartTime(Instant.parse("2020-02-02T02:02:02Z")); + track.setStatistics(new Statistics(Instant.parse("2020-02-02T02:02:02Z"), null, null, null, null, false, null, null, null, null, null)); // when String filename = subject.format(track, TrackFileFormat.GPX); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java index 6be534a51..21ff4fb90 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java @@ -610,7 +610,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(4), Duration.ofSeconds(4), Distance.of(11113.275390625), false, Speed.of(1111.3275390625), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(11113.275390625), false, Speed.of(1111.3275146484375), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Track.java b/src/main/java/de/dennisguse/opentracks/data/models/Track.java index 5ee9fb646..ba9b903aa 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Track.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Track.java @@ -142,8 +142,9 @@ public class Track { return trackStatistics.getStatistics(); } - public Statistics setStatistics() { - throw new RuntimeException("TODO"); + public void setStatistics(Statistics statistics) { + //TODO Implementation is used for refactoring: this.statistics = statistics; + setTrackStatistics(new SegmentStatisticUpdater(statistics)); } @Deprecated diff --git a/src/main/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator.java b/src/main/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator.java index 6f7ae8f65..06bda1c63 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator.java @@ -11,6 +11,7 @@ import java.util.UUID; import java.util.regex.Matcher; import java.util.regex.Pattern; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.util.FileUtils; @@ -91,7 +92,7 @@ public class TrackFilenameGenerator { Track track = new Track(); track.setName("Berlin"); track.setUuid(UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6")); - track.getTrackStatistics().setStartTime(Instant.ofEpochMilli(0)); + track.setStatistics(new Statistics(Instant.MIN, null, null, null, null, false, null, null, null, null, null)); return format(track, TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES); } diff --git a/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatistics.java b/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatistics.java index 40e8bffcb..5a6faa17d 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatistics.java +++ b/src/main/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatistics.java @@ -8,6 +8,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; @@ -35,9 +36,9 @@ public class AggregatedStatistics { public void aggregate(@NonNull Track track) { String activityTypeLocalized = track.getActivityTypeLocalized(); if (dataMap.containsKey(activityTypeLocalized)) { - dataMap.get(activityTypeLocalized).add(track.getTrackStatistics()); + dataMap.get(activityTypeLocalized).add(track.getStatistics()); } else { - dataMap.put(activityTypeLocalized, new AggregatedStatistic(activityTypeLocalized, track.getTrackStatistics())); + dataMap.put(activityTypeLocalized, new AggregatedStatistic(activityTypeLocalized, track.getStatistics())); } } @@ -58,9 +59,9 @@ public class AggregatedStatistics { private final SegmentStatisticUpdater trackStatistics; private int countTracks = 1; - public AggregatedStatistic(String activityTypeLocalized, SegmentStatisticUpdater trackStatistics) { + public AggregatedStatistic(String activityTypeLocalized, Statistics trackStatistics) { this.activityTypeLocalized = activityTypeLocalized; - this.trackStatistics = trackStatistics; + this.trackStatistics = new SegmentStatisticUpdater(trackStatistics); } public String getActivityTypeLocalized() { @@ -75,8 +76,8 @@ public class AggregatedStatistics { return countTracks; } - void add(SegmentStatisticUpdater statistics) { - trackStatistics.merge(statistics); + void add(Statistics statistics) { + trackStatistics.merge(new SegmentStatisticUpdater(statistics)); countTracks++; } } From bc62320b9fa3a1356dad9b37f4b44ef15cc56e39 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Tue, 28 Oct 2025 18:51:26 +0100 Subject: [PATCH 09/30] Track only has Statistics (instead of SegmentStatisticsUpdater). --- .../opentracks/data/ContentProviderUtils.java | 52 +++++++------------ .../opentracks/data/models/Statistics.java | 2 + .../opentracks/data/models/Track.java | 34 ++++++------ .../services/TrackRecordingManager.java | 2 +- .../stats/TrackStatisticsUpdater.java | 7 ++- 5 files changed, 46 insertions(+), 51 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index 65601f833..c7d790ef7 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -41,6 +41,8 @@ import java.util.UUID; import de.dennisguse.opentracks.BuildConfig; import de.dennisguse.opentracks.data.models.ActivityType; import de.dennisguse.opentracks.data.models.Altitude; +import de.dennisguse.opentracks.data.models.AltitudeExtremities; +import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Cadence; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; @@ -54,7 +56,6 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.data.tables.MarkerColumns; import de.dennisguse.opentracks.data.tables.TrackPointsColumns; import de.dennisguse.opentracks.data.tables.TracksColumns; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.SensorStatistics; import de.dennisguse.opentracks.ui.markers.MarkerUtils; import de.dennisguse.opentracks.util.FileUtils; @@ -117,7 +118,6 @@ public class ContentProviderUtils { int altitudeLossIndex = cursor.getColumnIndexOrThrow(TracksColumns.ALTITUDE_LOSS); Track track = new Track(ZoneOffset.ofTotalSeconds(cursor.getInt(startTimeOffsetIndex))); - SegmentStatisticUpdater trackStatistics = track.getTrackStatistics(); if (!cursor.isNull(idIndex)) { track.setId(new Track.Id(cursor.getLong(idIndex))); } @@ -137,37 +137,25 @@ public class ContentProviderUtils { track.setActivityTypeLocalized(cursor.getString(activityTypeLocalizedIndex)); } - if (!cursor.isNull(startTimeIndex)) { - trackStatistics.setStartTime(Instant.ofEpochMilli(cursor.getLong(startTimeIndex))); - } - if (!cursor.isNull(stopTimeIndex)) { - trackStatistics.setStopTime(Instant.ofEpochMilli(cursor.getLong(stopTimeIndex))); - } - if (!cursor.isNull(totalDistanceIndex)) { - trackStatistics.setTotalDistance(Distance.of(cursor.getFloat(totalDistanceIndex))); - } - if (!cursor.isNull(totalTimeIndex)) { - trackStatistics.setTotalTime(Duration.ofMillis(cursor.getLong(totalTimeIndex))); - } - if (!cursor.isNull(movingTimeIndex)) { - trackStatistics.setMovingTime(Duration.ofMillis(cursor.getLong(movingTimeIndex))); - } - if (!cursor.isNull(maxSpeedIndex)) { - trackStatistics.setMaxSpeed(Speed.of(cursor.getFloat(maxSpeedIndex))); - } - if (!cursor.isNull(minAltitudeIndex)) { - trackStatistics.setMinAltitude(cursor.getFloat(minAltitudeIndex)); - } - if (!cursor.isNull(maxAltitudeIndex)) { - trackStatistics.setMaxAltitude(cursor.getFloat(maxAltitudeIndex)); - } - if (!cursor.isNull(altitudeGainIndex)) { - trackStatistics.setTotalAltitudeGain(cursor.getFloat(altitudeGainIndex)); - } - if (!cursor.isNull(altitudeLossIndex)) { - trackStatistics.setTotalAltitudeLoss(cursor.getFloat(altitudeLossIndex)); - } + Statistics trackStatistics = new Statistics( + cursor.isNull(startTimeIndex) ? null : Instant.ofEpochMilli(cursor.getLong(startTimeIndex)), + cursor.isNull(stopTimeIndex) ? null : Instant.ofEpochMilli(cursor.getLong(stopTimeIndex)), + cursor.isNull(totalTimeIndex) ? null : Duration.ofMillis(cursor.getLong(totalTimeIndex)), + cursor.isNull(movingTimeIndex) ? null : Duration.ofMillis(cursor.getLong(movingTimeIndex)), + cursor.isNull(totalDistanceIndex) ? null : Distance.of(cursor.getFloat(totalDistanceIndex)), + + false, + + cursor.isNull(maxSpeedIndex) ? null : Speed.of(cursor.getFloat(maxSpeedIndex)), + cursor.isNull(minAltitudeIndex) || cursor.isNull(maxAltitudeIndex) ? null : new AltitudeExtremities(cursor.getFloat(minAltitudeIndex), cursor.getFloat(maxAltitudeIndex)), + cursor.isNull(altitudeGainIndex) || cursor.isNull(altitudeLossIndex) ? null : new AltitudeGainLoss(cursor.getFloat(altitudeGainIndex), cursor.getFloat(altitudeLossIndex)), + + null, + null + ); + + track.setStatistics(trackStatistics); return track; } diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java b/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java index 4ca059629..9c6c28b70 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java @@ -22,6 +22,8 @@ public record Statistics( @Nullable AltitudeGainLoss altitudeGainLoss, + + //NOTE: The following values are not persisted. @Nullable HeartRate avgHeartRate, @Nullable diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Track.java b/src/main/java/de/dennisguse/opentracks/data/models/Track.java index ba9b903aa..c5aaf2bbc 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Track.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Track.java @@ -49,18 +49,25 @@ public class Track { private ActivityType activityType; + //TODO Move to Statistics? private ZoneOffset zoneOffset; - @Deprecated // TODO Replace with Statistic - private SegmentStatisticUpdater trackStatistics = new SegmentStatisticUpdater(); + @NonNull + private Statistics trackStatistics; @VisibleForTesting public Track() { this(ZoneOffset.UTC); } + @Deprecated //TODO Remove public Track(@NonNull ZoneOffset zoneOffset) { - setZoneOffset(zoneOffset); + this(zoneOffset, new SegmentStatisticUpdater().getStatistics()); + } + + public Track(@NonNull ZoneOffset zoneOffset, @NonNull Statistics trackStatistics) { + this.zoneOffset = zoneOffset; + this.trackStatistics = trackStatistics; } /** @@ -130,32 +137,25 @@ public class Track { public OffsetDateTime getStartTime() { return trackStatistics - .getStartTime().atOffset(zoneOffset); + .startTime().atOffset(zoneOffset); } public OffsetDateTime getStopTime() { return trackStatistics - .getStopTime().atOffset(zoneOffset); + .stopTime().atOffset(zoneOffset); } public Statistics getStatistics() { - return trackStatistics.getStatistics(); - } - - public void setStatistics(Statistics statistics) { - //TODO Implementation is used for refactoring: this.statistics = statistics; - setTrackStatistics(new SegmentStatisticUpdater(statistics)); - } - - @Deprecated - @NonNull - public SegmentStatisticUpdater getTrackStatistics() { return trackStatistics; } + public void setStatistics(Statistics trackStatistics) { + this.trackStatistics = trackStatistics; + } + @Deprecated public void setTrackStatistics(@NonNull SegmentStatisticUpdater trackStatistics) { - this.trackStatistics = trackStatistics; + setStatistics(trackStatistics.getStatistics()); } @NonNull diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java index 294ab8f10..5df36b6b4 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java @@ -98,7 +98,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen return false; } - trackStatisticsUpdater = new TrackStatisticsUpdater(track.getTrackStatistics()); + trackStatisticsUpdater = new TrackStatisticsUpdater(track.getStatistics()); onNewTrackPoint(trackPointCreator.createSegmentStartManual()); reset(); diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index de68b9d41..c1e93c328 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -58,7 +58,12 @@ public class TrackStatisticsUpdater { this(new SegmentStatisticUpdater()); } - public TrackStatisticsUpdater(SegmentStatisticUpdater segmentStatisticUpdater) { + public TrackStatisticsUpdater(Statistics statistics) { + this(new SegmentStatisticUpdater(statistics)); + } + + @Deprecated + private TrackStatisticsUpdater(SegmentStatisticUpdater segmentStatisticUpdater) { this.segmentStatisticUpdater = segmentStatisticUpdater; this.currentSegment = new SegmentStatisticUpdater(); From c227d54f261897bd110fdea2b202718b5c1d6de5 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Tue, 28 Oct 2025 21:53:21 +0100 Subject: [PATCH 10/30] Cleanup: SegmentStatisticUpdater and Track do not need equal(). --- .../opentracks/data/models/Track.java | 17 ----------------- .../stats/SegmentStatisticUpdater.java | 9 --------- 2 files changed, 26 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Track.java b/src/main/java/de/dennisguse/opentracks/data/models/Track.java index c5aaf2bbc..b23bb559c 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Track.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Track.java @@ -26,7 +26,6 @@ import androidx.annotation.VisibleForTesting; import java.time.OffsetDateTime; import java.time.ZoneOffset; -import java.util.Objects; import java.util.UUID; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; @@ -169,22 +168,6 @@ public class Track { '}'; } - @Deprecated //TODO Remove: should not be used. - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; - Track track = (Track) o; - return id.equals(track.id); - } - - @Deprecated //TODO Remove: should not be used. - @Override - public int hashCode() { - return Objects.hash(id); - } - - public record Id(long id) implements Parcelable { @Override diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 1d5aa5ac4..a137b3617 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -411,15 +411,6 @@ public class SegmentStatisticUpdater { totalAltitudeLoss_m += loss_m; } - @Deprecated //TODO Remove as it should (a) not be necessary and (b) toString is not complete? - @Override - public boolean equals(Object o) { - if (this == o) return true; - if (!(o instanceof SegmentStatisticUpdater)) return false; - - return toString().equals(o.toString()); - } - @NonNull @Override public String toString() { From 005d00cfaa7a77b1855d1fbbdf45e39ceb142d3a Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Tue, 28 Oct 2025 22:00:31 +0100 Subject: [PATCH 11/30] Cleanup: SegmentStatisticUpdaterTest. --- ...atisticsTest.java => SegmentStatisticUpdaterTest.java} | 2 +- .../opentracks/stats/SegmentStatisticUpdater.java | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) rename src/androidTest/java/de/dennisguse/opentracks/stats/{TrackStatisticsTest.java => SegmentStatisticUpdaterTest.java} (99%) diff --git a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsTest.java b/src/androidTest/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdaterTest.java similarity index 99% rename from src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsTest.java rename to src/androidTest/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdaterTest.java index fc7708caa..2719051e7 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdaterTest.java @@ -38,7 +38,7 @@ import de.dennisguse.opentracks.data.models.Speed; * @author Rodrigo Damazio */ @RunWith(AndroidJUnit4.class) -public class TrackStatisticsTest { +public class SegmentStatisticUpdaterTest { private SegmentStatisticUpdater statistics; diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index a137b3617..ba96d0c5a 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -290,19 +290,11 @@ public class SegmentStatisticUpdater { isIdle = idle; } - public boolean hasAverageHeartRate() { - return avgHeartRate != null; - } - @Nullable public HeartRate getAverageHeartRate() { return avgHeartRate; } - public boolean hasPower() { - return avgPower != null; - } - @Nullable public Power getAveragePower() { return avgPower; From caf3d957cdb760e903dfe741cb71ff1353d8a736 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Tue, 28 Oct 2025 22:41:11 +0100 Subject: [PATCH 12/30] Cleanup: SegmentStatisticUpdaterTest uses Statistic. --- .../stats/SegmentStatisticUpdater.java | 31 ++++++++----------- 1 file changed, 13 insertions(+), 18 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index ba96d0c5a..6ddeb9fee 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -52,7 +52,11 @@ public class SegmentStatisticUpdater { private Instant stopTime; //TODO Should never be null! private Distance totalDistance; - // Updated when new points are received, may be stale. + /** + * Updated when new points are received, may be stale. + * This statistic is only updated when a new point is added to the statistics, so it may be off. + * If you need to calculate the proper totalTime, use startTime with the current time. + */ private Duration totalTime; // Based on when we believe the user is traveling. private Duration movingTime; @@ -181,12 +185,12 @@ public class SegmentStatisticUpdater { startTime = null; stopTime = null; - setTotalDistance(Distance.of(0)); - setTotalTime(Duration.ofSeconds(0)); - setMovingTime(Duration.ofSeconds(0)); - setMaxSpeed(Speed.zero()); - setTotalAltitudeGain(null); - setTotalAltitudeLoss(null); + totalTime = Duration.ofSeconds(0); + movingTime = Duration.ofSeconds(0); + totalDistance = Distance.of(0); + maxSpeed = Speed.zero(); + totalAltitudeGain_m = null; + totalAltitudeLoss_m = null; isIdle = false; } @@ -241,6 +245,7 @@ public class SegmentStatisticUpdater { return totalDistance; } + @VisibleForTesting public void setTotalDistance(Distance totalDistance_m) { this.totalDistance = totalDistance_m; } @@ -249,11 +254,6 @@ public class SegmentStatisticUpdater { totalDistance = totalDistance.plus(distance_m); } - /** - * Gets the total time in milliseconds that this track has been active. - * This statistic is only updated when a new point is added to the statistics, so it may be off. - * If you need to calculate the proper total time, use {@link #getStartTime} with the current time. - */ public Duration getTotalTime() { return totalTime; } @@ -406,11 +406,6 @@ public class SegmentStatisticUpdater { @NonNull @Override public String toString() { - return "TrackStatistics { Start Time: " + getStartTime() + "; Stop Time: " + getStopTime() - + "; Total Distance: " + getTotalDistance() + "; Total Time: " + getTotalTime() - + "; Moving Time: " + getMovingTime() + "; Max Speed: " + getMaxSpeed() - + "; Min Altitude: " + getMinAltitude() + "; Max Altitude: " + getMaxAltitude() - + "; Altitude Gain: " + getTotalAltitudeGain() - + "; Altitude Loss: " + getTotalAltitudeLoss() + "}"; + return "SegmentStatisticUpdater{" + getStatistics() + "}"; } } \ No newline at end of file From 3222a0c4976e72e4538a29464bdf73665eb6e7a6 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Wed, 29 Oct 2025 08:43:30 +0100 Subject: [PATCH 13/30] Rename IntervalStatistics to IntervalStatisticsUpdater. --- .../VoiceAnnouncementUtilsTest.java | 28 +++++++++---------- ...ava => IntervalStatisticsUpdaterTest.java} | 14 +++++----- .../VoiceAnnouncementManager.java | 10 +++---- .../announcement/VoiceAnnouncementUtils.java | 4 +-- .../intervals/IntervalStatisticsAdapter.java | 6 ++-- .../ui/intervals/IntervalStatisticsModel.java | 10 +++---- ...cs.java => IntervalStatisticsUpdater.java} | 4 +-- .../ui/intervals/IntervalsFragment.java | 2 +- 8 files changed, 39 insertions(+), 39 deletions(-) rename src/androidTest/java/de/dennisguse/opentracks/ui/intervals/{IntervalStatisticsTest.java => IntervalStatisticsUpdaterTest.java} (92%) rename src/main/java/de/dennisguse/opentracks/ui/intervals/{IntervalStatistics.java => IntervalStatisticsUpdater.java} (98%) diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java index 7eead65b6..a4b5c8bbe 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java @@ -33,9 +33,9 @@ import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.SensorStatistics; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; -import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; +import de.dennisguse.opentracks.stats.SensorStatistics; +import de.dennisguse.opentracks.ui.intervals.IntervalStatisticsUpdater; @RunWith(AndroidJUnit4.class) public class VoiceAnnouncementUtilsTest { @@ -163,10 +163,10 @@ public class VoiceAnnouncementUtilsTest { Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; - IntervalStatistics.Interval lastInterval; + IntervalStatisticsUpdater.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); - IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000)); + IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } @@ -214,10 +214,10 @@ public class VoiceAnnouncementUtilsTest { Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; - IntervalStatistics.Interval lastInterval; + IntervalStatisticsUpdater.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); - IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000)); + IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } @@ -328,10 +328,10 @@ public class VoiceAnnouncementUtilsTest { Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; - IntervalStatistics.Interval lastInterval; + IntervalStatisticsUpdater.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); - IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000)); + IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } @@ -379,10 +379,10 @@ public class VoiceAnnouncementUtilsTest { Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; - IntervalStatistics.Interval lastInterval; + IntervalStatisticsUpdater.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); - IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000)); + IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } @@ -409,10 +409,10 @@ public class VoiceAnnouncementUtilsTest { Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; - IntervalStatistics.Interval lastInterval; + IntervalStatisticsUpdater.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); - IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000)); + IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } @@ -447,10 +447,10 @@ public class VoiceAnnouncementUtilsTest { Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; - IntervalStatistics.Interval lastInterval; + IntervalStatisticsUpdater.Interval lastInterval; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(numberOfPoints, trackPointIterator.getCount()); - IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(1000)); + IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java similarity index 92% rename from src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsTest.java rename to src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java index 5a263c61c..d9949a823 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java @@ -25,9 +25,9 @@ import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; @RunWith(JUnit4.class) -public class IntervalStatisticsTest { +public class IntervalStatisticsUpdaterTest { - private static final String TAG = IntervalStatisticsTest.class.getSimpleName(); + private static final String TAG = IntervalStatisticsUpdaterTest.class.getSimpleName(); private final Context context = ApplicationProvider.getApplicationContext(); private ContentProviderUtils contentProviderUtils; @@ -148,19 +148,19 @@ public class IntervalStatisticsTest { } private void whenAndThen(Pair trackWithStats, int numberOfPoints, float distanceInterval) { - IntervalStatistics intervalStatistics = new IntervalStatistics(Distance.of(distanceInterval)); + IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(distanceInterval)); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater trackStatistics = trackWithStats.second; try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { assertEquals(trackPointIterator.getCount(), numberOfPoints); intervalStatistics.addTrackPoints(trackPointIterator); } - List intervalList = intervalStatistics.getIntervalList(); + List intervalList = intervalStatistics.getIntervalList(); Distance totalDistance = Distance.of(0); float totalTime = 0L; Float totalGain = null; Float totalLoss = null; - for (IntervalStatistics.Interval i : intervalList) { + for (IntervalStatisticsUpdater.Interval i : intervalList) { totalDistance = totalDistance.plus(i.getDistance()); totalTime += i.getDistance().toM() / i.getSpeed().toMPS(); @@ -184,12 +184,12 @@ public class IntervalStatisticsTest { if (totalGain != null) { assertEquals(totalGain, numberOfPoints * TestDataUtil.ALTITUDE_GAIN, 0.1); } else { - assertTrue(intervalStatistics.getIntervalList().stream().noneMatch(IntervalStatistics.Interval::hasGain)); + assertTrue(intervalStatistics.getIntervalList().stream().noneMatch(IntervalStatisticsUpdater.Interval::hasGain)); } if (totalLoss != null) { assertEquals(totalLoss, numberOfPoints * TestDataUtil.ALTITUDE_LOSS, 0.1); } else { - assertTrue(intervalStatistics.getIntervalList().stream().noneMatch(IntervalStatistics.Interval::hasLoss)); + assertTrue(intervalStatistics.getIntervalList().stream().noneMatch(IntervalStatisticsUpdater.Interval::hasLoss)); } for (int i = 0; i < intervalList.size() - 1; i++) { diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java index 0382bdee5..99bd7e64b 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java @@ -38,7 +38,7 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; +import de.dennisguse.opentracks.ui.intervals.IntervalStatisticsUpdater; /** * Execute a periodic task on a time or distance schedule. @@ -69,14 +69,14 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe private final ContentProviderUtils contentProviderUtils; private TrackPoint.Id startTrackPointId = null; - private IntervalStatistics intervalStatistics; + private IntervalStatisticsUpdater intervalStatistics; private Distance intervalDistance; public VoiceAnnouncementManager(@NonNull Context context) { this.context = context; contentProviderUtils = new ContentProviderUtils(context); intervalDistance = PreferencesUtils.getVoiceAnnouncementDistance(); - intervalStatistics = new IntervalStatistics(intervalDistance); + intervalStatistics = new IntervalStatisticsUpdater(intervalDistance); } public void start(@Nullable Statistics trackStatistics) { @@ -144,14 +144,14 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe private Spannable createAnnouncement(Track track, SensorDataSet sensorDataSet) { Distance currentIntervalDistance = PreferencesUtils.getVoiceAnnouncementDistance(); if (currentIntervalDistance != intervalDistance) { - intervalStatistics = new IntervalStatistics(currentIntervalDistance); + intervalStatistics = new IntervalStatisticsUpdater(currentIntervalDistance); intervalDistance = currentIntervalDistance; startTrackPointId = null; } TrackPointIterator trackPointIterator = new TrackPointIterator(contentProviderUtils, track.getId(), startTrackPointId); startTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator); - IntervalStatistics.Interval lastInterval = intervalStatistics.getLastInterval(); + IntervalStatisticsUpdater.Interval lastInterval = intervalStatistics.getLastInterval(); SensorStatistics sensorStatistics = null; if (track.getId() != null) { sensorStatistics = contentProviderUtils.getSensorStats(track.getId()); diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java index 7cb22c33b..7df5e430a 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtils.java @@ -38,7 +38,7 @@ import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.ui.intervals.IntervalStatistics; +import de.dennisguse.opentracks.ui.intervals.IntervalStatisticsUpdater; import de.dennisguse.opentracks.util.StringUtils; class VoiceAnnouncementUtils { @@ -51,7 +51,7 @@ class VoiceAnnouncementUtils { .append(context.getString(R.string.voiceIdle)); } - static Spannable createStatistics(Context context, Track track, SensorDataSet sensorDataSet, UnitSystem unitSystem, boolean isReportSpeed, @Nullable IntervalStatistics.Interval currentInterval, @Nullable SensorStatistics sensorStatistics) { + static Spannable createStatistics(Context context, Track track, SensorDataSet sensorDataSet, UnitSystem unitSystem, boolean isReportSpeed, @Nullable IntervalStatisticsUpdater.Interval currentInterval, @Nullable SensorStatistics sensorStatistics) { Statistics trackStatistics = track.getStatistics(); SpannableStringBuilder builder = new SpannableStringBuilder(); diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsAdapter.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsAdapter.java index 8de4d8ae1..1c495a681 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsAdapter.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsAdapter.java @@ -18,7 +18,7 @@ import de.dennisguse.opentracks.util.StringUtils; public class IntervalStatisticsAdapter extends RecyclerView.Adapter { - private List intervalList; + private List intervalList; private final Context context; private final StackMode stackMode; private UnitSystem unitSystem; @@ -43,7 +43,7 @@ public class IntervalStatisticsAdapter extends RecyclerView.Adapter swapData(List data, UnitSystem unitSystem, boolean isReportSpeed) { + public List swapData(List data, UnitSystem unitSystem, boolean isReportSpeed) { this.unitSystem = unitSystem; this.isReportSpeed = isReportSpeed; intervalList = data; diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java index 2bd1c892e..5c1d32395 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java @@ -32,8 +32,8 @@ public class IntervalStatisticsModel extends AndroidViewModel { private static final String TAG = IntervalStatisticsModel.class.getSimpleName(); - private MutableLiveData> intervalsLiveData; - private IntervalStatistics intervalStatistics; + private MutableLiveData> intervalsLiveData; + private IntervalStatisticsUpdater intervalStatistics; private Distance distanceInterval; private final ContentResolver contentResolver; private ContentObserver trackPointsTableObserver; @@ -65,7 +65,7 @@ public class IntervalStatisticsModel extends AndroidViewModel { handler = null; } - public MutableLiveData> getIntervalStats(Track.Id trackId, UnitSystem unitSystem, @Nullable IntervalOption interval) { + public MutableLiveData> getIntervalStats(Track.Id trackId, UnitSystem unitSystem, @Nullable IntervalOption interval) { if (intervalsLiveData == null) { if (interval == null) { interval = IntervalOption.OPTION_1; @@ -73,7 +73,7 @@ public class IntervalStatisticsModel extends AndroidViewModel { intervalsLiveData = new MutableLiveData<>(); distanceInterval = interval.getDistance(unitSystem); - intervalStatistics = new IntervalStatistics(distanceInterval); + intervalStatistics = new IntervalStatisticsUpdater(distanceInterval); loadIntervalStatistics(trackId); } @@ -112,7 +112,7 @@ public class IntervalStatisticsModel extends AndroidViewModel { lastTrackPointId = null; distanceInterval = interval.getDistance(unitSystem); - intervalStatistics = new IntervalStatistics(distanceInterval); + intervalStatistics = new IntervalStatisticsUpdater(distanceInterval); loadIntervalStatistics(trackId); } diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatistics.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java similarity index 98% rename from src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatistics.java rename to src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java index 99469b1e0..8295afa0f 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatistics.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java @@ -15,7 +15,7 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; -public class IntervalStatistics { +public class IntervalStatisticsUpdater { private TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); private final List intervalList; private final Distance distanceInterval; @@ -24,7 +24,7 @@ public class IntervalStatistics { /** * @param distanceInterval distance of every interval. */ - public IntervalStatistics(Distance distanceInterval) { + public IntervalStatisticsUpdater(Distance distanceInterval) { this.distanceInterval = distanceInterval; interval = new Interval(); diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalsFragment.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalsFragment.java index 7c814210e..c2281f67b 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalsFragment.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalsFragment.java @@ -192,7 +192,7 @@ public class IntervalsFragment extends Fragment { } viewBinding.intervalRate.setText(isReportSpeed ? getString(R.string.stats_speed) : getString(R.string.stats_pace)); - LiveData> liveData = viewModel.getIntervalStats(trackId, unitSystem, selectedInterval); + LiveData> liveData = viewModel.getIntervalStats(trackId, unitSystem, selectedInterval); liveData.observe(getActivity(), intervalList -> adapter.swapData(intervalList, unitSystem, isReportSpeed)); setIntervalsDropdownText(); From 7521f906ed44bc842b586e6dd0228969b09fff35 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Wed, 29 Oct 2025 08:43:49 +0100 Subject: [PATCH 14/30] IntervalStatisticsUpdater now uses Statistics. --- .../stats/SegmentStatisticUpdater.java | 4 -- .../stats/TrackStatisticsUpdater.java | 5 +++ .../intervals/IntervalStatisticsUpdater.java | 43 +++++++++++-------- 3 files changed, 29 insertions(+), 23 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 6ddeb9fee..fa7df7193 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -361,10 +361,6 @@ public class SegmentStatisticUpdater { } } - public boolean hasTotalAltitudeGain() { - return totalAltitudeGain_m != null; - } - @Nullable public Float getTotalAltitudeGain() { return totalAltitudeGain_m; diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index c1e93c328..724ebb762 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -79,6 +79,7 @@ public class TrackStatisticsUpdater { } //TODO Return Statistic? + @Deprecated public SegmentStatisticUpdater getTrackStatistics() { // Take a snapshot - we don't want anyone messing with our trackStatistics SegmentStatisticUpdater stats = new SegmentStatisticUpdater(segmentStatisticUpdater); @@ -86,6 +87,10 @@ public class TrackStatisticsUpdater { return stats; } + public Statistics getStatistics() { + return getTrackStatistics().getStatistics(); + } + public Statistics getCurrentSegment() { return currentSegment.getStatistics(); } diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java index 8295afa0f..317d10214 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java @@ -11,8 +11,8 @@ import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Power; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.TrackPoint; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; public class IntervalStatisticsUpdater { @@ -46,8 +46,8 @@ public class IntervalStatisticsUpdater { trackPoint = trackPointIterator.next(); trackStatisticsUpdater.addTrackPoint(trackPoint); - if (trackStatisticsUpdater.getTrackStatistics().getTotalDistance().plus(interval.distance).greaterOrEqualThan(distanceInterval)) { - interval.add(trackStatisticsUpdater.getTrackStatistics(), trackPoint); + if (trackStatisticsUpdater.getStatistics().totalDistance().plus(interval.distance).greaterOrEqualThan(distanceInterval)) { + interval.add(trackStatisticsUpdater.getStatistics(), trackPoint); double adjustFactor = distanceInterval.dividedBy(interval.distance); Interval adjustedInterval = new Interval(interval, adjustFactor); @@ -66,9 +66,9 @@ public class IntervalStatisticsUpdater { } if (newIntervalAdded) { - lastInterval.add(trackStatisticsUpdater.getTrackStatistics(), null); + lastInterval.add(trackStatisticsUpdater.getStatistics(), null); } else { - lastInterval.set(trackStatisticsUpdater.getTrackStatistics()); + lastInterval.set(trackStatisticsUpdater.getStatistics()); } return trackPoint != null ? trackPoint.getId() : null; @@ -98,6 +98,7 @@ public class IntervalStatisticsUpdater { return null; } + //TODO Could be replaced with Statistics? public static class Interval { private Distance distance = Distance.of(0); private Duration time = Duration.ofSeconds(0); @@ -172,13 +173,15 @@ public class IntervalStatisticsUpdater { return avgPower; } - private void add(SegmentStatisticUpdater trackStatistics, @Nullable TrackPoint lastTrackPoint) { - distance = distance.plus(trackStatistics.getTotalDistance()); - time = time.plus(trackStatistics.getTotalTime()); - gain_m = trackStatistics.hasTotalAltitudeGain() ? trackStatistics.getTotalAltitudeGain() : gain_m; - loss_m = trackStatistics.hasTotalAltitudeLoss() ? trackStatistics.getTotalAltitudeLoss() : loss_m; - avgHeartRate = trackStatistics.getAverageHeartRate(); - avgPower = trackStatistics.getAveragePower(); + private void add(Statistics trackStatistics, @Nullable TrackPoint lastTrackPoint) { + distance = distance.plus(trackStatistics.totalDistance()); + time = time.plus(trackStatistics.totalTime()); + if (trackStatistics.altitudeGainLoss() != null) { + gain_m = trackStatistics.altitudeGainLoss().gain_m(); + loss_m = trackStatistics.altitudeGainLoss().loss_m(); + } + avgHeartRate = trackStatistics.avgHeartRate(); + avgPower = trackStatistics.avgPower(); if (lastTrackPoint == null) { return; } @@ -190,13 +193,15 @@ public class IntervalStatisticsUpdater { } } - private void set(SegmentStatisticUpdater trackStatistics) { - distance = trackStatistics.getTotalDistance(); - time = trackStatistics.getTotalTime(); - gain_m = trackStatistics.hasTotalAltitudeGain() ? trackStatistics.getTotalAltitudeGain() : gain_m; - loss_m = trackStatistics.hasTotalAltitudeLoss() ? trackStatistics.getTotalAltitudeLoss() : loss_m; - avgHeartRate = trackStatistics.getAverageHeartRate(); - avgPower = trackStatistics.getAveragePower(); + private void set(Statistics trackStatistics) { + distance = trackStatistics.totalDistance(); + time = trackStatistics.totalTime(); + if (trackStatistics.altitudeGainLoss() != null) { + gain_m = trackStatistics.altitudeGainLoss().gain_m(); + loss_m = trackStatistics.altitudeGainLoss().loss_m(); + } + avgHeartRate = trackStatistics.avgHeartRate(); + avgPower = trackStatistics.avgPower(); } } } From 05e45b6870b6b3884bfe9cfa3c21165e2db21b17 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Wed, 29 Oct 2025 09:27:28 +0100 Subject: [PATCH 15/30] TrackStatisticsUpdater now provides Statistics. Used for non-testing code. --- .../opentracks/chart/ChartPointTest.java | 21 +++--- .../opentracks/content/data/TestDataUtil.java | 4 +- .../stats/TrackStatisticsUpdaterTest.java | 72 +++++++++---------- .../IntervalStatisticsUpdaterTest.java | 12 +--- .../opentracks/chart/ChartFragment.java | 3 +- .../opentracks/chart/ChartPoint.java | 8 +-- .../opentracks/data/TrackDataHub.java | 6 +- .../io/file/importer/TrackImporter.java | 2 +- .../services/TrackRecordingManager.java | 10 +-- .../services/TrackRecordingService.java | 2 +- .../stats/TrackStatisticsUpdater.java | 11 +-- .../intervals/IntervalStatisticsUpdater.java | 8 +-- 12 files changed, 75 insertions(+), 84 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java b/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java index f5539f0f3..49cf43e58 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java @@ -13,18 +13,20 @@ import java.time.Duration; import de.dennisguse.opentracks.data.models.Altitude; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; +//TODO assertEquals with ChartPoint (instead of individual comparisons) @RunWith(AndroidJUnit4.class) public class ChartPointTest { + private static final Statistics STATISTIC_NULL = new Statistics(null, null, Duration.ZERO, null, null, false, null, null, null, null, null); + @Test public void create_by_time() { // given - SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); - statistics.setTotalTime(Duration.ofSeconds(1000)); + Statistics statistics = new Statistics(null, null, Duration.ofSeconds(1000), null, null, false, null, null, null, null, null); // when ChartPoint point = ChartPoint.create(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), false, UnitSystem.IMPERIAL_FEET); @@ -36,8 +38,7 @@ public class ChartPointTest { @Test public void create_by_distance() { // given - SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); - statistics.setTotalDistance(Distance.of(1000)); + Statistics statistics = new Statistics(null, null, null, null, Distance.of(1000), false, null, null, null, null, null); // when ChartPoint point = ChartPoint.create(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), true, UnitSystem.METRIC); @@ -49,12 +50,11 @@ public class ChartPointTest { @Test public void create_get_altitude_speed_and_pace() { // given - SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint() .setAltitude(Altitude.EGM2008.of(50)); // when - ChartPoint point = ChartPoint.create(statistics, trackPoint, Speed.of(10), false, UnitSystem.METRIC); + ChartPoint point = ChartPoint.create(STATISTIC_NULL, trackPoint, Speed.of(10), false, UnitSystem.METRIC); // then assertEquals(50, point.altitude(), 0.01); @@ -65,11 +65,10 @@ public class ChartPointTest { @Test public void create_sensorNotAvailable() { // given - SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); TrackPoint trackPoint = TrackStubUtils.createDefaultTrackPoint() .setAltitude(Altitude.EGM2008.of(50)); // when - ChartPoint point = ChartPoint.create(statistics, trackPoint, Speed.of(10), false, UnitSystem.METRIC); + ChartPoint point = ChartPoint.create(STATISTIC_NULL, trackPoint, Speed.of(10), false, UnitSystem.METRIC); // then assertNull(point.heartRate()); @@ -86,10 +85,8 @@ public class ChartPointTest { .setCadence(101f) .setPower(102f); - SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); - // when - ChartPoint point = ChartPoint.create(statistics, trackPoint, Speed.of(10), false, UnitSystem.METRIC); + ChartPoint point = ChartPoint.create(STATISTIC_NULL, trackPoint, Speed.of(10), false, UnitSystem.METRIC); // then assertEquals(100.0, point.heartRate(), 0.01); diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java index bd9a28a62..3e718e36b 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java @@ -182,8 +182,8 @@ public class TestDataUtil { contentProviderUtils.insertTrackPoint(tp, dummyTrack.getId()); trackStatisticsUpdater.addTrackPoint(tp); } - dummyTrack.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics()); + dummyTrack.setStatistics(trackStatisticsUpdater.getTrackStatistics()); contentProviderUtils.updateTrack(dummyTrack); - return new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getTrackStatistics()); + return new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getSegmentStatisticUpdater()); } } diff --git a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java index a28b48337..d2cc129c1 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdaterTest.java @@ -31,7 +31,7 @@ public class TrackStatisticsUpdaterTest { TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); // then - SegmentStatisticUpdater statistics = subject.getTrackStatistics(); + SegmentStatisticUpdater statistics = subject.getSegmentStatisticUpdater(); assertNull(statistics.getStartTime()); assertNull(statistics.getStopTime()); assertEquals(Duration.ZERO, statistics.getTotalTime()); @@ -58,7 +58,7 @@ public class TrackStatisticsUpdaterTest { subject.addTrackPoint(tp); // then - SegmentStatisticUpdater statistics = subject.getTrackStatistics(); + SegmentStatisticUpdater statistics = subject.getSegmentStatisticUpdater(); assertEquals(startTime, statistics.getStartTime()); assertEquals(startTime, statistics.getStopTime()); assertEquals(Duration.ZERO, statistics.getTotalTime()); @@ -83,7 +83,7 @@ public class TrackStatisticsUpdaterTest { data.trackPoints().forEach(subject::addTrackPoint); // then - SegmentStatisticUpdater statistics = subject.getTrackStatistics(); + SegmentStatisticUpdater statistics = subject.getSegmentStatisticUpdater(); assertEquals(142.26, statistics.getTotalDistance().toM(), 0.01); assertEquals(Duration.ofSeconds(12), statistics.getTotalTime()); assertEquals(Duration.ofSeconds(12), statistics.getMovingTime()); @@ -115,7 +115,7 @@ public class TrackStatisticsUpdaterTest { subject.addTrackPoint(tp3); // then - assertEquals(1.10, subject.getTrackStatistics().getTotalDistance().toM(), 0.01); + assertEquals(1.10, subject.getSegmentStatisticUpdater().getTotalDistance().toM(), 0.01); } @Test @@ -140,14 +140,14 @@ public class TrackStatisticsUpdaterTest { subject.addTrackPoint(tp3); // then - assertEquals(110.57, subject.getTrackStatistics().getTotalDistance().toM(), 0.01); + assertEquals(110.57, subject.getSegmentStatisticUpdater().getTotalDistance().toM(), 0.01); // when subject.addTrackPoint(tp4); subject.addTrackPoint(tp5); // then - assertEquals(125.57, subject.getTrackStatistics().getTotalDistance().toM(), 0.01); + assertEquals(125.57, subject.getSegmentStatisticUpdater().getTotalDistance().toM(), 0.01); } @Test @@ -171,20 +171,20 @@ public class TrackStatisticsUpdaterTest { subject.addTrackPoint(tp3); // then - assertEquals(5, subject.getTrackStatistics().getTotalDistance().toM(), 0.01); + assertEquals(5, subject.getSegmentStatisticUpdater().getTotalDistance().toM(), 0.01); // when subject.addTrackPoint(tp4); subject.addTrackPoint(tp5); // then - assertEquals(59.18, subject.getTrackStatistics().getTotalDistance().toM(), 0.01); + assertEquals(59.18, subject.getSegmentStatisticUpdater().getTotalDistance().toM(), 0.01); } @Test public void addTrackPoint_maxSpeed_multiple_segments() { TrackStatisticsUpdater subject = new TrackStatisticsUpdater(); - assertEquals(Speed.of(0f), subject.getTrackStatistics().getMaxSpeed()); + assertEquals(Speed.of(0f), subject.getSegmentStatisticUpdater().getMaxSpeed()); subject.addTrackPoints(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.ofEpochSecond(0)), @@ -194,7 +194,7 @@ public class TrackStatisticsUpdaterTest { .setSpeed(Speed.of(2f)), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochSecond(4)) )); - assertEquals(Speed.of(2f), subject.getTrackStatistics().getMaxSpeed()); + assertEquals(Speed.of(2f), subject.getSegmentStatisticUpdater().getMaxSpeed()); // when subject.addTrackPoints(List.of( @@ -207,7 +207,7 @@ public class TrackStatisticsUpdaterTest { )); // then - assertEquals(Speed.of(2f), subject.getTrackStatistics().getMaxSpeed()); + assertEquals(Speed.of(2f), subject.getSegmentStatisticUpdater().getMaxSpeed()); } @Test @@ -234,7 +234,7 @@ public class TrackStatisticsUpdaterTest { )); // then - assertEquals(Duration.ofSeconds(35), subject.getTrackStatistics().getMovingTime()); + assertEquals(Duration.ofSeconds(35), subject.getSegmentStatisticUpdater().getMovingTime()); } @Test @@ -264,8 +264,8 @@ public class TrackStatisticsUpdaterTest { )); // then - assertEquals(Duration.ofSeconds(40), subject.getTrackStatistics().getMovingTime()); - assertEquals(Distance.of(1040), subject.getTrackStatistics().getTotalDistance()); + assertEquals(Duration.ofSeconds(40), subject.getSegmentStatisticUpdater().getMovingTime()); + assertEquals(Distance.of(1040), subject.getSegmentStatisticUpdater().getTotalDistance()); } @Test @@ -280,49 +280,49 @@ public class TrackStatisticsUpdaterTest { subject.addTrackPoint(new TrackPoint(TrackPoint.Type.IDLE, Instant.ofEpochSecond(30))); // then - assertTrue(subject.getTrackStatistics().isIdle()); - assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getMovingTime()); - assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getTotalTime()); - assertEquals(Distance.of(10), subject.getTrackStatistics().getTotalDistance()); + assertTrue(subject.getSegmentStatisticUpdater().isIdle()); + assertEquals(Duration.ofSeconds(30), subject.getSegmentStatisticUpdater().getMovingTime()); + assertEquals(Duration.ofSeconds(30), subject.getSegmentStatisticUpdater().getTotalTime()); + assertEquals(Distance.of(10), subject.getSegmentStatisticUpdater().getTotalDistance()); // when subject.addTrackPoint( new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochSecond(40)) .setSensorDistance(Distance.of(0))); // then - assertTrue(subject.getTrackStatistics().isIdle()); - assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getMovingTime()); - assertEquals(Duration.ofSeconds(40), subject.getTrackStatistics().getTotalTime()); - assertEquals(Distance.of(10), subject.getTrackStatistics().getTotalDistance()); + assertTrue(subject.getSegmentStatisticUpdater().isIdle()); + assertEquals(Duration.ofSeconds(30), subject.getSegmentStatisticUpdater().getMovingTime()); + assertEquals(Duration.ofSeconds(40), subject.getSegmentStatisticUpdater().getTotalTime()); + assertEquals(Distance.of(10), subject.getSegmentStatisticUpdater().getTotalDistance()); // when subject.addTrackPoint( new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochSecond(45)) .setSensorDistance(Distance.of(1))); // then - assertTrue(subject.getTrackStatistics().isIdle()); - assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getMovingTime()); - assertEquals(Duration.ofSeconds(45), subject.getTrackStatistics().getTotalTime()); - assertEquals(Distance.of(11), subject.getTrackStatistics().getTotalDistance()); + assertTrue(subject.getSegmentStatisticUpdater().isIdle()); + assertEquals(Duration.ofSeconds(30), subject.getSegmentStatisticUpdater().getMovingTime()); + assertEquals(Duration.ofSeconds(45), subject.getSegmentStatisticUpdater().getTotalTime()); + assertEquals(Distance.of(11), subject.getSegmentStatisticUpdater().getTotalDistance()); // when subject.addTrackPoint( new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.ofEpochSecond(50)) .setSensorDistance(Distance.of(10))); // then - assertFalse(subject.getTrackStatistics().isIdle()); - assertEquals(Duration.ofSeconds(30), subject.getTrackStatistics().getMovingTime()); - assertEquals(Duration.ofSeconds(50), subject.getTrackStatistics().getTotalTime()); - assertEquals(Distance.of(21), subject.getTrackStatistics().getTotalDistance()); + assertFalse(subject.getSegmentStatisticUpdater().isIdle()); + assertEquals(Duration.ofSeconds(30), subject.getSegmentStatisticUpdater().getMovingTime()); + assertEquals(Duration.ofSeconds(50), subject.getSegmentStatisticUpdater().getTotalTime()); + assertEquals(Distance.of(21), subject.getSegmentStatisticUpdater().getTotalDistance()); // when subject.addTrackPoint(new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.ofEpochSecond(60))); // then - assertFalse(subject.getTrackStatistics().isIdle()); - assertEquals(Duration.ofSeconds(40), subject.getTrackStatistics().getMovingTime()); - assertEquals(Duration.ofSeconds(60), subject.getTrackStatistics().getTotalTime()); - assertEquals(Distance.of(21), subject.getTrackStatistics().getTotalDistance()); + assertFalse(subject.getSegmentStatisticUpdater().isIdle()); + assertEquals(Duration.ofSeconds(40), subject.getSegmentStatisticUpdater().getMovingTime()); + assertEquals(Duration.ofSeconds(60), subject.getSegmentStatisticUpdater().getTotalTime()); + assertEquals(Distance.of(21), subject.getSegmentStatisticUpdater().getTotalDistance()); } @Test @@ -350,8 +350,8 @@ public class TrackStatisticsUpdaterTest { copy.addTrackPoint(tp5); // then - assertEquals(55.287, subject.getTrackStatistics().getTotalDistance().toM(), 0.01); - assertEquals(55.287, copy.getTrackStatistics().getTotalDistance().toM(), 0.01); + assertEquals(55.287, subject.getSegmentStatisticUpdater().getTotalDistance().toM(), 0.01); + assertEquals(55.287, copy.getSegmentStatisticUpdater().getTotalDistance().toM(), 0.01); } public TrackPoint createTrackPoint(double latitude, double longitude, Altitude altitude, Instant time) { diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java index d9949a823..25417b8ed 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java @@ -37,14 +37,6 @@ public class IntervalStatisticsUpdaterTest { contentProviderUtils = new ContentProviderUtils(context); } - private SegmentStatisticUpdater buildTrackStatistics(List trackPoints) { - TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); - for (TrackPoint tp : trackPoints) { - trackStatisticsUpdater.addTrackPoint(tp); - } - return trackStatisticsUpdater.getTrackStatistics(); - } - /** * Tests that build method compute the distance correctly comparing the result with TrackStatisticsUpdater result. */ @@ -133,9 +125,9 @@ public class IntervalStatisticsUpdaterTest { contentProviderUtils.insertTrackPoint(tp, dummyTrack.getId()); trackStatisticsUpdater.addTrackPoint(tp); } - dummyTrack.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics()); + dummyTrack.setStatistics(trackStatisticsUpdater.getTrackStatistics()); contentProviderUtils.updateTrack(dummyTrack); - Pair trackWithStats = new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getTrackStatistics()); + Pair trackWithStats = new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getSegmentStatisticUpdater()); // when and then whenAndThen(trackWithStats, numberOfPoints, distanceInterval); diff --git a/src/main/java/de/dennisguse/opentracks/chart/ChartFragment.java b/src/main/java/de/dennisguse/opentracks/chart/ChartFragment.java index c1b9714a3..d49fb2c8d 100644 --- a/src/main/java/de/dennisguse/opentracks/chart/ChartFragment.java +++ b/src/main/java/de/dennisguse/opentracks/chart/ChartFragment.java @@ -33,6 +33,7 @@ import java.util.List; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.TrackDataHub; import de.dennisguse.opentracks.data.models.Marker; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.databinding.ChartBinding; @@ -202,7 +203,7 @@ public class ChartFragment extends Fragment implements TrackDataHub.Listener { } } - public void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull SegmentStatisticUpdater trackStatistics) { + public void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull Statistics trackStatistics) { if (isResumed()) { ChartPoint point = ChartPoint.create(trackStatistics, trackPoint, trackPoint.getSpeed(), chartByDistance, viewBinding.chartView.getUnitSystem()); pendingPoints.add(point); diff --git a/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java b/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java index c90cb628c..a12426d51 100644 --- a/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java +++ b/src/main/java/de/dennisguse/opentracks/chart/ChartPoint.java @@ -4,9 +4,9 @@ import androidx.annotation.NonNull; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; public record ChartPoint( //X-axis @@ -22,11 +22,11 @@ public record ChartPoint( ) { - public static ChartPoint create(@NonNull SegmentStatisticUpdater trackStatistics, @NonNull TrackPoint trackPoint, Speed smoothedSpeed, boolean chartByDistance, UnitSystem unitSystem) { + public static ChartPoint create(@NonNull Statistics trackStatistics, @NonNull TrackPoint trackPoint, Speed smoothedSpeed, boolean chartByDistance, UnitSystem unitSystem) { return new ChartPoint( chartByDistance - ? trackStatistics.getTotalDistance().toKM_Miles(unitSystem) - : trackStatistics.getTotalTime().toMillis(), + ? trackStatistics.totalDistance().toKM_Miles(unitSystem) + : trackStatistics.totalTime().toMillis(), trackPoint.hasAltitude() ? Distance.of(trackPoint.getAltitude().toM()).toM_FT(unitSystem) : null, diff --git a/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java b/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java index 0cf59b9be..b5d9c867e 100644 --- a/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java +++ b/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java @@ -32,6 +32,7 @@ import java.util.HashSet; import java.util.Set; import de.dennisguse.opentracks.data.models.Marker; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.data.tables.MarkerColumns; @@ -40,7 +41,6 @@ import de.dennisguse.opentracks.data.tables.TracksColumns; import de.dennisguse.opentracks.services.RecordingStatus; import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.services.handlers.AltitudeCorrectionManager; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; /** @@ -428,7 +428,7 @@ public class TrackDataHub { * * @param trackPoint the trackPoint */ - default void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull SegmentStatisticUpdater trackStatistics) { + default void onSampledInTrackPoint(@NonNull TrackPoint trackPoint, @NonNull Statistics trackStatistics) { } /** @@ -436,7 +436,7 @@ public class TrackDataHub { * * @param trackPoint the trackPoint */ - default void onSampledOutTrackPoint(@NonNull TrackPoint trackPoint, @NonNull SegmentStatisticUpdater trackStatistics) { + default void onSampledOutTrackPoint(@NonNull TrackPoint trackPoint, @NonNull Statistics trackStatistics) { } /** diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/TrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/TrackImporter.java index fc9ee0616..433aafa1f 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/TrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/TrackImporter.java @@ -147,7 +147,7 @@ public class TrackImporter { TrackStatisticsUpdater updater = new TrackStatisticsUpdater(); updater.addTrackPoints(trackPoints); - track.setTrackStatistics(updater.getTrackStatistics()); + track.setStatistics(updater.getTrackStatistics()); Track.Id trackId = contentProviderUtils.insertTrack(track); diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java index 5df36b6b4..e674c610d 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java @@ -17,13 +17,13 @@ import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.models.ActivityType; import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.services.handlers.AltitudeCorrectionManager; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; import de.dennisguse.opentracks.settings.PreferencesUtils; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; import de.dennisguse.opentracks.util.TrackNameUtils; @@ -80,7 +80,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen String activityTypeLocalized = PreferencesUtils.getDefaultActivityTypeLocalized(); track.setActivityTypeLocalized(activityTypeLocalized); track.setActivityType(ActivityType.findByLocalizedString(context, activityTypeLocalized)); - track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics()); + track.setStatistics(trackStatisticsUpdater.getTrackStatistics()); track.setName(TrackNameUtils.getTrackName(context, trackId, track.getStartTime())); contentProviderUtils.updateTrack(track); @@ -130,7 +130,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen return null; } - track.setTrackStatistics(tmpTrackStatisticsUpdater.getTrackStatistics()); + track.setStatistics(tmpTrackStatisticsUpdater.getTrackStatistics()); return new RecordingData(track, current.first, current.second, tmpTrackStatisticsUpdater.getCurrentSegment()); } @@ -224,7 +224,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen handler.postDelayed(ON_IDLE, idleDuration.toMillis()); } - SegmentStatisticUpdater getTrackStatistics() { + Statistics getTrackStatistics() { return trackStatisticsUpdater == null ? null : trackStatisticsUpdater.getTrackStatistics(); } @@ -249,7 +249,7 @@ public class TrackRecordingManager implements SharedPreferences.OnSharedPreferen contentProviderUtils.insertTrackPoint(trackPoint, trackId); trackStatisticsUpdater.addTrackPoint(trackPoint); - contentProviderUtils.updateTrackStatistics(trackId, trackStatisticsUpdater.getTrackStatistics().getStatistics()); + contentProviderUtils.updateTrackStatistics(trackId, trackStatisticsUpdater.getTrackStatistics()); lastStoredTrackPoint = trackPoint; if (trackPoint.hasLocation()) { lastStoredTrackPointWithLocation = lastStoredTrackPoint; diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java index a6f1e97d6..3a04ae1aa 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java @@ -194,7 +194,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator. startSensors(); - voiceAnnouncementManager.start(trackRecordingManager.getTrackStatistics().getStatistics()); + voiceAnnouncementManager.start(trackRecordingManager.getTrackStatistics()); notificationManager.onRecordingStarted(this, recordingStatus.trackId()); } diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index 724ebb762..03945cb27 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -17,6 +17,7 @@ package de.dennisguse.opentracks.stats; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import java.time.Duration; import java.util.List; @@ -78,17 +79,17 @@ public class TrackStatisticsUpdater { resetAverageHeartRate(); } - //TODO Return Statistic? - @Deprecated - public SegmentStatisticUpdater getTrackStatistics() { + @Deprecated //TODO Remove + @VisibleForTesting + public SegmentStatisticUpdater getSegmentStatisticUpdater() { // Take a snapshot - we don't want anyone messing with our trackStatistics SegmentStatisticUpdater stats = new SegmentStatisticUpdater(segmentStatisticUpdater); stats.merge(currentSegment); return stats; } - public Statistics getStatistics() { - return getTrackStatistics().getStatistics(); + public Statistics getTrackStatistics() { + return getSegmentStatisticUpdater().getStatistics(); } public Statistics getCurrentSegment() { diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java index 317d10214..18540dca7 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java @@ -46,8 +46,8 @@ public class IntervalStatisticsUpdater { trackPoint = trackPointIterator.next(); trackStatisticsUpdater.addTrackPoint(trackPoint); - if (trackStatisticsUpdater.getStatistics().totalDistance().plus(interval.distance).greaterOrEqualThan(distanceInterval)) { - interval.add(trackStatisticsUpdater.getStatistics(), trackPoint); + if (trackStatisticsUpdater.getTrackStatistics().totalDistance().plus(interval.distance).greaterOrEqualThan(distanceInterval)) { + interval.add(trackStatisticsUpdater.getTrackStatistics(), trackPoint); double adjustFactor = distanceInterval.dividedBy(interval.distance); Interval adjustedInterval = new Interval(interval, adjustFactor); @@ -66,9 +66,9 @@ public class IntervalStatisticsUpdater { } if (newIntervalAdded) { - lastInterval.add(trackStatisticsUpdater.getStatistics(), null); + lastInterval.add(trackStatisticsUpdater.getTrackStatistics(), null); } else { - lastInterval.set(trackStatisticsUpdater.getStatistics()); + lastInterval.set(trackStatisticsUpdater.getTrackStatistics()); } return trackPoint != null ? trackPoint.getId() : null; From fd92793c2af04a43a85736ae20942308ac03678b Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Wed, 29 Oct 2025 19:03:14 +0100 Subject: [PATCH 16/30] Test: IntervalStatisticsUpdaterTest doesn't store data anymore. --- .../opentracks/content/data/TestDataUtil.java | 10 --- .../IntervalStatisticsUpdaterTest.java | 68 ++++++++----------- .../intervals/IntervalStatisticsUpdater.java | 4 +- 3 files changed, 32 insertions(+), 50 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java index 3e718e36b..c76402675 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java @@ -6,7 +6,6 @@ import android.util.Pair; import java.io.File; import java.io.IOException; -import java.time.Duration; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -85,10 +84,6 @@ public class TestDataUtil { createTrackPoint(i, TrackPoint.Type.SEGMENT_END_MANUAL) ); - //TODO Use TrackStatisticsUpdater - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setTotalDistance(Distance.of(0)); - stats.setTotalTime(Duration.ofMillis(0)); List markers = List.of( new Marker(trackId, trackPoints.get(1), "Marker 1", "Marker description 1", "Marker category 3", "", null), new Marker(trackId, trackPoints.get(4), "Marker 2", "Marker description 2", "Marker category 3", "", null), @@ -153,11 +148,6 @@ public class TestDataUtil { dstFile.createNewFile(); Uri photoUri = FileUtils.getUriForFile(context, dstFile); - //TODO Use TrackStatisticsUpdater - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setTotalDistance(Distance.of(0)); - stats.setTotalTime(Duration.ofMillis(0)); - return new Marker(trackId, trackPoint, "Marker name", "Marker description", "Marker category", "", photoUri); } diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java index 25417b8ed..8006aeb79 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java @@ -3,40 +3,24 @@ package de.dennisguse.opentracks.ui.intervals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; -import android.content.Context; import android.util.Pair; -import androidx.test.core.app.ApplicationProvider; - -import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.JUnit4; +import java.util.ArrayList; import java.util.List; import de.dennisguse.opentracks.content.data.TestDataUtil; -import de.dennisguse.opentracks.data.ContentProviderUtils; -import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; @RunWith(JUnit4.class) public class IntervalStatisticsUpdaterTest { - private static final String TAG = IntervalStatisticsUpdaterTest.class.getSimpleName(); - - private final Context context = ApplicationProvider.getApplicationContext(); - private ContentProviderUtils contentProviderUtils; - - @Before - public void setUp() { - contentProviderUtils = new ContentProviderUtils(context); - } - /** * Tests that build method compute the distance correctly comparing the result with TrackStatisticsUpdater result. */ @@ -117,36 +101,31 @@ public class IntervalStatisticsUpdaterTest { Track dummyTrack = new Track(); dummyTrack.setId(new Track.Id(System.currentTimeMillis())); dummyTrack.setName("Dummy Track Without Elevation Loss"); - contentProviderUtils.insertTrack(dummyTrack); TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); + + ArrayList trackPoints = new ArrayList<>(); for (int i = 0; i < numberOfPoints; i++) { - TrackPoint tp = TestDataUtil.createTrackPoint(i); - tp.setAltitudeLoss(null); - contentProviderUtils.insertTrackPoint(tp, dummyTrack.getId()); - trackStatisticsUpdater.addTrackPoint(tp); + trackPoints.add(TestDataUtil.createTrackPoint(i).setAltitudeLoss(null)); } + trackStatisticsUpdater.addTrackPoints(trackPoints); + dummyTrack.setStatistics(trackStatisticsUpdater.getTrackStatistics()); - contentProviderUtils.updateTrack(dummyTrack); - Pair trackWithStats = new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getSegmentStatisticUpdater()); + Pair> trackWithStats = new Pair<>(dummyTrack, trackPoints); // when and then - whenAndThen(trackWithStats, numberOfPoints, distanceInterval); + whenAndThen(trackWithStats.first, trackWithStats.second, numberOfPoints, distanceInterval); } private void whenAndThen(int numberOfPoints, float distanceInterval) { - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); - whenAndThen(trackWithStats, numberOfPoints, distanceInterval); - + Pair> trackWithStats = buildTrackWithTrackPoints(numberOfPoints); + whenAndThen(trackWithStats.first, trackWithStats.second, numberOfPoints, distanceInterval); } - private void whenAndThen(Pair trackWithStats, int numberOfPoints, float distanceInterval) { + private void whenAndThen(Track track, List trackPoints, int numberOfPoints, float distanceInterval) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(distanceInterval)); - Track.Id trackId = trackWithStats.first; - SegmentStatisticUpdater trackStatistics = trackWithStats.second; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - assertEquals(trackPointIterator.getCount(), numberOfPoints); - intervalStatistics.addTrackPoints(trackPointIterator); - } + + intervalStatistics.addTrackPoints(trackPoints.iterator()); + List intervalList = intervalStatistics.getIntervalList(); Distance totalDistance = Distance.of(0); float totalTime = 0L; @@ -170,9 +149,9 @@ public class IntervalStatisticsUpdaterTest { } // then - assertEquals(trackStatistics.getTotalDistance().toM(), totalDistance.toM(), 0.01); - assertEquals(trackStatistics.getTotalTime().toSeconds(), totalTime, 0.01); - assertEquals(intervalList.size(), (int) Math.ceil(trackStatistics.getTotalDistance().toM() / distanceInterval)); + assertEquals(track.getStatistics().totalTime().toSeconds(), totalTime, 0.01); + assertEquals(track.getStatistics().totalDistance().toM(), totalDistance.toM(), 0.01); + assertEquals(intervalList.size(), (int) Math.ceil(track.getStatistics().totalDistance().toM() / distanceInterval)); if (totalGain != null) { assertEquals(totalGain, numberOfPoints * TestDataUtil.ALTITUDE_GAIN, 0.1); } else { @@ -190,4 +169,17 @@ public class IntervalStatisticsUpdaterTest { } assertEquals(intervalList.get(intervalList.size() - 1).getDistance().toM(), totalDistance.toM(), 0.01); } + + private static Pair> buildTrackWithTrackPoints(int numberOfPoints) { + Track dummyTrack = new Track(); + TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); + + ArrayList trackPoints = new ArrayList<>(); + for (int i = 0; i < numberOfPoints; i++) { + trackPoints.add(TestDataUtil.createTrackPoint(i)); + } + trackStatisticsUpdater.addTrackPoints(trackPoints); + dummyTrack.setStatistics(trackStatisticsUpdater.getTrackStatistics()); + return new Pair<>(dummyTrack, trackPoints); + } } \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java index 18540dca7..884841849 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java @@ -4,9 +4,9 @@ import androidx.annotation.Nullable; import java.time.Duration; import java.util.ArrayList; +import java.util.Iterator; import java.util.List; -import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Power; @@ -38,7 +38,7 @@ public class IntervalStatisticsUpdater { * * @return the last track point's id used to compute the intervals. */ - public TrackPoint.Id addTrackPoints(TrackPointIterator trackPointIterator) { + public TrackPoint.Id addTrackPoints(Iterator trackPointIterator) { boolean newIntervalAdded = false; TrackPoint trackPoint = null; From 4db72230ff4a175e5df7f2333dff7ac6d79598cb Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Wed, 29 Oct 2025 21:05:33 +0100 Subject: [PATCH 17/30] Refactored VoiceAnnouncementUtilsTest. --- .../opentracks/content/data/TestDataUtil.java | 18 -- .../VoiceAnnouncementUtilsTest.java | 274 +++++++++++------- .../opentracks/data/models/Track.java | 6 + 3 files changed, 168 insertions(+), 130 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java index c76402675..870978911 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java @@ -19,8 +19,6 @@ import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; -import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; import de.dennisguse.opentracks.ui.markers.MarkerUtils; import de.dennisguse.opentracks.util.FileUtils; @@ -160,20 +158,4 @@ public class TestDataUtil { return trackPoints; } } - - public static Pair buildTrackWithTrackPoints(ContentProviderUtils contentProviderUtils, int numberOfPoints) { - Track dummyTrack = new Track(); - dummyTrack.setId(new Track.Id(System.currentTimeMillis())); - dummyTrack.setName("Dummy Track"); - contentProviderUtils.insertTrack(dummyTrack); - TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); - for (int i = 0; i < numberOfPoints; i++) { - TrackPoint tp = TestDataUtil.createTrackPoint(i); - contentProviderUtils.insertTrackPoint(tp, dummyTrack.getId()); - trackStatisticsUpdater.addTrackPoint(tp); - } - dummyTrack.setStatistics(trackStatisticsUpdater.getTrackStatistics()); - contentProviderUtils.updateTrack(dummyTrack); - return new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getSegmentStatisticUpdater()); - } } diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java index a4b5c8bbe..fca43146e 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java @@ -26,15 +26,19 @@ import de.dennisguse.opentracks.LocaleRule; import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.TrackPointIterator; +import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; +import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.UnitSystem; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.SensorStatistics; +import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; import de.dennisguse.opentracks.ui.intervals.IntervalStatisticsUpdater; @RunWith(AndroidJUnit4.class) @@ -66,16 +70,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_speed() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.of(20000)); - stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); - stats.setMaxSpeed(Speed.of(100)); - stats.setTotalAltitudeGain(6000f); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1).plusMinutes(5).plusSeconds(10), + Distance.of(20000), + false, + Speed.of(100), + null, + null, + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -89,16 +96,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_speed_rounding_check() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.of(20000)); - stats.setTotalTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1).plusSeconds(1)); - stats.setMaxSpeed(Speed.of(100)); - stats.setTotalAltitudeGain(6000f); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1).plusSeconds(1), + Distance.of(20000), + false, + Speed.of(100), + null, + new AltitudeGainLoss(6000, 6000), + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -112,16 +122,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_distance_rounding_check() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.of(19999)); - stats.setTotalTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1)); - stats.setMaxSpeed(Speed.of(100)); - stats.setTotalAltitudeGain(6000f); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1), + Distance.of(19999), + false, + Speed.of(100), + null, + new AltitudeGainLoss(6000, 6000), + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -135,16 +148,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_distance_rounding_check_two() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.of(19900)); - stats.setTotalTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1)); - stats.setMaxSpeed(Speed.of(100)); - stats.setTotalAltitudeGain(6000f); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1), + Distance.of(19900), + false, + Speed.of(100), + null, + new AltitudeGainLoss(6000, 6000), + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -160,7 +176,7 @@ public class VoiceAnnouncementUtilsTest { public void getAnnouncement_withInterval_metric_speed() { // given int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; @@ -174,8 +190,7 @@ public class VoiceAnnouncementUtilsTest { SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(stats.getStatistics()); // when String announcement = VoiceAnnouncementUtils.createStatistics(context, track, dataSet, UnitSystem.METRIC, true, lastInterval, null).toString(); @@ -186,16 +201,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_pace() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.of(20000)); - stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); - stats.setMaxSpeed(Speed.of(100)); - stats.setTotalAltitudeGain(6000f); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1).plusMinutes(5).plusSeconds(10), + Distance.of(20000), + false, + Speed.of(100), + null, + new AltitudeGainLoss(6000, 6000), + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -211,7 +229,7 @@ public class VoiceAnnouncementUtilsTest { public void getAnnouncement_withInterval_metric_pace() { // given int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; @@ -222,8 +240,7 @@ public class VoiceAnnouncementUtilsTest { lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(stats.getStatistics()); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -237,16 +254,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_imperial_speed() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.of(20000)); - stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); - stats.setMaxSpeed(Speed.of(100)); - stats.setTotalAltitudeGain(6000f); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1).plusMinutes(5).plusSeconds(10), + Distance.of(20000), + false, + Speed.of(100), + null, + new AltitudeGainLoss(6000, 6000), + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -260,14 +280,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_imperial_speed_1() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.ofMile(1.1)); - stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1)); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1), + Distance.ofMile(1.1), + false, + null, + null, + null, + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -281,14 +306,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_imperial_meter_speed_1() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.ofMile(1.1)); - stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1)); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1), + Distance.ofMile(1.1), + false, + null, + null, + null, + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -302,14 +332,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_metric_speed_1() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.ofKilometer(1.1)); - stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1)); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1), + Distance.ofKilometer(1.1), + false, + null, + null, + null, + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -325,7 +360,7 @@ public class VoiceAnnouncementUtilsTest { public void getAnnouncement_withInterval_imperial_speed() { // given int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; @@ -336,8 +371,7 @@ public class VoiceAnnouncementUtilsTest { lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(stats.getStatistics()); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -351,16 +385,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_imperial_pace() { - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setStartTime(Instant.EPOCH); - stats.setTotalDistance(Distance.of(20000)); - stats.setTotalTime(Duration.ofHours(2).plusMinutes(5).plusSeconds(10)); - stats.setMovingTime(Duration.ofHours(1).plusMinutes(5).plusSeconds(10)); - stats.setMaxSpeed(Speed.of(100)); - stats.setTotalAltitudeGain(6000f); - - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH, + Duration.ofHours(2).plusMinutes(5).plusSeconds(10), + Duration.ofHours(1).plusMinutes(5).plusSeconds(10), + Distance.of(20000), + false, + Speed.of(100), + null, + new AltitudeGainLoss(6000, 6000), + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -376,7 +413,7 @@ public class VoiceAnnouncementUtilsTest { public void getAnnouncement_withInterval_imperial_pace() { // given int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; @@ -387,8 +424,7 @@ public class VoiceAnnouncementUtilsTest { lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(stats.getStatistics()); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -406,7 +442,7 @@ public class VoiceAnnouncementUtilsTest { PreferencesUtils.setVoiceAnnounceLapHeartRate(true); int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; @@ -419,8 +455,7 @@ public class VoiceAnnouncementUtilsTest { SensorStatistics sensorStatistics = new SensorStatistics(HeartRate.of(180f), HeartRate.of(180f), null, null, null, null); - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(stats.getStatistics()); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -444,7 +479,7 @@ public class VoiceAnnouncementUtilsTest { PreferencesUtils.setVoiceAnnounceLapSpeedPace(false); int numberOfPoints = 1000; - Pair trackWithStats = TestDataUtil.buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); + Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; @@ -457,8 +492,7 @@ public class VoiceAnnouncementUtilsTest { SensorStatistics sensorStatistics = new SensorStatistics(HeartRate.of(180f), HeartRate.of(180f), null, null, null, null); - Track track = new Track(); - track.setTrackStatistics(stats); + Track track = new Track(stats.getStatistics()); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -484,4 +518,20 @@ public class VoiceAnnouncementUtilsTest { assertEquals("1.1 miles", MessageFormat.format(template, Map.of("n", 1.11))); assertEquals("1.2 miles", MessageFormat.format(template, Map.of("n", 1.18))); } + + public static Pair buildTrackWithTrackPoints(ContentProviderUtils contentProviderUtils, int numberOfPoints) { + Track dummyTrack = new Track(); + dummyTrack.setId(new Track.Id(System.currentTimeMillis())); + dummyTrack.setName("Dummy Track"); + contentProviderUtils.insertTrack(dummyTrack); + TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); + for (int i = 0; i < numberOfPoints; i++) { + TrackPoint tp = TestDataUtil.createTrackPoint(i); + contentProviderUtils.insertTrackPoint(tp, dummyTrack.getId()); + trackStatisticsUpdater.addTrackPoint(tp); + } + dummyTrack.setStatistics(trackStatisticsUpdater.getTrackStatistics()); + contentProviderUtils.updateTrack(dummyTrack); + return new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getSegmentStatisticUpdater()); + } } diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Track.java b/src/main/java/de/dennisguse/opentracks/data/models/Track.java index b23bb559c..c20d6916d 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Track.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Track.java @@ -54,11 +54,17 @@ public class Track { @NonNull private Statistics trackStatistics; + @Deprecated @VisibleForTesting public Track() { this(ZoneOffset.UTC); } + @VisibleForTesting + public Track(Statistics statistics) { + this(ZoneOffset.UTC, statistics); + } + @Deprecated //TODO Remove public Track(@NonNull ZoneOffset zoneOffset) { this(zoneOffset, new SegmentStatisticUpdater().getStatistics()); From 8f537f33a75447e8f6b20524be6b85fd310e2c8d Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Wed, 29 Oct 2025 21:25:05 +0100 Subject: [PATCH 18/30] Cleanup: removed Track.setTrackStatistics(SegmentStatisticsUpdater). --- .../data/CustomContentProviderUtilsTest.java | 29 ++++++++------- ...cordingServiceNotificationManagerTest.java | 37 +++++++++---------- .../share/TrackShareSummaryGeneratorTest.java | 34 ++++++++--------- .../AggregatedStatisticsTest.java | 29 ++++++++------- .../opentracks/data/models/Track.java | 5 --- 5 files changed, 67 insertions(+), 67 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java index 3dad21cdf..93ec4e9a4 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java @@ -51,18 +51,20 @@ import java.util.UUID; import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.content.data.TestSensorDataUtil; import de.dennisguse.opentracks.data.models.Altitude; +import de.dennisguse.opentracks.data.models.AltitudeExtremities; +import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.data.tables.MarkerColumns; import de.dennisguse.opentracks.data.tables.TrackPointsColumns; import de.dennisguse.opentracks.data.tables.TracksColumns; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.util.FileUtils; /** @@ -406,18 +408,19 @@ public class CustomContentProviderUtilsTest { Pair> track = TestDataUtil.createTrack(trackId, 10); // AverageSpeed - SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); - statistics.setStartTime(Instant.ofEpochMilli(1000)); - statistics.setStopTime(Instant.ofEpochMilli(2500)); - statistics.setTotalTime(Duration.ofMillis(1500)); - statistics.setMovingTime(Duration.ofMillis(700)); - statistics.setTotalDistance(Distance.of(750.0)); - statistics.setTotalAltitudeGain(50.0f); - statistics.setMaxSpeed(Speed.of(60.0)); - statistics.setMaxAltitude(1250.0); - statistics.setMinAltitude(1200.0); - - track.first.setTrackStatistics(statistics); + track.first.setStatistics(new Statistics( + Instant.ofEpochMilli(1000), + Instant.ofEpochMilli(2500), + Duration.ofMillis(1500), + Duration.ofMillis(700), + Distance.of(750), + false, + Speed.of(60), + new AltitudeExtremities(1250, 1200), + new AltitudeGainLoss(50, 50), + null, + null + )); contentProviderUtils.insertTrack(track.first); Marker marker = new Marker(trackId, track.second.get(0)); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java index 97a03e161..8c01dfe80 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java @@ -16,25 +16,20 @@ import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import de.dennisguse.opentracks.data.models.Altitude; import de.dennisguse.opentracks.data.models.Distance; +import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; @RunWith(MockitoJUnitRunner.class) public class TrackRecordingServiceNotificationManagerTest { private final Context context = ApplicationProvider.getApplicationContext(); - @Mock - private TrackPoint trackPointMock; //TODO No mock - - @Mock - private SegmentStatisticUpdater trackStatisticsMock; //TODO only use Statistic (not mock) - @Mock private NotificationCompat.Builder notificationCompatBuilder; @@ -43,10 +38,22 @@ public class TrackRecordingServiceNotificationManagerTest { @Test public void updateLocation_triggersAlertOnlyOnFirstInaccurateLocation() { - when(trackPointMock.hasHorizontalAccuracy()).thenReturn(true); - when(trackPointMock.getHorizontalAccuracy()).thenReturn(Distance.of(999f)); - when(trackPointMock.getSpeed()).thenReturn(Speed.of(0)); - when(trackStatisticsMock.getStatistics()).thenReturn(new Statistics( + TrackPoint trackPointMock = new TrackPoint(TrackPoint.Type.TRACKPOINT, + new Position( + null, + null, null, Distance.of(999f), + Altitude.WGS84.of(10), null, + null, + Speed.of(0)) + ); + + when(notificationCompatBuilder.setOnlyAlertOnce(anyBoolean())) + .thenReturn(notificationCompatBuilder); + + TrackRecordingServiceNotificationManager subject = new TrackRecordingServiceNotificationManager(notificationManager, notificationCompatBuilder); + subject.setUnitSystem(UnitSystem.METRIC); + + Track track = new Track(new Statistics( null, null, null, @@ -59,14 +66,6 @@ public class TrackRecordingServiceNotificationManagerTest { null, null )); - when(notificationCompatBuilder.setOnlyAlertOnce(anyBoolean())) - .thenReturn(notificationCompatBuilder); - - TrackRecordingServiceNotificationManager subject = new TrackRecordingServiceNotificationManager(notificationManager, notificationCompatBuilder); - subject.setUnitSystem(UnitSystem.METRIC); - - Track track = new Track(); - track.setTrackStatistics(trackStatisticsMock); RecordingData data = new RecordingData(track, trackPointMock, null, null); // when diff --git a/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java b/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java index df92ea7ad..fc98b5b13 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java @@ -18,8 +18,6 @@ package de.dennisguse.opentracks.share; import static org.junit.Assert.assertEquals; -import android.content.Context; - import androidx.test.core.app.ApplicationProvider; import androidx.test.ext.junit.runners.AndroidJUnit4; @@ -36,10 +34,12 @@ import java.util.Locale; import de.dennisguse.opentracks.LocaleRule; import de.dennisguse.opentracks.R; +import de.dennisguse.opentracks.data.models.AltitudeExtremities; +import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.util.StringUtils; /** @@ -56,8 +56,6 @@ public class TrackShareSummaryGeneratorTest { private static final Instant START_TIME = Instant.ofEpochMilli(1288721514000L); private TrackShareSummaryGenerator descriptionGenerator; - private final Context context = ApplicationProvider.getApplicationContext(); - @Before public void setUp() { descriptionGenerator = new TrackShareSummaryGenerator(ApplicationProvider.getApplicationContext()); @@ -65,19 +63,21 @@ public class TrackShareSummaryGeneratorTest { @Test public void testGenerateTrackDescription() { - Track track = new Track(); - SegmentStatisticUpdater stats = new SegmentStatisticUpdater(); - stats.setTotalDistance(Distance.of(20000)); - stats.setTotalTime(Duration.ofMillis(600000)); - stats.setMovingTime(Duration.ofMillis(300000)); - stats.setMaxSpeed(Speed.of(100)); - stats.setMaxAltitude(550); - stats.setMinAltitude(-500); - stats.setTotalAltitudeGain(6000f); - stats.setTotalAltitudeLoss(6000f); - stats.setStartTime(START_TIME); - track.setTrackStatistics(stats); + Track track = new Track(new Statistics( + START_TIME, + START_TIME, + Duration.ofSeconds(600), + Duration.ofSeconds(300), + Distance.of(20000), + false, + Speed.of(100), + new AltitudeExtremities(-500, 550), + new AltitudeGainLoss(6000, 6000), + null, + null + )); track.setActivityTypeLocalized("hiking"); + String expected = //"Created by" "OpenTracks (Debug)\n\n" + "Name: -\n" diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java index 463d7cc3c..b49fa24d2 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java @@ -17,8 +17,11 @@ import java.util.List; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.models.ActivityType; +import de.dennisguse.opentracks.data.models.AltitudeExtremities; +import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Speed; +import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; @@ -28,21 +31,21 @@ public class AggregatedStatisticsTest { private final Context context = ApplicationProvider.getApplicationContext(); private static Track createTrack(Context context, Distance totalDistance, Duration totalTime, String activityTypeLocalized) { - SegmentStatisticUpdater statistics = new SegmentStatisticUpdater(); - statistics.setStartTime(Instant.ofEpochMilli(1000L)); // Resulting start time - statistics.setStopTime(statistics.getStartTime().plus(totalTime)); - statistics.setTotalTime(totalTime); - statistics.setMovingTime(totalTime); - statistics.setTotalDistance(totalDistance); - statistics.setTotalAltitudeGain(50.0f); - statistics.setMaxSpeed(Speed.of(50.0)); // Resulting max speed - statistics.setMaxAltitude(1250.0); - statistics.setMinAltitude(1200.0); // Resulting min altitude - - Track track = new Track(); + Track track = new Track(new Statistics( + Instant.ofEpochMilli(1000), + Instant.ofEpochMilli(1000).plus(totalTime), + totalTime, + totalTime, + totalDistance, + false, + Speed.of(50), + new AltitudeExtremities(1250, 1250), + new AltitudeGainLoss(50, 50), + null, + null + )); track.setActivityType(ActivityType.findByLocalizedString(context, activityTypeLocalized)); track.setActivityTypeLocalized(activityTypeLocalized); - track.setTrackStatistics(statistics); return track; } diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Track.java b/src/main/java/de/dennisguse/opentracks/data/models/Track.java index c20d6916d..55b36b43f 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Track.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Track.java @@ -158,11 +158,6 @@ public class Track { this.trackStatistics = trackStatistics; } - @Deprecated - public void setTrackStatistics(@NonNull SegmentStatisticUpdater trackStatistics) { - setStatistics(trackStatistics.getStatistics()); - } - @NonNull @Override public String toString() { From 11f1b6e72df80c42ecc7463b8143e1857ed4d4bb Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Wed, 29 Oct 2025 21:51:59 +0100 Subject: [PATCH 19/30] Cleanup: TrackPointIterator is now package private. --- .../opentracks/content/data/TestDataUtil.java | 4 ++-- .../data/CustomContentProviderUtilsTest.java | 7 ++++--- .../VoiceAnnouncementUtilsTest.java | 20 +++++++------------ .../opentracks/data/ContentProviderUtils.java | 3 ++- .../opentracks/data/TrackDataHub.java | 3 ++- .../opentracks/data/TrackPointIterator.java | 6 +++--- .../io/file/exporter/CSVTrackExporter.java | 4 ++-- .../io/file/exporter/GPXTrackExporter.java | 4 ++-- .../io/file/exporter/KMLTrackExporter.java | 4 ++-- .../VoiceAnnouncementManager.java | 5 +++-- .../ui/intervals/IntervalStatisticsModel.java | 4 ++-- .../util/AutoCloseableIterator.java | 11 ++++++++++ 12 files changed, 42 insertions(+), 33 deletions(-) create mode 100644 src/main/java/de/dennisguse/opentracks/util/AutoCloseableIterator.java diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java index 870978911..04685d957 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java @@ -11,7 +11,6 @@ import java.util.ArrayList; import java.util.List; import de.dennisguse.opentracks.data.ContentProviderUtils; -import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Altitude; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Marker; @@ -20,6 +19,7 @@ import de.dennisguse.opentracks.data.models.Speed; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.ui.markers.MarkerUtils; +import de.dennisguse.opentracks.util.AutoCloseableIterator; import de.dennisguse.opentracks.util.FileUtils; public class TestDataUtil { @@ -150,7 +150,7 @@ public class TestDataUtil { } public static List getTrackPoints(ContentProviderUtils contentProviderUtils, Track.Id trackId) { - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { ArrayList trackPoints = new ArrayList<>(); while (trackPointIterator.hasNext()) { trackPoints.add(trackPointIterator.next()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java index 93ec4e9a4..c0948bcab 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java @@ -65,6 +65,7 @@ import de.dennisguse.opentracks.data.tables.MarkerColumns; import de.dennisguse.opentracks.data.tables.TrackPointsColumns; import de.dennisguse.opentracks.data.tables.TracksColumns; import de.dennisguse.opentracks.stats.SensorStatistics; +import de.dennisguse.opentracks.util.AutoCloseableIterator; import de.dennisguse.opentracks.util.FileUtils; /** @@ -116,7 +117,7 @@ public class CustomContentProviderUtilsTest { private void testIterator(Track.Id trackId, int numPoints) { TrackPoint.Id lastPointId = initializeTrack(trackId, numPoints); List locations = new ArrayList<>(numPoints); - try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { + try (AutoCloseableIterator it = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { while (it.hasNext()) { TrackPoint trackPoint = it.next(); assertNotNull(trackPoint); @@ -154,7 +155,7 @@ public class CustomContentProviderUtilsTest { // Load all inserted trackPoints. TrackPoint.Id lastPointId = null; int counter = 0; - try (TrackPointIterator it = contentProviderUtils.getTrackPointLocationIterator(id, null)) { + try (AutoCloseableIterator it = contentProviderUtils.getTrackPointLocationIterator(id, null)) { while (it.hasNext()) { TrackPoint trackPoint = it.next(); lastPointId = trackPoint.getId(); @@ -857,7 +858,7 @@ public class CustomContentProviderUtilsTest { TrackPoint.Id startTrackPointId = trackpointIds.get(0); // when - TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, trackpointIds.get(0)); + AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, trackpointIds.get(0)); // then for (int i = 0; i < trackpointIds.size(); i++) { diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java index fca43146e..de42c5e38 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java @@ -25,7 +25,6 @@ import java.util.Map; import de.dennisguse.opentracks.LocaleRule; import de.dennisguse.opentracks.content.data.TestDataUtil; import de.dennisguse.opentracks.data.ContentProviderUtils; -import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; @@ -40,6 +39,7 @@ import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.SensorStatistics; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; import de.dennisguse.opentracks.ui.intervals.IntervalStatisticsUpdater; +import de.dennisguse.opentracks.util.AutoCloseableIterator; @RunWith(AndroidJUnit4.class) public class VoiceAnnouncementUtilsTest { @@ -180,8 +180,7 @@ public class VoiceAnnouncementUtilsTest { Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - assertEquals(numberOfPoints, trackPointIterator.getCount()); + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); @@ -233,8 +232,7 @@ public class VoiceAnnouncementUtilsTest { Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - assertEquals(numberOfPoints, trackPointIterator.getCount()); + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); @@ -364,8 +362,7 @@ public class VoiceAnnouncementUtilsTest { Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - assertEquals(numberOfPoints, trackPointIterator.getCount()); + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); @@ -417,8 +414,7 @@ public class VoiceAnnouncementUtilsTest { Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - assertEquals(numberOfPoints, trackPointIterator.getCount()); + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); @@ -446,8 +442,7 @@ public class VoiceAnnouncementUtilsTest { Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - assertEquals(numberOfPoints, trackPointIterator.getCount()); + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); @@ -483,8 +478,7 @@ public class VoiceAnnouncementUtilsTest { Track.Id trackId = trackWithStats.first; SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - assertEquals(numberOfPoints, trackPointIterator.getCount()); + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); intervalStatistics.addTrackPoints(trackPointIterator); lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index c7d790ef7..5d0fc424b 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -58,6 +58,7 @@ import de.dennisguse.opentracks.data.tables.TrackPointsColumns; import de.dennisguse.opentracks.data.tables.TracksColumns; import de.dennisguse.opentracks.stats.SensorStatistics; import de.dennisguse.opentracks.ui.markers.MarkerUtils; +import de.dennisguse.opentracks.util.AutoCloseableIterator; import de.dennisguse.opentracks.util.FileUtils; /** @@ -831,7 +832,7 @@ public class ContentProviderUtils { * @param trackId the track id * @param startTrackPointId the starting trackPoint id. `null` to ignore */ - public TrackPointIterator getTrackPointLocationIterator(final Track.Id trackId, final TrackPoint.Id startTrackPointId) { + public AutoCloseableIterator getTrackPointLocationIterator(final Track.Id trackId, final TrackPoint.Id startTrackPointId) { return new TrackPointIterator(this, trackId, startTrackPointId); } diff --git a/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java b/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java index b5d9c867e..db169f62b 100644 --- a/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java +++ b/src/main/java/de/dennisguse/opentracks/data/TrackDataHub.java @@ -42,6 +42,7 @@ import de.dennisguse.opentracks.services.RecordingStatus; import de.dennisguse.opentracks.services.TrackRecordingService; import de.dennisguse.opentracks.services.handlers.AltitudeCorrectionManager; import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; +import de.dennisguse.opentracks.util.AutoCloseableIterator; /** * Track data hub. @@ -330,7 +331,7 @@ public class TrackDataHub { } TrackPoint trackPoint = null; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(selectedTrackId, next)) { + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(selectedTrackId, next)) { while (trackPointIterator.hasNext()) { //Prevents a NPE if stop() is happening while notifyTrackPointsTableUpdate() diff --git a/src/main/java/de/dennisguse/opentracks/data/TrackPointIterator.java b/src/main/java/de/dennisguse/opentracks/data/TrackPointIterator.java index ecd5da7cb..b7f648bd4 100644 --- a/src/main/java/de/dennisguse/opentracks/data/TrackPointIterator.java +++ b/src/main/java/de/dennisguse/opentracks/data/TrackPointIterator.java @@ -5,16 +5,16 @@ import android.database.Cursor; import androidx.annotation.NonNull; import androidx.annotation.VisibleForTesting; -import java.util.Iterator; import java.util.NoSuchElementException; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; +import de.dennisguse.opentracks.util.AutoCloseableIterator; /** * A lightweight wrapper around the original {@link Cursor}. */ -public class TrackPointIterator implements Iterator, AutoCloseable { +class TrackPointIterator extends AutoCloseableIterator { private static final String TAG = TrackPointIterator.class.getSimpleName(); @@ -23,7 +23,7 @@ public class TrackPointIterator implements Iterator, AutoCloseable { private final CachedTrackPointsIndexes indexes; private Cursor cursor; - public TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, TrackPoint.Id startTrackPointId) { + TrackPointIterator(ContentProviderUtils contentProviderUtils, Track.Id trackId, TrackPoint.Id startTrackPointId) { this.contentProviderUtils = contentProviderUtils; this.trackId = trackId; diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/CSVTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/CSVTrackExporter.java index 8f086c51a..ab5da9ac9 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/CSVTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/CSVTrackExporter.java @@ -28,10 +28,10 @@ import java.util.Locale; import java.util.function.Function; import de.dennisguse.opentracks.data.ContentProviderUtils; -import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; +import de.dennisguse.opentracks.util.AutoCloseableIterator; import de.dennisguse.opentracks.util.StringUtils; /** @@ -131,7 +131,7 @@ public class CSVTrackExporter implements TrackExporter { } private void writeTrackPoints(List columns, Track track) throws InterruptedException { - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), null)) { + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), null)) { while (trackPointIterator.hasNext()) { if (Thread.interrupted()) throw new InterruptedException(); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java index 9df2a08a0..71e2c0eac 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java @@ -33,13 +33,13 @@ import java.util.function.Function; import java.util.stream.Stream; import de.dennisguse.opentracks.data.ContentProviderUtils; -import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; +import de.dennisguse.opentracks.util.AutoCloseableIterator; import de.dennisguse.opentracks.util.StringUtils; /** @@ -128,7 +128,7 @@ public class GPXTrackExporter implements TrackExporter { LinkedList sensorPoints = new LinkedList<>(); - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), null)) { + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), null)) { while (trackPointIterator.hasNext()) { if (Thread.interrupted()) throw new InterruptedException(); diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java index 445b4bb18..cb71f304c 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java @@ -36,13 +36,13 @@ import java.util.Objects; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.ContentProviderUtils; -import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.ActivityType; import de.dennisguse.opentracks.data.models.Marker; import de.dennisguse.opentracks.data.models.Position; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.ui.markers.MarkerUtils; +import de.dennisguse.opentracks.util.AutoCloseableIterator; import de.dennisguse.opentracks.util.StringUtils; /** @@ -162,7 +162,7 @@ public class KMLTrackExporter implements TrackExporter { boolean wroteTrack = false; boolean wroteSegment = false; - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), null)) { + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), null)) { while (trackPointIterator.hasNext()) { if (Thread.interrupted()) throw new InterruptedException(); diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java index 99bd7e64b..0787134b5 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java @@ -30,7 +30,6 @@ import java.util.List; import de.dennisguse.opentracks.R; import de.dennisguse.opentracks.data.ContentProviderUtils; -import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Statistics; import de.dennisguse.opentracks.data.models.Track; @@ -39,6 +38,7 @@ import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.stats.SensorStatistics; import de.dennisguse.opentracks.ui.intervals.IntervalStatisticsUpdater; +import de.dennisguse.opentracks.util.AutoCloseableIterator; /** * Execute a periodic task on a time or distance schedule. @@ -149,7 +149,8 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe startTrackPointId = null; } - TrackPointIterator trackPointIterator = new TrackPointIterator(contentProviderUtils, track.getId(), startTrackPointId); + //TODO wrap in try {} + AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), startTrackPointId); startTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator); IntervalStatisticsUpdater.Interval lastInterval = intervalStatistics.getLastInterval(); SensorStatistics sensorStatistics = null; diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java index 5c1d32395..a0b8399c7 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsModel.java @@ -17,12 +17,12 @@ import java.util.concurrent.Executor; import java.util.concurrent.Executors; import de.dennisguse.opentracks.data.ContentProviderUtils; -import de.dennisguse.opentracks.data.TrackPointIterator; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.Track; import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.data.tables.TrackPointsColumns; import de.dennisguse.opentracks.settings.UnitSystem; +import de.dennisguse.opentracks.util.AutoCloseableIterator; /** * This model is used to load intervals for a track. @@ -92,7 +92,7 @@ public class IntervalStatisticsModel extends AndroidViewModel { private void loadIntervalStatistics(Track.Id trackId) { executor.execute(() -> { ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getApplication()); - try (TrackPointIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, lastTrackPointId)) { + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, lastTrackPointId)) { lastTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator); intervalsLiveData.postValue(intervalStatistics.getIntervalList()); } diff --git a/src/main/java/de/dennisguse/opentracks/util/AutoCloseableIterator.java b/src/main/java/de/dennisguse/opentracks/util/AutoCloseableIterator.java new file mode 100644 index 000000000..ab145f9f5 --- /dev/null +++ b/src/main/java/de/dennisguse/opentracks/util/AutoCloseableIterator.java @@ -0,0 +1,11 @@ +package de.dennisguse.opentracks.util; + +import java.util.Iterator; + +public abstract class AutoCloseableIterator implements Iterator, AutoCloseable { + + /** + * Override: AutoClosable.close() throws Exception. + */ + public abstract void close(); +} From 58655814b2791d7b053094f819b29047a91443bf Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Wed, 29 Oct 2025 21:57:22 +0100 Subject: [PATCH 20/30] VoiceAnnouncementManager should close TrackPointIterator to avoid memory leaks. --- .../announcement/VoiceAnnouncementManager.java | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java index 0787134b5..d48f55c9a 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java @@ -149,16 +149,16 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe startTrackPointId = null; } - //TODO wrap in try {} - AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), startTrackPointId); - startTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator); - IntervalStatisticsUpdater.Interval lastInterval = intervalStatistics.getLastInterval(); - SensorStatistics sensorStatistics = null; - if (track.getId() != null) { - sensorStatistics = contentProviderUtils.getSensorStats(track.getId()); - } + try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(track.getId(), startTrackPointId)) { + startTrackPointId = intervalStatistics.addTrackPoints(trackPointIterator); + IntervalStatisticsUpdater.Interval lastInterval = intervalStatistics.getLastInterval(); + SensorStatistics sensorStatistics = null; + if (track.getId() != null) { + sensorStatistics = contentProviderUtils.getSensorStats(track.getId()); + } - return VoiceAnnouncementUtils.createStatistics(context, track, sensorDataSet, PreferencesUtils.getUnitSystem(), PreferencesUtils.isReportSpeed(track), lastInterval, sensorStatistics); + return VoiceAnnouncementUtils.createStatistics(context, track, sensorDataSet, PreferencesUtils.getUnitSystem(), PreferencesUtils.isReportSpeed(track), lastInterval, sensorStatistics); + } } public void stop() { From 5988ae3d3f63b35ea52118c8cbc665ca22ba66b2 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Thu, 30 Oct 2025 21:30:01 +0100 Subject: [PATCH 21/30] VoiceAnnouncementUtilsTest do not use SegmentStatisticsUpdater. --- .../VoiceAnnouncementUtilsTest.java | 76 ++++++++++++++++--- .../IntervalStatisticsUpdaterTest.java | 5 +- 2 files changed, 68 insertions(+), 13 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java index de42c5e38..48a4ab403 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java @@ -178,7 +178,6 @@ public class VoiceAnnouncementUtilsTest { int numberOfPoints = 1000; Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); @@ -189,7 +188,19 @@ public class VoiceAnnouncementUtilsTest { SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); - Track track = new Track(stats.getStatistics()); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH.plusSeconds(999), + Duration.ofMinutes(16).plusSeconds(39), + Duration.ofMinutes(16).plusSeconds(39), + Distance.of(14208), + false, + Speed.of(104), + null, + null, + null, + null + )); // when String announcement = VoiceAnnouncementUtils.createStatistics(context, track, dataSet, UnitSystem.METRIC, true, lastInterval, null).toString(); @@ -230,7 +241,6 @@ public class VoiceAnnouncementUtilsTest { int numberOfPoints = 1000; Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); @@ -238,7 +248,19 @@ public class VoiceAnnouncementUtilsTest { lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } - Track track = new Track(stats.getStatistics()); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH.plusSeconds(999), + Duration.ofMinutes(16).plusSeconds(39), + Duration.ofMinutes(16).plusSeconds(39), + Distance.of(14208), + false, + Speed.of(104), + null, + null, + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -360,7 +382,6 @@ public class VoiceAnnouncementUtilsTest { int numberOfPoints = 1000; Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); @@ -368,7 +389,19 @@ public class VoiceAnnouncementUtilsTest { lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } - Track track = new Track(stats.getStatistics()); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH.plusSeconds(999), + Duration.ofMinutes(16).plusSeconds(39), + Duration.ofMinutes(16).plusSeconds(39), + Distance.of(14208), + false, + Speed.of(104), + null, + null, + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -412,7 +445,6 @@ public class VoiceAnnouncementUtilsTest { int numberOfPoints = 1000; Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); @@ -420,7 +452,19 @@ public class VoiceAnnouncementUtilsTest { lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); } - Track track = new Track(stats.getStatistics()); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH.plusSeconds(999), + Duration.ofMinutes(16).plusSeconds(39), + Duration.ofMinutes(16).plusSeconds(39), + Distance.of(14208), + false, + Speed.of(104), + null, + null, + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -476,7 +520,6 @@ public class VoiceAnnouncementUtilsTest { int numberOfPoints = 1000; Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); Track.Id trackId = trackWithStats.first; - SegmentStatisticUpdater stats = trackWithStats.second; IntervalStatisticsUpdater.Interval lastInterval; try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); @@ -486,7 +529,19 @@ public class VoiceAnnouncementUtilsTest { SensorStatistics sensorStatistics = new SensorStatistics(HeartRate.of(180f), HeartRate.of(180f), null, null, null, null); - Track track = new Track(stats.getStatistics()); + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH.plusSeconds(999), + Duration.ofMinutes(16).plusSeconds(39), + Duration.ofMinutes(16).plusSeconds(39), + Distance.of(14208), + false, + Speed.of(104), + null, + null, + null, + null + )); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); @@ -513,6 +568,7 @@ public class VoiceAnnouncementUtilsTest { assertEquals("1.2 miles", MessageFormat.format(template, Map.of("n", 1.18))); } + @Deprecated public static Pair buildTrackWithTrackPoints(ContentProviderUtils contentProviderUtils, int numberOfPoints) { Track dummyTrack = new Track(); dummyTrack.setId(new Track.Id(System.currentTimeMillis())); diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java index 8006aeb79..fc89ea127 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java @@ -171,7 +171,6 @@ public class IntervalStatisticsUpdaterTest { } private static Pair> buildTrackWithTrackPoints(int numberOfPoints) { - Track dummyTrack = new Track(); TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); ArrayList trackPoints = new ArrayList<>(); @@ -179,7 +178,7 @@ public class IntervalStatisticsUpdaterTest { trackPoints.add(TestDataUtil.createTrackPoint(i)); } trackStatisticsUpdater.addTrackPoints(trackPoints); - dummyTrack.setStatistics(trackStatisticsUpdater.getTrackStatistics()); - return new Pair<>(dummyTrack, trackPoints); + + return new Pair<>(new Track(trackStatisticsUpdater.getTrackStatistics()), trackPoints); } } \ No newline at end of file From 73ce97a63e1193a63dab78979b50207c23a4cec7 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Thu, 30 Oct 2025 21:37:26 +0100 Subject: [PATCH 22/30] VoiceAnnouncementUtilsTest do not store data. --- .../VoiceAnnouncementUtilsTest.java | 195 ++++-------------- 1 file changed, 41 insertions(+), 154 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java index 48a4ab403..444a69431 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java @@ -19,12 +19,12 @@ import org.mockito.Mockito; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.Locale; import java.util.Map; import de.dennisguse.opentracks.LocaleRule; import de.dennisguse.opentracks.content.data.TestDataUtil; -import de.dennisguse.opentracks.data.ContentProviderUtils; import de.dennisguse.opentracks.data.models.AltitudeGainLoss; import de.dennisguse.opentracks.data.models.Distance; import de.dennisguse.opentracks.data.models.HeartRate; @@ -35,11 +35,8 @@ import de.dennisguse.opentracks.data.models.TrackPoint; import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.settings.UnitSystem; -import de.dennisguse.opentracks.stats.SegmentStatisticUpdater; import de.dennisguse.opentracks.stats.SensorStatistics; -import de.dennisguse.opentracks.stats.TrackStatisticsUpdater; import de.dennisguse.opentracks.ui.intervals.IntervalStatisticsUpdater; -import de.dennisguse.opentracks.util.AutoCloseableIterator; @RunWith(AndroidJUnit4.class) public class VoiceAnnouncementUtilsTest { @@ -48,12 +45,9 @@ public class VoiceAnnouncementUtilsTest { public final LocaleRule mLocaleRule = new LocaleRule(Locale.ENGLISH); private final Context context = ApplicationProvider.getApplicationContext(); - private ContentProviderUtils contentProviderUtils; @Before public void setUp() { - contentProviderUtils = new ContentProviderUtils(context); - PreferencesUtils.setVoiceAnnounceHeartRateCurrent(false); PreferencesUtils.setVoiceAnnounceLapHeartRate(false); PreferencesUtils.setVoiceAnnounceAverageHeartRate(false); @@ -175,35 +169,13 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_withInterval_metric_speed() { // given - int numberOfPoints = 1000; - Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); - Track.Id trackId = trackWithStats.first; - IntervalStatisticsUpdater.Interval lastInterval; - try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); - intervalStatistics.addTrackPoints(trackPointIterator); - lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); - } - + Pair data = buildTrackWithTrackPoints(); + SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); - Track track = new Track(new Statistics( - Instant.EPOCH, - Instant.EPOCH.plusSeconds(999), - Duration.ofMinutes(16).plusSeconds(39), - Duration.ofMinutes(16).plusSeconds(39), - Distance.of(14208), - false, - Speed.of(104), - null, - null, - null, - null - )); - // when - String announcement = VoiceAnnouncementUtils.createStatistics(context, track, dataSet, UnitSystem.METRIC, true, lastInterval, null).toString(); + String announcement = VoiceAnnouncementUtils.createStatistics(context, data.first, dataSet, UnitSystem.METRIC, true, data.second, null).toString(); // then assertEquals("12:16 AM. Total distance 14.2 kilometers. 16 minutes 39 seconds. Average moving speed 51.2 kilometers per hour. Lap speed 51.2 kilometers per hour.", announcement); @@ -238,35 +210,13 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_withInterval_metric_pace() { // given - int numberOfPoints = 1000; - Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); - Track.Id trackId = trackWithStats.first; - IntervalStatisticsUpdater.Interval lastInterval; - try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); - intervalStatistics.addTrackPoints(trackPointIterator); - lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); - } - - Track track = new Track(new Statistics( - Instant.EPOCH, - Instant.EPOCH.plusSeconds(999), - Duration.ofMinutes(16).plusSeconds(39), - Duration.ofMinutes(16).plusSeconds(39), - Distance.of(14208), - false, - Speed.of(104), - null, - null, - null, - null - )); + Pair data = buildTrackWithTrackPoints(); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); // when - String announcement = VoiceAnnouncementUtils.createStatistics(context, track, dataSet, UnitSystem.METRIC, false, lastInterval, null).toString(); + String announcement = VoiceAnnouncementUtils.createStatistics(context, data.first, dataSet, UnitSystem.METRIC, false, data.second, null).toString(); // then assertEquals("12:16 AM. Total distance 14.2 kilometers. 16 minutes 39 seconds. Pace 1 minute 10 seconds per kilometer. Lap time 1 minute 10 seconds per kilometer.", announcement); @@ -379,35 +329,13 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_withInterval_imperial_speed() { // given - int numberOfPoints = 1000; - Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); - Track.Id trackId = trackWithStats.first; - IntervalStatisticsUpdater.Interval lastInterval; - try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); - intervalStatistics.addTrackPoints(trackPointIterator); - lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); - } - - Track track = new Track(new Statistics( - Instant.EPOCH, - Instant.EPOCH.plusSeconds(999), - Duration.ofMinutes(16).plusSeconds(39), - Duration.ofMinutes(16).plusSeconds(39), - Distance.of(14208), - false, - Speed.of(104), - null, - null, - null, - null - )); + Pair data = buildTrackWithTrackPoints(); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); // when - String announcement = VoiceAnnouncementUtils.createStatistics(context, track, dataSet, UnitSystem.IMPERIAL_FEET, true, lastInterval, null).toString(); + String announcement = VoiceAnnouncementUtils.createStatistics(context, data.first, dataSet, UnitSystem.IMPERIAL_FEET, true, data.second, null).toString(); // then assertEquals("12:16 AM. Total distance 8.8 miles. 16 minutes 39 seconds. Average moving speed 31.8 miles per hour. Lap speed 31.8 miles per hour.", announcement); @@ -442,35 +370,13 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_withInterval_imperial_pace() { // given - int numberOfPoints = 1000; - Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); - Track.Id trackId = trackWithStats.first; - IntervalStatisticsUpdater.Interval lastInterval; - try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); - intervalStatistics.addTrackPoints(trackPointIterator); - lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); - } - - Track track = new Track(new Statistics( - Instant.EPOCH, - Instant.EPOCH.plusSeconds(999), - Duration.ofMinutes(16).plusSeconds(39), - Duration.ofMinutes(16).plusSeconds(39), - Distance.of(14208), - false, - Speed.of(104), - null, - null, - null, - null - )); + Pair data = buildTrackWithTrackPoints(); SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); // when - String announcement = VoiceAnnouncementUtils.createStatistics(context, track, dataSet, UnitSystem.IMPERIAL_FEET, false, lastInterval, null).toString(); + String announcement = VoiceAnnouncementUtils.createStatistics(context, data.first, dataSet, UnitSystem.IMPERIAL_FEET, false, data.second, null).toString(); // then assertEquals("12:16 AM. Total distance 8.8 miles. 16 minutes 39 seconds. Pace 1 minute 53 seconds per mile. Lap time 1 minute 53 seconds per mile.", announcement); @@ -478,29 +384,19 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_heart_rate_and_sensor_statistics() { + // given PreferencesUtils.setVoiceAnnounceAverageHeartRate(true); PreferencesUtils.setVoiceAnnounceLapHeartRate(true); - int numberOfPoints = 1000; - Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); - Track.Id trackId = trackWithStats.first; - SegmentStatisticUpdater stats = trackWithStats.second; - IntervalStatisticsUpdater.Interval lastInterval; - try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); - intervalStatistics.addTrackPoints(trackPointIterator); - lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); - } + Pair data = buildTrackWithTrackPoints(); SensorStatistics sensorStatistics = new SensorStatistics(HeartRate.of(180f), HeartRate.of(180f), null, null, null, null); - Track track = new Track(stats.getStatistics()); - SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); // when - String announcement = VoiceAnnouncementUtils.createStatistics(context, track, dataSet, UnitSystem.METRIC, true, lastInterval, sensorStatistics).toString(); + String announcement = VoiceAnnouncementUtils.createStatistics(context, data.first, dataSet, UnitSystem.METRIC, true, data.second, sensorStatistics).toString(); // then assertEquals("12:16 AM. Total distance 14.2 kilometers. 16 minutes 39 seconds. Average moving speed 51.2 kilometers per hour. Lap speed 51.2 kilometers per hour. Average heart rate 180 bpm. Lap heart rate 133 bpm.", announcement); @@ -508,6 +404,7 @@ public class VoiceAnnouncementUtilsTest { @Test public void getAnnouncement_heart_rate() { + // given PreferencesUtils.setVoiceAnnounceHeartRateCurrent(true); PreferencesUtils.setVoiceAnnounceLapHeartRate(true); PreferencesUtils.setVoiceAnnounceAverageHeartRate(true); @@ -517,37 +414,15 @@ public class VoiceAnnouncementUtilsTest { PreferencesUtils.setVoiceAnnounceAverageSpeedPace(false); PreferencesUtils.setVoiceAnnounceLapSpeedPace(false); - int numberOfPoints = 1000; - Pair trackWithStats = buildTrackWithTrackPoints(contentProviderUtils, numberOfPoints); - Track.Id trackId = trackWithStats.first; - IntervalStatisticsUpdater.Interval lastInterval; - try (AutoCloseableIterator trackPointIterator = contentProviderUtils.getTrackPointLocationIterator(trackId, null)) { - IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); - intervalStatistics.addTrackPoints(trackPointIterator); - lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); - } + Pair data = buildTrackWithTrackPoints(); SensorStatistics sensorStatistics = new SensorStatistics(HeartRate.of(180f), HeartRate.of(180f), null, null, null, null); - Track track = new Track(new Statistics( - Instant.EPOCH, - Instant.EPOCH.plusSeconds(999), - Duration.ofMinutes(16).plusSeconds(39), - Duration.ofMinutes(16).plusSeconds(39), - Distance.of(14208), - false, - Speed.of(104), - null, - null, - null, - null - )); - SensorDataSet dataSet = Mockito.mock(SensorDataSet.class); Mockito.when(dataSet.getHeartRate()).thenReturn(new Pair<>(HeartRate.of(60), "unused")); // when - String announcement = VoiceAnnouncementUtils.createStatistics(context, track, dataSet, UnitSystem.METRIC, true, lastInterval, sensorStatistics).toString(); + String announcement = VoiceAnnouncementUtils.createStatistics(context, data.first, dataSet, UnitSystem.METRIC, true, data.second, sensorStatistics).toString(); // then assertEquals("12:16 AM. Current heart rate 60 bpm. Average heart rate 180 bpm. Lap heart rate 133 bpm.", announcement); @@ -568,20 +443,32 @@ public class VoiceAnnouncementUtilsTest { assertEquals("1.2 miles", MessageFormat.format(template, Map.of("n", 1.18))); } - @Deprecated - public static Pair buildTrackWithTrackPoints(ContentProviderUtils contentProviderUtils, int numberOfPoints) { - Track dummyTrack = new Track(); - dummyTrack.setId(new Track.Id(System.currentTimeMillis())); - dummyTrack.setName("Dummy Track"); - contentProviderUtils.insertTrack(dummyTrack); - TrackStatisticsUpdater trackStatisticsUpdater = new TrackStatisticsUpdater(); + private static Pair buildTrackWithTrackPoints() { + int numberOfPoints = 1000; + + ArrayList trackPoints = new ArrayList<>(); for (int i = 0; i < numberOfPoints; i++) { - TrackPoint tp = TestDataUtil.createTrackPoint(i); - contentProviderUtils.insertTrackPoint(tp, dummyTrack.getId()); - trackStatisticsUpdater.addTrackPoint(tp); + trackPoints.add(TestDataUtil.createTrackPoint(i)); } - dummyTrack.setStatistics(trackStatisticsUpdater.getTrackStatistics()); - contentProviderUtils.updateTrack(dummyTrack); - return new Pair<>(dummyTrack.getId(), trackStatisticsUpdater.getSegmentStatisticUpdater()); + + IntervalStatisticsUpdater intervalStatistics = new IntervalStatisticsUpdater(Distance.of(1000)); + intervalStatistics.addTrackPoints(trackPoints.iterator()); + IntervalStatisticsUpdater.Interval lastInterval = intervalStatistics.getIntervalList().get(intervalStatistics.getIntervalList().size() - 1); + + Track track = new Track(new Statistics( + Instant.EPOCH, + Instant.EPOCH.plusSeconds(999), + Duration.ofMinutes(16).plusSeconds(39), + Duration.ofMinutes(16).plusSeconds(39), + Distance.of(14208), + false, + Speed.of(104), + null, + null, + null, + null + )); + + return new Pair<>(track, lastInterval); } } From 696939112a776f10b28a2ead0aa6c524259b9e8a Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Thu, 30 Oct 2025 21:52:00 +0100 Subject: [PATCH 23/30] Cleanup: Statistics doesn't need isIdle. isIdle is only used by SegmentStatisticsUpdater. --- .../opentracks/chart/ChartPointTest.java | 6 ++-- .../data/CustomContentProviderUtilsTest.java | 1 - .../io/file/TrackFilenameGenerator2Test.java | 2 +- .../io/file/TrackFilenameGeneratorTest.java | 2 +- ...cordingServiceNotificationManagerTest.java | 1 - .../TrackRecordingServiceRecordingTest.java | 30 +++++++++---------- .../VoiceAnnouncementUtilsTest.java | 11 ------- .../share/TrackShareSummaryGeneratorTest.java | 1 - .../AggregatedStatisticsTest.java | 1 - .../opentracks/data/ContentProviderUtils.java | 2 -- .../opentracks/data/models/Statistics.java | 2 +- .../io/file/TrackFilenameGenerator.java | 2 +- .../stats/SegmentStatisticUpdater.java | 3 +- .../SettingsCustomLayoutEditAdapter.java | 1 - 14 files changed, 23 insertions(+), 42 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java b/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java index 49cf43e58..47725fcb5 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/chart/ChartPointTest.java @@ -21,12 +21,12 @@ import de.dennisguse.opentracks.settings.UnitSystem; @RunWith(AndroidJUnit4.class) public class ChartPointTest { - private static final Statistics STATISTIC_NULL = new Statistics(null, null, Duration.ZERO, null, null, false, null, null, null, null, null); + private static final Statistics STATISTIC_NULL = new Statistics(null, null, Duration.ZERO, null, null, null, null, null, null, null); @Test public void create_by_time() { // given - Statistics statistics = new Statistics(null, null, Duration.ofSeconds(1000), null, null, false, null, null, null, null, null); + Statistics statistics = new Statistics(null, null, Duration.ofSeconds(1000), null, null, null, null, null, null, null); // when ChartPoint point = ChartPoint.create(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), false, UnitSystem.IMPERIAL_FEET); @@ -38,7 +38,7 @@ public class ChartPointTest { @Test public void create_by_distance() { // given - Statistics statistics = new Statistics(null, null, null, null, Distance.of(1000), false, null, null, null, null, null); + Statistics statistics = new Statistics(null, null, null, null, Distance.of(1000), null, null, null, null, null); // when ChartPoint point = ChartPoint.create(statistics, TrackStubUtils.createDefaultTrackPoint(), Speed.of(0), true, UnitSystem.METRIC); diff --git a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java index c0948bcab..ac16c0b62 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/data/CustomContentProviderUtilsTest.java @@ -415,7 +415,6 @@ public class CustomContentProviderUtilsTest { Duration.ofMillis(1500), Duration.ofMillis(700), Distance.of(750), - false, Speed.of(60), new AltitudeExtremities(1250, 1200), new AltitudeGainLoss(50, 50), diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator2Test.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator2Test.java index 9c86f1471..bf53c99bb 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator2Test.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator2Test.java @@ -37,7 +37,7 @@ public class TrackFilenameGenerator2Test { Track track = new Track(); track.setName("Best Track"); track.setUuid(UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6")); - track.setStatistics(new Statistics(Instant.parse("2020-02-02T02:02:02Z"), null, null, null, null, false, null, null, null, null, null)); + track.setStatistics(new Statistics(Instant.parse("2020-02-02T02:02:02Z"), null, null, null, null, null, null, null, null, null)); // when subject.format(track, TrackFileFormat.GPX); diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest.java index 0e014f107..84d675160 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/TrackFilenameGeneratorTest.java @@ -51,7 +51,7 @@ public class TrackFilenameGeneratorTest { Track track = new Track(); track.setName("Best Track"); track.setUuid(UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb")); - track.setStatistics(new Statistics(Instant.parse("2020-02-02T02:02:02Z"), null, null, null, null, false, null, null, null, null, null)); + track.setStatistics(new Statistics(Instant.parse("2020-02-02T02:02:02Z"), null, null, null, null, null, null, null, null, null)); // when String filename = subject.format(track, TrackFileFormat.GPX); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java index 8c01dfe80..c17bf9cf1 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManagerTest.java @@ -59,7 +59,6 @@ public class TrackRecordingServiceNotificationManagerTest { null, null, Distance.of(0), - false, null, null, null, diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java index 21ff4fb90..c78317116 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java @@ -107,7 +107,7 @@ public class TrackRecordingServiceRecordingTest { // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(startTime), Duration.ZERO, Duration.ZERO, Distance.of(0), false, Speed.zero(), new AltitudeExtremities(0.0, 0.0), null, null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(startTime), Duration.ZERO, Duration.ZERO, Distance.of(0), Speed.zero(), new AltitudeExtremities(0.0, 0.0), null, null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -121,7 +121,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.zero(), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), Speed.zero(), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -193,7 +193,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(pauseTime), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.zero(), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(pauseTime), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), Speed.zero(), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -209,7 +209,7 @@ public class TrackRecordingServiceRecordingTest { service.resumeTrack(trackId); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(resumeTime), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.zero(), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(resumeTime), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), Speed.zero(), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -342,7 +342,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps1), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps1), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -350,7 +350,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.0001, 35.0, 1, 15); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps2), Duration.ofSeconds(4), Duration.ofSeconds(4), Distance.of(11.113178253173828), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps2), Duration.ofSeconds(4), Duration.ofSeconds(4), Distance.of(11.113178253173828), Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -358,7 +358,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps3, 45.0002, 35.0, 1, 15); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps3), Duration.ofSeconds(6), Duration.ofSeconds(6), Distance.of(22.226356506347656), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps3), Duration.ofSeconds(6), Duration.ofSeconds(6), Distance.of(22.226356506347656), Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -367,7 +367,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(22.226356506347656), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(22.226356506347656), Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -420,7 +420,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - Statistics gps1Statistics = new Statistics(Instant.parse(startTime), Instant.parse(gps1), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null); + Statistics gps1Statistics = new Statistics(Instant.parse(startTime), Instant.parse(gps1), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null); assertEquals(gps1Statistics, contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -443,7 +443,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(2.222635507583618), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(2.222635507583618), Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); new TrackPointAssert().assertEquals(List.of( @@ -548,7 +548,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 100, 15); // then - Statistics startStatistics = new Statistics(Instant.parse(startTime), Instant.parse(startTime), Duration.ofSeconds(0), Duration.ofSeconds(0), Distance.of(0), false, Speed.of(0), new AltitudeExtremities(0.0, 0.0), null, null, null); + Statistics startStatistics = new Statistics(Instant.parse(startTime), Instant.parse(startTime), Duration.ofSeconds(0), Duration.ofSeconds(0), Distance.of(0), Speed.of(0), new AltitudeExtremities(0.0, 0.0), null, null, null); assertEquals(startStatistics, contentProviderUtils.getTrack(trackId).getStatistics()); @@ -566,7 +566,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(0), false, Speed.of(0), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(0), Speed.of(0), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); // then @@ -593,7 +593,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps1, 45.0, 35.0, 1, 15); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps1), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), false, Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps1), Duration.ofSeconds(1), Duration.ofSeconds(1), Distance.of(0), Speed.of(15), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -601,7 +601,7 @@ public class TrackRecordingServiceRecordingTest { TrackRecordingServiceTestUtils.sendGPSLocation(trackPointCreator, gps2, 45.1, 35.0, 1, 15); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps2), Duration.ofSeconds(4), Duration.ofSeconds(4), Distance.of(11113.275390625), false, Speed.of(2778.31884765625f), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(gps2), Duration.ofSeconds(4), Duration.ofSeconds(4), Distance.of(11113.275390625), Speed.of(2778.31884765625f), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); // when @@ -610,7 +610,7 @@ public class TrackRecordingServiceRecordingTest { service.endCurrentTrack(); // then - assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(11113.275390625), false, Speed.of(1111.3275146484375), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) + assertEquals(new Statistics(Instant.parse(startTime), Instant.parse(stopTime), Duration.ofSeconds(10), Duration.ofSeconds(10), Distance.of(11113.275390625), Speed.of(1111.3275146484375), new AltitudeExtremities(0.0, 0.0), new AltitudeGainLoss(0, 0), null, null) , contentProviderUtils.getTrack(trackId).getStatistics()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java index 444a69431..8717765f4 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementUtilsTest.java @@ -70,7 +70,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1).plusMinutes(5).plusSeconds(10), Distance.of(20000), - false, Speed.of(100), null, null, @@ -96,7 +95,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1).plusSeconds(1), Distance.of(20000), - false, Speed.of(100), null, new AltitudeGainLoss(6000, 6000), @@ -122,7 +120,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1), Distance.of(19999), - false, Speed.of(100), null, new AltitudeGainLoss(6000, 6000), @@ -148,7 +145,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1), Distance.of(19900), - false, Speed.of(100), null, new AltitudeGainLoss(6000, 6000), @@ -189,7 +185,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1).plusMinutes(5).plusSeconds(10), Distance.of(20000), - false, Speed.of(100), null, new AltitudeGainLoss(6000, 6000), @@ -230,7 +225,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1).plusMinutes(5).plusSeconds(10), Distance.of(20000), - false, Speed.of(100), null, new AltitudeGainLoss(6000, 6000), @@ -256,7 +250,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1), Distance.ofMile(1.1), - false, null, null, null, @@ -282,7 +275,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1), Distance.ofMile(1.1), - false, null, null, null, @@ -308,7 +300,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1), Distance.ofKilometer(1.1), - false, null, null, null, @@ -349,7 +340,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofHours(2).plusMinutes(5).plusSeconds(10), Duration.ofHours(1).plusMinutes(5).plusSeconds(10), Distance.of(20000), - false, Speed.of(100), null, new AltitudeGainLoss(6000, 6000), @@ -461,7 +451,6 @@ public class VoiceAnnouncementUtilsTest { Duration.ofMinutes(16).plusSeconds(39), Duration.ofMinutes(16).plusSeconds(39), Distance.of(14208), - false, Speed.of(104), null, null, diff --git a/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java b/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java index fc98b5b13..04ffbe816 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/share/TrackShareSummaryGeneratorTest.java @@ -69,7 +69,6 @@ public class TrackShareSummaryGeneratorTest { Duration.ofSeconds(600), Duration.ofSeconds(300), Distance.of(20000), - false, Speed.of(100), new AltitudeExtremities(-500, 550), new AltitudeGainLoss(6000, 6000), diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java index b49fa24d2..bc037d010 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/ui/aggregatedStatistics/AggregatedStatisticsTest.java @@ -37,7 +37,6 @@ public class AggregatedStatisticsTest { totalTime, totalTime, totalDistance, - false, Speed.of(50), new AltitudeExtremities(1250, 1250), new AltitudeGainLoss(50, 50), diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index 5d0fc424b..568c6b2ce 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -146,8 +146,6 @@ public class ContentProviderUtils { cursor.isNull(totalDistanceIndex) ? null : Distance.of(cursor.getFloat(totalDistanceIndex)), - false, - cursor.isNull(maxSpeedIndex) ? null : Speed.of(cursor.getFloat(maxSpeedIndex)), cursor.isNull(minAltitudeIndex) || cursor.isNull(maxAltitudeIndex) ? null : new AltitudeExtremities(cursor.getFloat(minAltitudeIndex), cursor.getFloat(maxAltitudeIndex)), cursor.isNull(altitudeGainIndex) || cursor.isNull(altitudeLossIndex) ? null : new AltitudeGainLoss(cursor.getFloat(altitudeGainIndex), cursor.getFloat(altitudeLossIndex)), diff --git a/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java b/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java index 9c6c28b70..4fd957c03 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/Statistics.java @@ -14,7 +14,7 @@ public record Statistics( Duration movingTime, // Based on when we believe the user is traveling Distance totalDistance, - boolean isIdle, //TODO Check if this is persisted; if not: remove + //TODO Check if this is persisted; if not: remove Speed maxSpeed, @Nullable diff --git a/src/main/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator.java b/src/main/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator.java index 06bda1c63..f9f761630 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/TrackFilenameGenerator.java @@ -92,7 +92,7 @@ public class TrackFilenameGenerator { Track track = new Track(); track.setName("Berlin"); track.setUuid(UUID.fromString("f81d4fae-7dec-11d0-a765-00a0c91e6bf6")); - track.setStatistics(new Statistics(Instant.MIN, null, null, null, null, false, null, null, null, null, null)); + track.setStatistics(new Statistics(Instant.MIN, null, null, null, null, null, null, null, null, null)); return format(track, TrackFileFormat.KMZ_WITH_TRACKDETAIL_AND_SENSORDATA_AND_PICTURES); } diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index fa7df7193..59becef9f 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -81,6 +81,7 @@ public class SegmentStatisticUpdater { */ public SegmentStatisticUpdater(SegmentStatisticUpdater other) { this(other.getStatistics()); + this.isIdle = other.isIdle(); } public SegmentStatisticUpdater(Statistics statistics) { @@ -99,7 +100,6 @@ public class SegmentStatisticUpdater { } avgHeartRate = statistics.avgHeartRate(); avgPower = statistics.avgPower(); - isIdle = statistics.isIdle(); } /** @@ -208,7 +208,6 @@ public class SegmentStatisticUpdater { movingTime, totalDistance, - isIdle, getMaxSpeed(), altitudeExtremities.hasData() ? new AltitudeExtremities(altitudeExtremities.getMin(), altitudeExtremities.getMax()) : null, totalAltitudeGain_m != null && totalAltitudeLoss_m != null ? new AltitudeGainLoss(totalAltitudeGain_m, totalAltitudeLoss_m) : null, diff --git a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java index a1a8f66ee..5f8dab3ca 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java +++ b/src/main/java/de/dennisguse/opentracks/ui/customRecordingLayout/SettingsCustomLayoutEditAdapter.java @@ -46,7 +46,6 @@ public class SettingsCustomLayoutEditAdapter extends RecyclerView.Adapter Date: Thu, 30 Oct 2025 22:33:00 +0100 Subject: [PATCH 24/30] Cleanup: TrackPoint uses AltitudeGainLoss. --- .../opentracks/content/data/TestDataUtil.java | 3 +- .../content/data/TestSensorDataUtil.java | 3 +- .../io/file/importer/ExportImportTest.java | 37 ++++------- .../file/importer/GPXTrackImporterTest.java | 15 ++--- .../file/importer/KMLTrackImporterTest.java | 16 ++--- .../io/file/importer/TrackPointAssert.java | 10 +-- .../TrackRecordingServiceRecordingTest.java | 63 +++++++------------ .../IntervalStatisticsUpdaterTest.java | 2 +- .../raw/legacy_kml22_statistics_marker.kml | 15 ----- .../opentracks/data/ContentProviderUtils.java | 16 ++--- .../opentracks/data/models/TrackPoint.java | 42 +++++-------- .../io/file/exporter/CSVTrackExporter.java | 4 +- .../io/file/exporter/GPXTrackExporter.java | 4 +- .../io/file/exporter/KMLTrackExporter.java | 10 ++- .../io/file/importer/GPXTrackImporter.java | 13 +--- .../io/file/importer/KMLTrackImporter.java | 9 ++- .../sensors/sensorData/SensorDataSet.java | 3 +- .../stats/SegmentStatisticUpdater.java | 31 ++++----- .../stats/TrackStatisticsUpdater.java | 8 +-- .../intervals/IntervalStatisticsUpdater.java | 8 +-- 20 files changed, 105 insertions(+), 207 deletions(-) diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java index 04685d957..4920899a2 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestDataUtil.java @@ -119,8 +119,7 @@ public class TestDataUtil { trackPoint.setHeartRate(100f + i % 80); trackPoint.setCadence(300f + i); trackPoint.setPower(400f + i); - trackPoint.setAltitudeGain(ALTITUDE_GAIN); - trackPoint.setAltitudeLoss(ALTITUDE_LOSS); + trackPoint.setAltitudeGainLoss(ALTITUDE_GAIN, ALTITUDE_LOSS); return trackPoint; } diff --git a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestSensorDataUtil.java b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestSensorDataUtil.java index 563ae4f36..a20380b01 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/content/data/TestSensorDataUtil.java +++ b/src/androidTest/java/de/dennisguse/opentracks/content/data/TestSensorDataUtil.java @@ -41,8 +41,7 @@ public class TestSensorDataUtil { if (power != null) { tp.setPower(power); } - tp.setAltitudeGain(3f); - tp.setAltitudeLoss(3f); + tp.setAltitudeGainLoss(3, 3); trackPointList.add(tp); } 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 6c4ce1010..fa00a7577 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 @@ -237,17 +237,14 @@ public class ExportImportTest { Altitude.WGS84.of(1020.25), null, null, Speed.of(15))) - .setAltitudeLoss(1f) - .setAltitudeGain(1f), + .setAltitudeGainLoss(1, 1), new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2020-02-02T02:02:04Z")) .setSensorDistance(Distance.of(10)) .setSpeed(Speed.of(15)) .setHeartRate(HeartRate.of(66)) .setCadence(3) - .setPower(50) - .setAltitudeLoss(1f) - .setAltitudeGain(1f), + .setPower(50).setAltitudeGainLoss(1, 1), new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse("2020-02-02T02:02:15Z")) .setHeartRate(HeartRate.of(68)) .setCadence(3) @@ -260,8 +257,7 @@ public class ExportImportTest { null, Speed.of(5))) .setSensorDistance(Distance.of(2)) - .setAltitudeLoss(0f) - .setAltitudeGain(0f) + .setAltitudeGainLoss(0, 0) .setHeartRate(HeartRate.of(69)) .setCadence(3) .setPower(50), @@ -274,27 +270,23 @@ public class ExportImportTest { Altitude.WGS84.of(999.1229858398438), null, null, Speed.of(15))) - .setAltitudeLoss(0f) - .setAltitudeGain(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC, new Position(Instant.parse("2020-02-02T02:03:22Z"), 3.123456, 16d, Distance.of(10), Altitude.WGS84.of(999.1229858398438), null, null, Speed.of(15))) - .setAltitudeLoss(0f) - .setAltitudeGain(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.IDLE, Instant.parse("2020-02-02T02:03:30Z")) - .setAltitudeLoss(0f) - .setAltitudeGain(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse("2020-02-02T02:03:50Z"), 3.123456, 16.001, Distance.of(10), Altitude.WGS84.of(999.1229858398438), null, null, Speed.of(15))) - .setAltitudeLoss(0f) - .setAltitudeGain(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse("2020-02-02T02:04:00Z")) ), actual); } @@ -433,8 +425,7 @@ public class ExportImportTest { Altitude.WGS84.of(1020.2), null, null, Speed.of(15))) - .setAltitudeLoss(1f) - .setAltitudeGain(1f), + .setAltitudeGainLoss(1, 1), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse("2020-02-02T02:02:17Z"), @@ -442,8 +433,7 @@ public class ExportImportTest { Altitude.WGS84.of(1020.2), null, null, Speed.of(5))) - .setAltitudeLoss(1f) - .setAltitudeGain(1f) + .setAltitudeGainLoss(1, 1) .setSensorDistance(Distance.of(12)) .setHeartRate(69) .setPower(50f) @@ -455,8 +445,7 @@ public class ExportImportTest { Altitude.WGS84.of(999.0999755859375), null, null, Speed.of(15))) - .setAltitudeLoss(0f) - .setAltitudeGain(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC, new Position( Instant.parse("2020-02-02T02:03:22Z"), @@ -464,8 +453,7 @@ public class ExportImportTest { Altitude.WGS84.of(999.0999755859375), null, null, Speed.of(15))) - .setAltitudeLoss(0f) - .setAltitudeGain(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse("2020-02-02T02:03:50Z"), @@ -473,8 +461,7 @@ public class ExportImportTest { Altitude.WGS84.of(999.0999755859375), null, null, Speed.of(10))) - .setAltitudeLoss(0f) - .setAltitudeGain(0f) + .setAltitudeGainLoss(0, 0) .setSpeed(Speed.of(15)) ), actual); diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java index 8cbb7025c..e3c80be8b 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporterTest.java @@ -267,8 +267,7 @@ public class GPXTrackImporterTest { Altitude.WGS84.of(10), null, null, Speed.of(15))) - .setAltitudeLoss(1f) - .setAltitudeGain(1f), + .setAltitudeGainLoss(1, 1), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse("2020-02-02T02:02:17Z"), @@ -276,8 +275,7 @@ public class GPXTrackImporterTest { Altitude.WGS84.of(10), null, null, Speed.of(5))) - .setAltitudeLoss(1f) - .setAltitudeGain(1f) + .setAltitudeGainLoss(1, 1) .setSensorDistance(Distance.of(12)) .setHeartRate(69) .setPower(50f) @@ -289,8 +287,7 @@ public class GPXTrackImporterTest { Altitude.WGS84.of(10), null, null, Speed.of(15))) - .setAltitudeLoss(0f) - .setAltitudeGain(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC, new Position( Instant.parse("2020-02-02T02:03:22Z"), @@ -298,8 +295,7 @@ public class GPXTrackImporterTest { Altitude.WGS84.of(10), null, null, Speed.of(15))) - .setAltitudeLoss(0f) - .setAltitudeGain(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse("2020-02-02T02:03:50Z"), @@ -307,8 +303,7 @@ public class GPXTrackImporterTest { Altitude.WGS84.of(10), null, null, Speed.of(10))) - .setAltitudeLoss(0f) - .setAltitudeGain(0f) + .setAltitudeGainLoss(0, 0) .setSpeed(Speed.of(15)) ), actual); } diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/KMLTrackImporterTest.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/KMLTrackImporterTest.java index afff5a01b..da05889ed 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/KMLTrackImporterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/KMLTrackImporterTest.java @@ -189,24 +189,21 @@ public class KMLTrackImporterTest { 12.340097, 1.234156, null, Altitude.WGS84.of(469.286376953125), null, null, - Speed.of(0.539))) - .setAltitudeGain(0f), + Speed.of(0.539))), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse("2020-11-28T17:06:25.448Z"), 12.340036, 1.23415, null, Altitude.WGS84.of(439.1626281738281), null, null, - Speed.of(0.1577))) - .setAltitudeGain(0f), + Speed.of(0.1577))), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse("2020-11-28T17:06:47.888Z"), 12.340057, 1.23405, null, Altitude.WGS84.of(421.8070983886719), null, null, - Speed.of(0))) - .setAltitudeGain(0f), + Speed.of(0))), // created resume trackpoint with time of next valid trackpoint new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC, new Position( @@ -214,16 +211,14 @@ public class KMLTrackImporterTest { 12.340057, 1.23405, null, Altitude.WGS84.of(419.93902587890625), null, null, - Speed.of(0))) - .setAltitudeGain(0f), + Speed.of(0))), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse("2020-11-28T17:06:56.905Z"), 12.340057, 1.23405, null, Altitude.WGS84.of(419.9036560058594), null, null, - Speed.of(0))) - .setAltitudeGain(0f), + Speed.of(0))), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse("2020-11-28T17:07:20.870Z"), @@ -231,7 +226,6 @@ public class KMLTrackImporterTest { Altitude.WGS84.of(417.99432373046875), null, null, Speed.of(0))) - .setAltitudeGain(0f) ), importedTrackPoints); } diff --git a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java index 1c1895fce..b1c8fe7d1 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java +++ b/src/androidTest/java/de/dennisguse/opentracks/io/file/importer/TrackPointAssert.java @@ -29,13 +29,9 @@ public class TrackPointAssert { Assert.assertEquals("altitude", expected.getAltitude().toM(), actual.getAltitude().toM(), delta); } - Assert.assertEquals("has altitudeGain", expected.hasAltitudeGain(), actual.hasAltitudeGain()); - if (expected.hasAltitudeGain()) { - Assert.assertEquals("altitudeGain", expected.getAltitudeGain(), actual.getAltitudeGain(), delta); - } - Assert.assertEquals("has altitudeLoss", expected.hasAltitudeLoss(), actual.hasAltitudeLoss()); - if (expected.hasAltitudeLoss()) { - Assert.assertEquals("altitudeLoss", expected.getAltitudeLoss(), actual.getAltitudeLoss(), delta); + Assert.assertEquals("has altitudeGainLoss", expected.hasAltitudeGainLoss(), actual.hasAltitudeGainLoss()); + if (expected.hasAltitudeGainLoss()) { + Assert.assertEquals("altitudeGainLoss", expected.getAltitudeGainLoss(), actual.getAltitudeGainLoss()); } Assert.assertEquals("has speed", expected.hasSpeed(), actual.hasSpeed()); diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java index c78317116..cb416225b 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceRecordingTest.java @@ -127,8 +127,7 @@ public class TrackRecordingServiceRecordingTest { new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(stopTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); } @@ -199,8 +198,7 @@ public class TrackRecordingServiceRecordingTest { new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(pauseTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); //when @@ -215,8 +213,7 @@ public class TrackRecordingServiceRecordingTest { new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(pauseTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(resumeTime)) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); } @@ -249,8 +246,7 @@ public class TrackRecordingServiceRecordingTest { new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(starTime)), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(pauseTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) ), trackPoints); } @@ -279,8 +275,7 @@ public class TrackRecordingServiceRecordingTest { new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(stopTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(resumeTime)) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); } @@ -316,12 +311,10 @@ public class TrackRecordingServiceRecordingTest { new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), new TrackPoint(TrackPoint.Type.TRACKPOINT, Instant.parse(sensor3)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) .setHeartRate(HeartRate.of(7)), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(stopTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) .setHeartRate(HeartRate.of(7)) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); } @@ -379,8 +372,7 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse(gps2), @@ -388,8 +380,7 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse(gps3), @@ -397,11 +388,9 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(stopTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); } @@ -455,8 +444,7 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse(gps3), @@ -464,8 +452,7 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, new Position( Instant.parse(stopTime), @@ -473,8 +460,7 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); } @@ -516,8 +502,7 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.TRACKPOINT, new Position( Instant.parse(gps3), @@ -525,11 +510,9 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(stopTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); } @@ -573,8 +556,7 @@ public class TrackRecordingServiceRecordingTest { new TrackPointAssert().assertEquals(List.of( new TrackPoint(TrackPoint.Type.SEGMENT_START_MANUAL, Instant.parse(startTime)), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(stopTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); } @@ -624,8 +606,7 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_START_AUTOMATIC, new Position( Instant.parse(gps2), @@ -633,11 +614,9 @@ public class TrackRecordingServiceRecordingTest { null, null, null, Speed.of(15))) - .setAltitudeGain(0f) - .setAltitudeLoss(0f), + .setAltitudeGainLoss(0, 0), new TrackPoint(TrackPoint.Type.SEGMENT_END_MANUAL, Instant.parse(stopTime)) - .setAltitudeGain(0f) - .setAltitudeLoss(0f) + .setAltitudeGainLoss(0, 0) ), TestDataUtil.getTrackPoints(contentProviderUtils, trackId)); } diff --git a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java index fc89ea127..67e23752f 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdaterTest.java @@ -105,7 +105,7 @@ public class IntervalStatisticsUpdaterTest { ArrayList trackPoints = new ArrayList<>(); for (int i = 0; i < numberOfPoints; i++) { - trackPoints.add(TestDataUtil.createTrackPoint(i).setAltitudeLoss(null)); + trackPoints.add(TestDataUtil.createTrackPoint(i).setAltitudeGainLoss(null)); } trackStatisticsUpdater.addTrackPoints(trackPoints); diff --git a/src/androidTest/res/raw/legacy_kml22_statistics_marker.kml b/src/androidTest/res/raw/legacy_kml22_statistics_marker.kml index bd95dbd7e..aa7f272dc 100644 --- a/src/androidTest/res/raw/legacy_kml22_statistics_marker.kml +++ b/src/androidTest/res/raw/legacy_kml22_statistics_marker.kml @@ -74,7 +74,6 @@ Average moving pace: 0:00 min/km (0:00 min/mi) Fastest pace: 0:00 min/km (0:00 min/mi) Max elevation: -9223372036854775808 m (-9223372036854775808 ft) Min elevation: 9223372036854775807 m (9223372036854775807 ft) -Elevation gain: 0 m (0 ft) Max grade: 0 % Min grade: 0 % Recorded: 6/23 11:29]]> @@ -126,11 +125,6 @@ Recorded: 6/23 11:29]]> 0.15777911 0.0 - - 0.0 - 0.0 - 0.0 - @@ -148,14 +142,6 @@ Recorded: 6/23 11:29]]> 0.0 0.0 - - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - 0.0 - @@ -179,7 +165,6 @@ Average moving pace: 0:00 min/km (0:00 min/mi) Fastest pace: 0:00 min/km (0:00 min/mi) Max elevation: 469 m (1540 ft) Min elevation: 419 m (1376 ft) -Elevation gain: 0 m (0 ft) Recorded: 11/28 18:06]]> 2020-11-28T17:07:20.870Z diff --git a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java index 568c6b2ce..7084bdb24 100644 --- a/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java +++ b/src/main/java/de/dennisguse/opentracks/data/ContentProviderUtils.java @@ -652,11 +652,8 @@ public class ContentProviderUtils { trackPoint.setPower(cursor.getFloat(indexes.sensorPowerIndex)); } - if (!cursor.isNull(indexes.altitudeGainIndex)) { - trackPoint.setAltitudeGain(cursor.getFloat(indexes.altitudeGainIndex)); - } - if (!cursor.isNull(indexes.altitudeLossIndex)) { - trackPoint.setAltitudeLoss(cursor.getFloat(indexes.altitudeLossIndex)); + if (!cursor.isNull(indexes.altitudeGainIndex) && !cursor.isNull(indexes.altitudeLossIndex)) { + trackPoint.setAltitudeGainLoss(cursor.getFloat(indexes.altitudeGainIndex), cursor.getFloat(indexes.altitudeLossIndex)); } return trackPoint; @@ -810,13 +807,10 @@ public class ContentProviderUtils { values.put(TrackPointsColumns.SENSOR_POWER, trackPoint.getPower().getW()); } - if (trackPoint.hasAltitudeGain()) { - values.put(TrackPointsColumns.ALTITUDE_GAIN, trackPoint.getAltitudeGain()); + if (trackPoint.hasAltitudeGainLoss()) { + values.put(TrackPointsColumns.ALTITUDE_GAIN, trackPoint.getAltitudeGainLoss().gain_m()); + values.put(TrackPointsColumns.ALTITUDE_LOSS, trackPoint.getAltitudeGainLoss().loss_m()); } - if (trackPoint.hasAltitudeLoss()) { - values.put(TrackPointsColumns.ALTITUDE_LOSS, trackPoint.getAltitudeLoss()); - } - return values; } diff --git a/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java b/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java index 0536701cd..58151bb68 100644 --- a/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java +++ b/src/main/java/de/dennisguse/opentracks/data/models/TrackPoint.java @@ -83,9 +83,7 @@ public class TrackPoint { private HeartRate heartRate = null; private Cadence cadence = null; private Power power = null; - //TODO Use AltitudeGainLoss - private Float altitudeGain_m = null; - private Float altitudeLoss_m = null; + private AltitudeGainLoss altitudeGainLoss = null; public TrackPoint(@Nullable TrackPoint.Id id, @NonNull Type type, @NonNull Position position) { this.id = id; @@ -164,31 +162,21 @@ public class TrackPoint { return getPosition().toLocation(); } - public boolean hasAltitudeGain() { - return altitudeGain_m != null; + public boolean hasAltitudeGainLoss() { + return altitudeGainLoss != null; } - public float getAltitudeGain() { - return altitudeGain_m; + public AltitudeGainLoss getAltitudeGainLoss() { + return altitudeGainLoss; } - @Deprecated - public TrackPoint setAltitudeGain(Float altitudeGain_m) { - this.altitudeGain_m = altitudeGain_m; + public TrackPoint setAltitudeGainLoss(AltitudeGainLoss altitudeGainLoss) { + this.altitudeGainLoss = altitudeGainLoss; return this; } - public boolean hasAltitudeLoss() { - return altitudeLoss_m != null; - } - - public float getAltitudeLoss() { - return altitudeLoss_m; - } - - @Deprecated - public TrackPoint setAltitudeLoss(Float altitudeLoss_m) { - this.altitudeLoss_m = altitudeLoss_m; + public TrackPoint setAltitudeGainLoss(float altitudeGain_m, float altitudeLoss_m) { + setAltitudeGainLoss(new AltitudeGainLoss(altitudeGain_m, altitudeLoss_m)); return this; } @@ -327,11 +315,10 @@ public class TrackPoint { if (hasSensorDistance() && lastTrackPoint.hasSensorDistance()) { sensorDistance = sensorDistance.minus(lastTrackPoint.getSensorDistance()); } - if (hasAltitudeGain() && lastTrackPoint.hasAltitudeGain()) { - altitudeGain_m -= lastTrackPoint.altitudeGain_m; - } - if (hasAltitudeLoss() && lastTrackPoint.hasAltitudeLoss()) { - altitudeLoss_m -= lastTrackPoint.altitudeLoss_m; + if (hasAltitudeGainLoss() && lastTrackPoint.hasAltitudeGainLoss()) { + altitudeGainLoss = new AltitudeGainLoss( + altitudeGainLoss.gain_m() - lastTrackPoint.altitudeGainLoss.gain_m(), + altitudeGainLoss.loss_m() - lastTrackPoint.altitudeGainLoss.loss_m()); } return this; } @@ -398,8 +385,7 @@ public class TrackPoint { ", heartRate=" + heartRate + ", cadence=" + cadence + ", power=" + power + - ", altitudeGain_m=" + altitudeGain_m + - ", altitudeLoss_m=" + altitudeLoss_m + + ", altitudeGainLoss=" + altitudeGainLoss + '}'; } diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/CSVTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/CSVTrackExporter.java index ab5da9ac9..40a7dddb1 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/CSVTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/CSVTrackExporter.java @@ -98,8 +98,8 @@ public class CSVTrackExporter implements TrackExporter { new Column("accuracy_vertical", t -> t.hasVerticalAccuracy() ? DISTANCE_FORMAT.format(t.getVerticalAccuracy().toM()) : ""), new Column("speed", t -> t.hasSpeed() ? SPEED_FORMAT.format(t.getSpeed().toKMH()) : ""), - new Column("altitude_gain", t -> t.hasAltitudeGain() ? ALTITUDE_FORMAT.format(t.getAltitudeGain()) : ""), - new Column("altitude_loss", t -> t.hasAltitudeLoss() ? ALTITUDE_FORMAT.format(t.getAltitudeLoss()) : ""), + new Column("altitude_gain", t -> t.hasAltitudeGainLoss() ? ALTITUDE_FORMAT.format(t.getAltitudeGainLoss().gain_m()) : ""), + new Column("altitude_loss", t -> t.hasAltitudeGainLoss() ? ALTITUDE_FORMAT.format(t.getAltitudeGainLoss().loss_m()) : ""), new Column("sensor_distance", t -> t.hasSensorDistance() ? DISTANCE_FORMAT.format(t.getSensorDistance().toM()) : ""), new Column("heartrate", t -> t.hasHeartRate() ? HEARTRATE_FORMAT.format(t.getHeartRate().getBPM()) : ""), new Column("cadence", t -> t.hasCadence() ? CADENCE_FORMAT.format(t.getCadence().getRPM()) : ""), diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java index 71e2c0eac..3359ebff0 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/GPXTrackExporter.java @@ -338,12 +338,12 @@ public class GPXTrackExporter implements TrackExporter { extensionContent += "" + POWER_FORMAT.format(trackPoint.getPower().getW()) + "\n"; } - Double cumulativeGain = cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasAltitudeGain() ? (double) tp.getAltitudeGain() : null); + Double cumulativeGain = cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasAltitudeGainLoss() ? (double) tp.getAltitudeGainLoss().gain_m() : null); if (cumulativeGain != null) { extensionContent += ("" + ALTITUDE_FORMAT.format(cumulativeGain) + "\n"); } - Double cumulativeLoss = cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasAltitudeLoss() ? (double) tp.getAltitudeLoss() : null); + Double cumulativeLoss = cumulateSensorData(trackPoint, sensorPoints, (tp) -> tp.hasAltitudeGainLoss() ? (double) tp.getAltitudeGainLoss().loss_m() : null); if (cumulativeLoss != null) { extensionContent += ("" + ALTITUDE_FORMAT.format(cumulativeLoss) + "\n"); } diff --git a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java index cb71f304c..8c8d783df 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/exporter/KMLTrackExporter.java @@ -384,9 +384,13 @@ public class KMLTrackExporter implements TrackExporter { heartRateList.add(trackPoint.hasHeartRate() ? trackPoint.getHeartRate().getBPM() : null); cadenceList.add(trackPoint.hasCadence() ? trackPoint.getCadence().getRPM() : null); powerList.add(trackPoint.hasPower() ? trackPoint.getPower().getW() : null); - - altitudeGainList.add(trackPoint.hasAltitudeGain() ? trackPoint.getAltitudeGain() : null); - altitudeLossList.add(trackPoint.hasAltitudeLoss() ? trackPoint.getAltitudeLoss() : null); + if (trackPoint.hasAltitudeGainLoss()) { + altitudeGainList.add(trackPoint.getAltitudeGainLoss().loss_m()); + altitudeLossList.add(trackPoint.getAltitudeGainLoss().loss_m()); + } else { + altitudeGainList.add(null); + altitudeLossList.add(null); + } accuracyHorizontal.add(trackPoint.hasHorizontalAccuracy() ? (float) trackPoint.getHorizontalAccuracy().toM() : null); accuracyVertical.add(trackPoint.hasVerticalAccuracy() ? (float) trackPoint.getVerticalAccuracy().toM() : null); } diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporter.java index e7e258667..9abac901d 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/GPXTrackImporter.java @@ -369,18 +369,11 @@ public class GPXTrackImporter extends DefaultHandler implements XMLImporter.Trac } } - if (gain != null) { + if (gain != null && loss != null) { try { - trackPoint.setAltitudeGain(Float.parseFloat(gain)); + trackPoint.setAltitudeGainLoss(Float.parseFloat(gain), Float.parseFloat(loss)); } catch (NumberFormatException e) { - throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse altitude gain: %s", gain)), e); - } - } - if (loss != null) { - try { - trackPoint.setAltitudeLoss(Float.parseFloat(loss)); - } catch (NumberFormatException e) { - throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse altitude loss: %s", loss)), e); + throw new ParsingException(createErrorMessage(String.format(Locale.US, "Unable to parse altitude gain: %s or los: %s", gain, loss)), e); } } if (sensorDistance != null) { diff --git a/src/main/java/de/dennisguse/opentracks/io/file/importer/KMLTrackImporter.java b/src/main/java/de/dennisguse/opentracks/io/file/importer/KMLTrackImporter.java index 370f9ea50..3e77dac96 100644 --- a/src/main/java/de/dennisguse/opentracks/io/file/importer/KMLTrackImporter.java +++ b/src/main/java/de/dennisguse/opentracks/io/file/importer/KMLTrackImporter.java @@ -342,11 +342,10 @@ public class KMLTrackImporter extends DefaultHandler implements XMLImporter.Trac if (i < sensorPowerList.size() && sensorPowerList.get(i) != null) { trackPoint.setPower(sensorPowerList.get(i)); } - if (i < altitudeGainList.size()) { - trackPoint.setAltitudeGain(altitudeGainList.get(i)); - } - if (i < altitudeLossList.size()) { - trackPoint.setAltitudeLoss(altitudeLossList.get(i)); + if (i < altitudeGainList.size() && i < altitudeLossList.size()) { + if (altitudeGainList.get(i) != null && altitudeLossList.get(i) != null) { + trackPoint.setAltitudeGainLoss(altitudeGainList.get(i), altitudeLossList.get(i)); + } } if (i < accuracyHorizontal.size() && accuracyHorizontal.get(i) != null) { trackPoint.setHorizontalAccuracy(Distance.of(accuracyHorizontal.get(i))); 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 2d1e6aeb5..eacfc9e49 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/sensorData/SensorDataSet.java @@ -185,8 +185,7 @@ public class SensorDataSet { } if (barometer != null && barometer.hasReceivedData()) { - trackPoint.setAltitudeGain(barometer.getAggregatedValue(trackPointCreator.createNow()).gain_m()); - trackPoint.setAltitudeLoss(barometer.getAggregatedValue(trackPointCreator.createNow()).loss_m()); + trackPoint.setAltitudeGainLoss(barometer.getAggregatedValue(trackPointCreator.createNow()).gain_m(), barometer.getAggregatedValue(trackPointCreator.createNow()).loss_m()); } } diff --git a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java index 59becef9f..1044810b2 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/SegmentStatisticUpdater.java @@ -360,42 +360,37 @@ public class SegmentStatisticUpdater { } } + @VisibleForTesting + @Deprecated @Nullable public Float getTotalAltitudeGain() { return totalAltitudeGain_m; } + @VisibleForTesting + @Deprecated public void setTotalAltitudeGain(Float totalAltitudeGain_m) { this.totalAltitudeGain_m = totalAltitudeGain_m; } - @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) - public void addTotalAltitudeGain(float gain_m) { - if (totalAltitudeGain_m == null) { - totalAltitudeGain_m = 0f; - } - totalAltitudeGain_m += gain_m; - } - - public boolean hasTotalAltitudeLoss() { - return totalAltitudeLoss_m != null; - } - + @VisibleForTesting + @Deprecated @Nullable public Float getTotalAltitudeLoss() { return totalAltitudeLoss_m; } - public void setTotalAltitudeLoss(Float totalAltitudeLoss_m) { - this.totalAltitudeLoss_m = totalAltitudeLoss_m; - } - @VisibleForTesting(otherwise = VisibleForTesting.PACKAGE_PRIVATE) - public void addTotalAltitudeLoss(float loss_m) { + public void addTotalAltitudeGainLoss(AltitudeGainLoss altitudeGainLoss) { + if (totalAltitudeGain_m == null) { + totalAltitudeGain_m = 0f; + } + totalAltitudeGain_m += altitudeGainLoss.gain_m(); + if (totalAltitudeLoss_m == null) { totalAltitudeLoss_m = 0f; } - totalAltitudeLoss_m += loss_m; + totalAltitudeLoss_m += altitudeGainLoss.loss_m(); } @NonNull diff --git a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java index 03945cb27..b0d1bed61 100644 --- a/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/stats/TrackStatisticsUpdater.java @@ -114,12 +114,8 @@ public class TrackStatisticsUpdater { currentSegment.setTotalTime(Duration.between(currentSegment.getStartTime(), trackPoint.getTime())); // Process sensor data: barometer - if (trackPoint.hasAltitudeGain()) { - currentSegment.addTotalAltitudeGain(trackPoint.getAltitudeGain()); - } - - if (trackPoint.hasAltitudeLoss()) { - currentSegment.addTotalAltitudeLoss(trackPoint.getAltitudeLoss()); + if (trackPoint.hasAltitudeGainLoss()) { + currentSegment.addTotalAltitudeGainLoss(trackPoint.getAltitudeGainLoss()); } //Update absolute (GPS-based) altitude diff --git a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java index 884841849..72314ee52 100644 --- a/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java +++ b/src/main/java/de/dennisguse/opentracks/ui/intervals/IntervalStatisticsUpdater.java @@ -185,11 +185,9 @@ public class IntervalStatisticsUpdater { if (lastTrackPoint == null) { return; } - if (hasGain() && lastTrackPoint.hasAltitudeGain()) { - gain_m = gain_m - lastTrackPoint.getAltitudeGain(); - } - if (hasLoss() && lastTrackPoint.hasAltitudeLoss()) { - loss_m = loss_m - lastTrackPoint.getAltitudeLoss(); + if (hasGain() && lastTrackPoint.hasAltitudeGainLoss()) { + gain_m = gain_m - lastTrackPoint.getAltitudeGainLoss().gain_m(); + loss_m = loss_m - lastTrackPoint.getAltitudeGainLoss().loss_m(); } } From 95b27f66fb81dc96eb5c3e77f68877e40b036778 Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Fri, 31 Oct 2025 18:34:07 +0100 Subject: [PATCH 25/30] AndroidStudio: set line width (for autoformatting) to 200. --- .idea/codeStyles/Project.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index e8dd7072a..74fccbea9 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -47,6 +47,12 @@ + + + +