From 4d5c59be962122c11ea12fe90efa25c4a57527eb Mon Sep 17 00:00:00 2001 From: Dennis Guse Date: Tue, 8 Aug 2023 23:22:35 +0200 Subject: [PATCH] TrackRecordingService: must be stopped via TrackRecordingServiceConnection and handles Preference changes. --- .gitignore | 1 + ...TrackRecordingServiceStateMachineTest.java | 4 +- .../sensors/BluetoothRemoteSensorManager.java | 73 +++++++++---------- .../opentracks/sensors/SensorManager.java | 17 ++++- .../services/TrackRecordingManager.java | 8 -- .../services/TrackRecordingService.java | 60 +++++++-------- ...ckRecordingServiceNotificationManager.java | 2 - .../VoiceAnnouncementManager.java | 2 - .../services/handlers/GPSManager.java | 22 +++--- .../services/handlers/TrackPointCreator.java | 8 +- 10 files changed, 96 insertions(+), 101 deletions(-) diff --git a/.gitignore b/.gitignore index 503308ed9..fc0db155f 100644 --- a/.gitignore +++ b/.gitignore @@ -53,6 +53,7 @@ captures/ .idea/.name .idea/caches/ .idea/compiler.xml +.idea/androidTestResultsUserPreferences.xml .idea/copyright/profiles_settings.xml .idea/dataSources.ids .idea/datasources.xml diff --git a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceStateMachineTest.java b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceStateMachineTest.java index 297a33c14..1541da6f7 100644 --- a/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceStateMachineTest.java +++ b/src/androidTest/java/de/dennisguse/opentracks/services/TrackRecordingServiceStateMachineTest.java @@ -132,7 +132,7 @@ public class TrackRecordingServiceStateMachineTest { assertEquals(GpsStatusValue.GPS_ENABLED, service.getGpsStatusObservable().getValue()); // when - service.stopSensorsAndShutdown(); + service.stopSensors(); Thread.sleep(1000); // then @@ -177,7 +177,7 @@ public class TrackRecordingServiceStateMachineTest { // then assertFalse(service.isRecording()); assertEquals(TrackRecordingService.STATUS_DEFAULT, service.getRecordingStatusObservable().getValue()); - assertEquals(TrackRecordingService.NOT_RECORDING, service.getRecordingDataObservable().getValue()); + assertNotEquals(TrackRecordingService.NOT_RECORDING, service.getRecordingDataObservable().getValue()); assertEquals(GpsStatusValue.GPS_NONE, service.getGpsStatusObservable().getValue()); diff --git a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java index 40e5ab847..3e6ddc54f 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/BluetoothRemoteSensorManager.java @@ -47,7 +47,7 @@ import de.dennisguse.opentracks.util.PermissionRequester; * * @author Sandor Dornbush */ -public class BluetoothRemoteSensorManager implements SensorConnector, AbstractBluetoothConnectionManager.SensorDataObserver { +public class BluetoothRemoteSensorManager implements SensorConnector, AbstractBluetoothConnectionManager.SensorDataObserver, SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = BluetoothRemoteSensorManager.class.getSimpleName(); @@ -65,39 +65,6 @@ public class BluetoothRemoteSensorManager implements SensorConnector, AbstractBl private final BluetoothConnectionManagerCyclingPower cyclingPower = new BluetoothConnectionManagerCyclingPower(this); private final BluetoothConnectionRunningSpeedAndCadence runningSpeedAndCadence = new BluetoothConnectionRunningSpeedAndCadence(this); - private final SharedPreferences.OnSharedPreferenceChangeListener sharedPreferenceChangeListener = (sharedPreferences, key) -> { - if (!started) return; - - if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_heart_rate_key, key)) { - String address = PreferencesUtils.getBluetoothHeartRateSensorAddress(); - connect(heartRate, address); - } - - if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_cycling_cadence_key, key)) { - String address = PreferencesUtils.getBluetoothCyclingCadenceSensorAddress(); - connect(cyclingCadence, address); - } - - if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_cycling_speed_key, key)) { - String address = PreferencesUtils.getBluetoothCyclingSpeedSensorAddress(); - - connect(cyclingSpeed, address); - } - - if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_cycling_power_key, key)) { - String address = PreferencesUtils.getBluetoothCyclingPowerSensorAddress(); - - connect(cyclingPower, address); - } - - - if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_running_speed_and_cadence_key, key)) { - String address = PreferencesUtils.getBluetoothRunningSpeedAndCadenceAddress(); - - connect(runningSpeedAndCadence, address); - } - }; - public BluetoothRemoteSensorManager(@NonNull Context context, @NonNull Handler handler, @Nullable SensorManager.SensorDataChangedObserver observer) { this.context = context; this.handler = handler; @@ -109,8 +76,8 @@ public class BluetoothRemoteSensorManager implements SensorConnector, AbstractBl public void start(Context context, Handler handler) { started = true; - //Registering triggers connection startup - PreferencesUtils.registerOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); + // Triggers connection startup + onSharedPreferenceChanged(null, null); } @Override @@ -121,7 +88,6 @@ public class BluetoothRemoteSensorManager implements SensorConnector, AbstractBl cyclingPower.disconnect(); runningSpeedAndCadence.disconnect(); - PreferencesUtils.unregisterOnSharedPreferenceChangeListener(sharedPreferenceChangeListener); started = false; } @@ -175,4 +141,37 @@ public class BluetoothRemoteSensorManager implements SensorConnector, AbstractBl public Handler getHandler() { return handler; } + + @Override + public void onSharedPreferenceChanged(SharedPreferences unused, @Nullable String key) { + if (!started) return; + + if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_heart_rate_key, key)) { + String address = PreferencesUtils.getBluetoothHeartRateSensorAddress(); + connect(heartRate, address); + } + + if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_cycling_cadence_key, key)) { + String address = PreferencesUtils.getBluetoothCyclingCadenceSensorAddress(); + connect(cyclingCadence, address); + } + + if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_cycling_speed_key, key)) { + String address = PreferencesUtils.getBluetoothCyclingSpeedSensorAddress(); + + connect(cyclingSpeed, address); + } + + if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_cycling_power_key, key)) { + String address = PreferencesUtils.getBluetoothCyclingPowerSensorAddress(); + + connect(cyclingPower, address); + } + + if (PreferencesUtils.isKey(R.string.settings_sensor_bluetooth_running_speed_and_cadence_key, key)) { + String address = PreferencesUtils.getBluetoothRunningSpeedAndCadenceAddress(); + + connect(runningSpeedAndCadence, address); + } + } } diff --git a/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java b/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java index f76ce1993..d2a848cc7 100644 --- a/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java +++ b/src/main/java/de/dennisguse/opentracks/sensors/SensorManager.java @@ -1,9 +1,11 @@ package de.dennisguse.opentracks.sensors; import android.content.Context; +import android.content.SharedPreferences; import android.os.Handler; import android.util.Log; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import de.dennisguse.opentracks.data.models.TrackPoint; @@ -12,7 +14,7 @@ import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.services.handlers.GPSManager; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; -public class SensorManager { +public class SensorManager implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = SensorManager.class.getSimpleName(); @@ -49,11 +51,12 @@ public class SensorManager { public void start(Context context, Handler handler) { gpsManager = new GPSManager(observer); //TODO Pass listener - gpsManager.start(context, handler); - altitudeSumManager = new AltitudeSumManager(); bluetoothSensorManager = new BluetoothRemoteSensorManager(context, handler, listener); + onSharedPreferenceChanged(null, null); + + gpsManager.start(context, handler); altitudeSumManager.start(context, handler); bluetoothSensorManager.start(context, handler); } @@ -114,6 +117,14 @@ public class SensorManager { this.altitudeSumManager = altitudeSumManager; } + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String key) { + if (gpsManager != null) { + gpsManager.onSharedPreferenceChanged(sharedPreferences, key); + bluetoothSensorManager.onSharedPreferenceChanged(sharedPreferences, key); + } + } + public interface SensorDataChangedObserver { void onChange(SensorData sensorData); diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java index 24d89f5b1..546a5f402 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingManager.java @@ -58,14 +58,6 @@ class TrackRecordingManager implements SharedPreferences.OnSharedPreferenceChang contentProviderUtils = new ContentProviderUtils(context); } - public void start() { - PreferencesUtils.registerOnSharedPreferenceChangeListener(this); - } - - public void stop() { - PreferencesUtils.unregisterOnSharedPreferenceChangeListener(this); - } - Track.Id startNewTrack() { TrackPoint segmentStartTrackPoint = trackPointCreator.createSegmentStartManual(); // Create new track diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java index ac450063e..93e07aa9d 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingService.java @@ -18,6 +18,7 @@ package de.dennisguse.opentracks.services; import android.app.Service; import android.content.Intent; +import android.content.SharedPreferences; import android.content.pm.ServiceInfo; import android.os.Build; import android.os.Handler; @@ -26,6 +27,7 @@ import android.os.PowerManager.WakeLock; import android.util.Log; import android.util.Pair; +import androidx.annotation.Nullable; import androidx.annotation.VisibleForTesting; import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; @@ -40,9 +42,10 @@ import de.dennisguse.opentracks.sensors.sensorData.SensorDataSet; import de.dennisguse.opentracks.services.announcement.VoiceAnnouncementManager; import de.dennisguse.opentracks.services.handlers.GpsStatusValue; import de.dennisguse.opentracks.services.handlers.TrackPointCreator; +import de.dennisguse.opentracks.settings.PreferencesUtils; import de.dennisguse.opentracks.util.SystemUtils; -public class TrackRecordingService extends Service implements TrackPointCreator.Callback { +public class TrackRecordingService extends Service implements TrackPointCreator.Callback, SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = TrackRecordingService.class.getSimpleName(); @@ -81,7 +84,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator. private MutableLiveData recordingDataObservable; // The following variables are set when recording: - private WakeLock wakeLock; + private WakeLock wakeLock; //TODO Move to SensorManager private Handler handler; private TrackPointCreator trackPointCreator; @@ -93,6 +96,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator. @Override public void onCreate() { super.onCreate(); + Log.d(TAG, "Create"); handler = new Handler(Looper.getMainLooper()); @@ -103,40 +107,39 @@ public class TrackRecordingService extends Service implements TrackPointCreator. trackPointCreator = new TrackPointCreator(this, this, handler); trackRecordingManager = new TrackRecordingManager(this, trackPointCreator); - trackRecordingManager.start(); voiceAnnouncementManager = new VoiceAnnouncementManager(this); notificationManager = new TrackRecordingServiceNotificationManager(this); + + PreferencesUtils.registerOnSharedPreferenceChangeListener(this); } @Override public void onDestroy() { - trackPointCreator.stop(); + Log.d(TAG, "Destroying"); + if (isRecording()) { + endCurrentTrack(); + } + + PreferencesUtils.unregisterOnSharedPreferenceChangeListener(this); + trackPointCreator = null; handler.removeCallbacksAndMessages(null); //Some tests do not finish the recording completely handler = null; - trackRecordingManager.stop(); trackRecordingManager = null; // Reverse order from onCreate - stopForeground(true); - - notificationManager.stop(); notificationManager = null; - voiceAnnouncementManager.stop(); voiceAnnouncementManager = null; - // This should be the next to last operation - wakeLock = SystemUtils.releaseWakeLock(wakeLock); - - updateRecordingStatus(STATUS_DEFAULT); recordingStatusObservable = null; gpsStatusObservable = null; recordingDataObservable = null; + Log.d(TAG, "Destroyed"); super.onDestroy(); } @@ -210,34 +213,15 @@ public class TrackRecordingService extends Service implements TrackPointCreator. updateRecordingStatus(STATUS_DEFAULT); trackRecordingManager.end(); - endRecording(); - stopSelf(); - } - - private void endRecording() { stopUpdateRecordingData(); - recordingDataObservable.postValue(NOT_RECORDING); voiceAnnouncementManager.stop(); - // Update instance variables - trackPointCreator.stop(); - stopSensors(); } - public void stopSensorsAndShutdown() { - if (isRecording()) { - return; - } - stopSensors(); - stopSelf(); - } - void stopSensors() { - if (!isRecording()) return; - trackPointCreator.stop(); stopForeground(true); notificationManager.cancelNotification(); @@ -258,6 +242,8 @@ public class TrackRecordingService extends Service implements TrackPointCreator. @Override public void newGpsStatus(GpsStatusValue gpsStatusValue) { + Log.e(TAG, "newGpsStatus: " + gpsStatusValue.message); + notificationManager.updateContent(getString(gpsStatusValue.message)); gpsStatusObservable.postValue(gpsStatusValue); } @@ -291,7 +277,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator. } private void updateRecordingDataWhileRecording() { - if (!recordingStatus.isRecording()) { + if (!isRecording()) { Log.w(TAG, "Currently not recording; cannot update data."); return; } @@ -323,4 +309,12 @@ public class TrackRecordingService extends Service implements TrackPointCreator. public boolean isRecording() { return recordingStatus.isRecording(); } + + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String key) { + voiceAnnouncementManager.onSharedPreferenceChanged(sharedPreferences, key); + trackRecordingManager.onSharedPreferenceChanged(sharedPreferences, key); + trackPointCreator.onSharedPreferenceChanged(sharedPreferences, key); + notificationManager.onSharedPreferenceChanged(sharedPreferences, key); + } } \ No newline at end of file diff --git a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java index 7dd1f098e..7c9eb13ee 100644 --- a/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/TrackRecordingServiceNotificationManager.java @@ -42,7 +42,6 @@ class TrackRecordingServiceNotificationManager implements SharedPreferences.OnSh private UnitSystem unitSystem = null; TrackRecordingServiceNotificationManager(Context context) { - PreferencesUtils.registerOnSharedPreferenceChangeListener(this); notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID, context.getString(R.string.app_name), NotificationManager.IMPORTANCE_HIGH); @@ -65,7 +64,6 @@ class TrackRecordingServiceNotificationManager implements SharedPreferences.OnSh void stop() { cancelNotification(); - PreferencesUtils.unregisterOnSharedPreferenceChangeListener(this); } @VisibleForTesting 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 1dbc557bd..0bfe185af 100644 --- a/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/announcement/VoiceAnnouncementManager.java @@ -60,7 +60,6 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe public VoiceAnnouncementManager(@NonNull TrackRecordingService trackRecordingService) { this.trackRecordingService = trackRecordingService; - PreferencesUtils.registerOnSharedPreferenceChangeListener(this); } public void start(@Nullable TrackStatistics trackStatistics) { @@ -106,7 +105,6 @@ public class VoiceAnnouncementManager implements SharedPreferences.OnSharedPrefe } public void stop() { - PreferencesUtils.unregisterOnSharedPreferenceChangeListener(this); if (voiceAnnouncement != null) { voiceAnnouncement.stop(); voiceAnnouncement = null; diff --git a/src/main/java/de/dennisguse/opentracks/services/handlers/GPSManager.java b/src/main/java/de/dennisguse/opentracks/services/handlers/GPSManager.java index 6d3cb1134..5814db613 100644 --- a/src/main/java/de/dennisguse/opentracks/services/handlers/GPSManager.java +++ b/src/main/java/de/dennisguse/opentracks/services/handlers/GPSManager.java @@ -48,7 +48,8 @@ public class GPSManager implements SensorConnector, LocationListenerCompat, GpsS this.context = context; this.handler = handler; - PreferencesUtils.registerOnSharedPreferenceChangeListener(this); + onSharedPreferenceChanged(null, null); + gpsStatusManager = new GpsStatusManager(context, this, handler); locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE); registerLocationListener(); @@ -62,20 +63,15 @@ public class GPSManager implements SensorConnector, LocationListenerCompat, GpsS @SuppressWarnings({"MissingPermission"}) //TODO upgrade to AGP7.0.0/API31 started complaining about removeUpdates. public void stop(Context context) { - if (locationManager != null && context != null) { - if (PermissionRequester.GPS.hasPermission(context)) { - LocationManagerCompat.removeUpdates(locationManager, this); - } - locationManager = null; - context = null; - handler = null; + if (locationManager != null) { + LocationManagerCompat.removeUpdates(locationManager, this); } + locationManager = null; + this.context = null; + handler = null; - if (gpsStatusManager != null) { - gpsStatusManager.stop(); - gpsStatusManager = null; - } - PreferencesUtils.unregisterOnSharedPreferenceChangeListener(this); + gpsStatusManager.stop(); + gpsStatusManager = null; } @Override diff --git a/src/main/java/de/dennisguse/opentracks/services/handlers/TrackPointCreator.java b/src/main/java/de/dennisguse/opentracks/services/handlers/TrackPointCreator.java index 40b76d003..382ad2b95 100644 --- a/src/main/java/de/dennisguse/opentracks/services/handlers/TrackPointCreator.java +++ b/src/main/java/de/dennisguse/opentracks/services/handlers/TrackPointCreator.java @@ -1,6 +1,7 @@ package de.dennisguse.opentracks.services.handlers; import android.content.Context; +import android.content.SharedPreferences; import android.location.Location; import android.os.Handler; import android.util.Log; @@ -23,7 +24,7 @@ import de.dennisguse.opentracks.settings.PreferencesUtils; /** * Creates TrackPoints while recording by fusing data from different sensors (e.g., GNSS, barometer, BLE sensors). */ -public class TrackPointCreator { +public class TrackPointCreator implements SharedPreferences.OnSharedPreferenceChangeListener { private static final String TAG = TrackPointCreator.class.getSimpleName(); @@ -150,6 +151,11 @@ public class TrackPointCreator { service.newGpsStatus(gpsStatusValue); } + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, @Nullable String key) { + sensorManager.onSharedPreferenceChanged(sharedPreferences, key); + } + public interface Callback { /** * @return Was TrackPoint stored (not discarded)?