forked from upstream-mirrors/OpenTracks
@@ -268,6 +268,30 @@ public class TrackRecordingServiceTest {
|
||||
assertEquals(TrackPoint.Type.TRACKPOINT, trackPoints.get(3).getType());
|
||||
}
|
||||
|
||||
@MediumTest
|
||||
@Test
|
||||
public void testRecording_stopPausedTrack() throws TimeoutException {
|
||||
// given
|
||||
TrackRecordingServiceInterface service = ((TrackRecordingServiceInterface) mServiceRule.bindService(createStartIntent(context)));
|
||||
Track.Id trackId = service.startNewTrack();
|
||||
assertTrue(service.isRecording());
|
||||
service.pauseCurrentTrack();
|
||||
|
||||
assertEquals(2, contentProviderUtils.getTrackPoints(trackId).size());
|
||||
|
||||
// when
|
||||
service.endCurrentTrack();
|
||||
|
||||
// then
|
||||
assertFalse(service.isRecording());
|
||||
assertNull(service.getRecordingTrackId());
|
||||
|
||||
List<TrackPoint> trackPoints = contentProviderUtils.getTrackPoints(trackId);
|
||||
assertEquals(2, trackPoints.size());
|
||||
assertEquals(TrackPoint.Type.SEGMENT_START_MANUAL, trackPoints.get(0).getType());
|
||||
assertEquals(TrackPoint.Type.SEGMENT_END_MANUAL, trackPoints.get(1).getType());
|
||||
}
|
||||
|
||||
@Ignore("Sometimes fails on CI.")
|
||||
@MediumTest
|
||||
@Test
|
||||
|
||||
@@ -54,7 +54,7 @@ public class TrackController implements View.OnTouchListener {
|
||||
private final TransitionDrawable transition;
|
||||
|
||||
private boolean isRecording;
|
||||
private boolean isPaused;
|
||||
private boolean isRecordingPaused;
|
||||
private Duration totalTime;
|
||||
private boolean isResumed = false;
|
||||
|
||||
@@ -63,8 +63,9 @@ public class TrackController implements View.OnTouchListener {
|
||||
// A runnable to update the total time.
|
||||
private final Runnable updateTotalTimeRunnable = new Runnable() {
|
||||
public void run() {
|
||||
if (isResumed && isRecording && !isPaused) {
|
||||
viewBinding.trackControllerTotalTime.setText(StringUtils.formatElapsedTimeWithHour(totalTime));
|
||||
if (isResumed && isRecording && !isRecordingPaused) {
|
||||
updateTotalTime();
|
||||
setTotalTime();
|
||||
handlerUpdateTotalTime.postDelayed(this, UnitConversions.ONE_SECOND_MS);
|
||||
}
|
||||
}
|
||||
@@ -82,7 +83,7 @@ public class TrackController implements View.OnTouchListener {
|
||||
|
||||
viewBinding.trackControllerRecord.setOnTouchListener(this);
|
||||
viewBinding.trackControllerRecord.setOnClickListener((view) -> {
|
||||
if (buttonDelay != null || (isRecording && !isPaused)) {
|
||||
if (buttonDelay != null || (isRecording && !isRecordingPaused)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -118,7 +119,7 @@ public class TrackController implements View.OnTouchListener {
|
||||
//To pause a recording
|
||||
if (viewBinding.trackControllerRecord.equals(view)
|
||||
&& event.getAction() == MotionEvent.ACTION_DOWN
|
||||
&& isRecording && !isPaused) {
|
||||
&& isRecording && !isRecordingPaused) {
|
||||
|
||||
transition.startTransition(buttonDelayDuration);
|
||||
|
||||
@@ -165,10 +166,11 @@ public class TrackController implements View.OnTouchListener {
|
||||
|
||||
public void update(boolean recording, boolean paused) {
|
||||
if (!isResumed) {
|
||||
handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable);
|
||||
return;
|
||||
}
|
||||
isRecording = recording;
|
||||
isPaused = paused;
|
||||
isRecordingPaused = paused;
|
||||
boolean visible = alwaysShow || isRecording;
|
||||
viewBinding.trackControllerContainer.setVisibility(visible ? View.VISIBLE : View.GONE);
|
||||
|
||||
@@ -177,27 +179,26 @@ public class TrackController implements View.OnTouchListener {
|
||||
return;
|
||||
}
|
||||
|
||||
viewBinding.trackControllerRecord.setImageResource(isRecording && !isPaused ? R.drawable.ic_button_pause : R.drawable.button_record);
|
||||
viewBinding.trackControllerRecord.setContentDescription(activity.getString(isRecording && !isPaused ? R.string.image_pause : R.string.image_record));
|
||||
if (isRecording && !isRecordingPaused) {
|
||||
handlerUpdateTotalTime.postDelayed(updateTotalTimeRunnable, UnitConversions.ONE_SECOND_MS);
|
||||
}
|
||||
|
||||
viewBinding.trackControllerRecord.setImageResource(isRecording && !isRecordingPaused ? R.drawable.ic_button_pause : R.drawable.button_record);
|
||||
viewBinding.trackControllerRecord.setContentDescription(activity.getString(isRecording && !isRecordingPaused ? R.string.image_pause : R.string.image_record));
|
||||
|
||||
viewBinding.trackControllerStop.setEnabled(isRecording);
|
||||
|
||||
viewBinding.trackControllerStatus.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
|
||||
if (isRecording) {
|
||||
viewBinding.trackControllerStatus.setTextColor(activity.getResources().getColor(isPaused ? android.R.color.white : R.color.recording_text));
|
||||
viewBinding.trackControllerStatus.setTextColor(activity.getResources().getColor(isRecordingPaused ? android.R.color.white : R.color.recording_text));
|
||||
showStatusSetDefaultText();
|
||||
}
|
||||
|
||||
handlerUpdateTotalTime.removeCallbacks(updateTotalTimeRunnable);
|
||||
viewBinding.trackControllerTotalTime.setVisibility(isRecording ? View.VISIBLE : View.INVISIBLE);
|
||||
|
||||
if (isRecording) {
|
||||
totalTime = getTotalTime();
|
||||
if (totalTime != null) {
|
||||
viewBinding.trackControllerTotalTime.setText(StringUtils.formatElapsedTimeWithHour(totalTime));
|
||||
}
|
||||
if (!isPaused) {
|
||||
handlerUpdateTotalTime.postDelayed(updateTotalTimeRunnable, UnitConversions.ONE_SECOND_MS);
|
||||
}
|
||||
updateTotalTime();
|
||||
setTotalTime();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -219,16 +220,21 @@ public class TrackController implements View.OnTouchListener {
|
||||
viewBinding.trackControllerContainer.setVisibility(View.VISIBLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the total time for the current recording track.
|
||||
*/
|
||||
private Duration getTotalTime() {
|
||||
private void updateTotalTime() {
|
||||
TrackRecordingServiceInterface trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
|
||||
return trackRecordingService != null ? trackRecordingService.getTotalTime() : null;
|
||||
if (trackRecordingService != null) {
|
||||
totalTime = trackRecordingService.getTotalTime();
|
||||
}
|
||||
}
|
||||
|
||||
private void setTotalTime() {
|
||||
if (totalTime != null) {
|
||||
viewBinding.trackControllerTotalTime.setText(StringUtils.formatElapsedTimeWithHour(totalTime));
|
||||
}
|
||||
}
|
||||
|
||||
private void showStatusSetDefaultText() {
|
||||
viewBinding.trackControllerStatus.setText(isPaused ? R.string.generic_paused : R.string.generic_recording);
|
||||
viewBinding.trackControllerStatus.setText(isRecordingPaused ? R.string.generic_paused : R.string.generic_recording);
|
||||
}
|
||||
|
||||
public interface Callback {
|
||||
|
||||
@@ -15,7 +15,6 @@ import androidx.recyclerview.widget.GridLayoutManager;
|
||||
import androidx.recyclerview.widget.RecyclerView;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -409,26 +408,15 @@ public class StatisticsRecordingFragment extends Fragment implements TrackDataLi
|
||||
}
|
||||
|
||||
private void updateTotalTime() {
|
||||
Duration totalTime;
|
||||
Duration totalTime = lastTrackStatistics.getTotalTime();
|
||||
if (isSelectedTrackRecording()) {
|
||||
totalTime = calculateTotalTime();
|
||||
} else {
|
||||
totalTime = lastTrackStatistics.getTotalTime();
|
||||
TrackRecordingServiceInterface trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
|
||||
if (trackRecordingService != null) {
|
||||
totalTime = trackRecordingService.getTotalTime();
|
||||
}
|
||||
}
|
||||
viewBinding.statsTotalTimeValue.setText(StringUtils.formatElapsedTime(totalTime));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return time from service.
|
||||
* If service isn't bound then use lastTrackStatistics for calculate it.
|
||||
*/
|
||||
private Duration calculateTotalTime() {
|
||||
TrackRecordingServiceInterface trackRecordingService = trackRecordingServiceConnection.getServiceIfBound();
|
||||
if (trackRecordingService != null) {
|
||||
return trackRecordingService.getTotalTime();
|
||||
} else {
|
||||
return Duration.between(lastTrackStatistics.getStopTime().plus(lastTrackStatistics.getTotalTime()), Instant.now());
|
||||
}
|
||||
viewBinding.statsTotalTimeValue.setText(StringUtils.formatElapsedTime(totalTime));
|
||||
}
|
||||
|
||||
private void setLocationValues() {
|
||||
|
||||
@@ -234,10 +234,13 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
if (trackStatisticsUpdater == null) {
|
||||
return Duration.ofSeconds(0);
|
||||
}
|
||||
if (!isPaused()) {
|
||||
trackStatisticsUpdater.updateTime(Instant.now());
|
||||
if (isPaused()) {
|
||||
return trackStatisticsUpdater.getTrackStatistics().getTotalTime();
|
||||
}
|
||||
return trackStatisticsUpdater.getTrackStatistics().getTotalTime();
|
||||
|
||||
TrackStatistics statistics = trackStatisticsUpdater.getTrackStatistics();
|
||||
return Duration.between(statistics.getStopTime(), Instant.now())
|
||||
.plus(statistics.getTotalTime());
|
||||
}
|
||||
|
||||
public Marker.Id insertMarker(String name, String category, String description, String photoUrl) {
|
||||
@@ -420,24 +423,24 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
}
|
||||
|
||||
// Need to remember the recordingTrackId before setting it to -1L
|
||||
boolean wasPause = isPaused();
|
||||
Track.Id trackId = recordingTrackId;
|
||||
boolean wasPaused = recordingTrackPaused;
|
||||
|
||||
updateRecordingState(null, true);
|
||||
|
||||
// Update database
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
if (track != null) {
|
||||
if (lastTrackPoint != null) {
|
||||
insertTrackPointIfNewer(track, lastTrackPoint);
|
||||
if (!wasPause) {
|
||||
// Update database
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
if (track != null) {
|
||||
if (lastTrackPoint != null) {
|
||||
insertTrackPointIfNewer(track, lastTrackPoint);
|
||||
}
|
||||
|
||||
insertTrackPoint(track, TrackPoint.createSegmentEnd());
|
||||
}
|
||||
|
||||
insertTrackPoint(track, TrackPoint.createSegmentEnd());
|
||||
|
||||
// Update the recording track time
|
||||
updateTrackTotalTime(track);
|
||||
}
|
||||
|
||||
Track track = contentProviderUtils.getTrack(trackId);
|
||||
ExportUtils.postWorkoutExport(this, track, new ExportServiceResultReceiver(new Handler(), this));
|
||||
|
||||
endRecording(true);
|
||||
@@ -663,7 +666,9 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
}
|
||||
contentProviderUtils.insertTrackPoint(trackPoint, track.getId());
|
||||
trackStatisticsUpdater.addTrackPoint(trackPoint, recordingDistanceInterval);
|
||||
updateTrackTotalTime(track);
|
||||
|
||||
track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
|
||||
contentProviderUtils.updateTrack(track);
|
||||
} catch (SQLiteException e) {
|
||||
/*
|
||||
* Insert failed, most likely because of SqlLite error code 5 (SQLite_BUSY).
|
||||
@@ -674,17 +679,6 @@ public class TrackRecordingService extends Service implements HandlerServer.Hand
|
||||
voiceExecutor.update();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the recording track time.
|
||||
*
|
||||
* @param track the track
|
||||
*/
|
||||
private void updateTrackTotalTime(Track track) {
|
||||
trackStatisticsUpdater.updateTime(Instant.now());
|
||||
track.setTrackStatistics(trackStatisticsUpdater.getTrackStatistics());
|
||||
contentProviderUtils.updateTrack(track);
|
||||
}
|
||||
|
||||
SensorDataSet getSensorDataSet() {
|
||||
if (remoteSensorManager == null) {
|
||||
return null;
|
||||
|
||||
@@ -22,7 +22,6 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.VisibleForTesting;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||
import de.dennisguse.opentracks.content.provider.TrackPointIterator;
|
||||
@@ -91,11 +90,6 @@ public class TrackStatisticsUpdater {
|
||||
trackInitialized = true;
|
||||
}
|
||||
|
||||
public void updateTime(Instant time) {
|
||||
currentSegment.setStopTime(time);
|
||||
currentSegment.setTotalTime(Duration.between(currentSegment.getStartTime(), time));
|
||||
}
|
||||
|
||||
public TrackStatistics getTrackStatistics() {
|
||||
// Take a snapshot - we don't want anyone messing with our trackStatistics
|
||||
TrackStatistics stats = new TrackStatistics(trackStatistics);
|
||||
@@ -120,7 +114,9 @@ public class TrackStatisticsUpdater {
|
||||
}
|
||||
|
||||
// Always update time
|
||||
updateTime(trackPoint.getTime());
|
||||
currentSegment.setStopTime(trackPoint.getTime());
|
||||
currentSegment.setTotalTime(Duration.between(currentSegment.getStartTime(), trackPoint.getTime()));
|
||||
|
||||
if (trackPoint.isSegmentStart() || trackPoint.isSegmentEnd()) {
|
||||
if (trackPoint.isSegmentEnd()) {
|
||||
if (lastTrackPoint != null && lastMovingTrackPoint != null && lastTrackPoint != lastMovingTrackPoint) {
|
||||
@@ -240,9 +236,6 @@ public class TrackStatisticsUpdater {
|
||||
return newAverage - oldAverage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the speed is valid.
|
||||
*/
|
||||
private boolean isValidSpeed(@NonNull TrackPoint trackPoint, @NonNull TrackPoint lastTrackPoint) {
|
||||
// There are a lot of noisy speed readings. Do the cheapest checks first, most expensive last.
|
||||
if (trackPoint.getSpeed() == 0) {
|
||||
|
||||
Reference in New Issue
Block a user