Bluetooth: send sensor data directly to SensorManager.

Part of #1424.
This commit is contained in:
Dennis Guse
2023-11-05 13:05:43 +01:00
parent 17487961ad
commit 3a2a62a6d7
9 changed files with 50 additions and 71 deletions
@@ -35,7 +35,7 @@ import de.dennisguse.opentracks.data.models.Track;
import de.dennisguse.opentracks.data.models.TrackPoint;
import de.dennisguse.opentracks.io.file.importer.TrackPointAssert;
import de.dennisguse.opentracks.sensors.AltitudeSumManager;
import de.dennisguse.opentracks.sensors.BluetoothRemoteSensorManager;
import de.dennisguse.opentracks.sensors.SensorManager;
import de.dennisguse.opentracks.sensors.sensorData.SensorDataHeartRate;
import de.dennisguse.opentracks.sensors.sensorData.SensorDataRunning;
import de.dennisguse.opentracks.services.handlers.TrackPointCreator;
@@ -252,17 +252,17 @@ public class TrackRecordingServiceRecordingTest {
trackPointCreator.setClock(startTime);
Track.Id trackId = service.startNewTrack();
trackPointCreator.getSensorManager().setAltitudeSumManager(altitudeSumManager);
BluetoothRemoteSensorManager remoteSensorManager = trackPointCreator.getSensorManager().getBluetoothSensorManager();
SensorManager sensorManager = trackPointCreator.getSensorManager();
// when
String sensor1 = "2020-02-02T02:02:03Z";
trackPointCreator.setClock(sensor1);
remoteSensorManager.onChanged(new SensorDataHeartRate("", "", HeartRate.of(5))); //Should be ignored
sensorManager.onChanged(new SensorDataHeartRate("", "", HeartRate.of(5))); //Should be ignored
String sensor3 = "2020-02-02T02:02:13Z";
trackPointCreator.setClock(sensor3);
remoteSensorManager.onChanged(new SensorDataHeartRate("", "", HeartRate.of(7)));
sensorManager.onChanged(new SensorDataHeartRate("", "", HeartRate.of(7)));
String stopTime = "2020-02-02T02:02:15Z";
trackPointCreator.setClock(stopTime);
@@ -589,17 +589,17 @@ public class TrackRecordingServiceRecordingTest {
trackPointCreator.setClock(startTime);
Track.Id trackId = service.startNewTrack();
trackPointCreator.getSensorManager().setAltitudeSumManager(altitudeSumManager);
BluetoothRemoteSensorManager remoteSensorManager = trackPointCreator.getSensorManager().getBluetoothSensorManager();
SensorManager sensorManager = trackPointCreator.getSensorManager();
// when
String sensor1 = "2020-02-02T02:02:03Z";
trackPointCreator.setClock(sensor1);
remoteSensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(0))); //Should be ignored
sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(0))); //Should be ignored
// when
String sensor2 = "2020-02-02T02:02:04Z";
trackPointCreator.setClock(sensor2);
remoteSensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(2)));
sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(2)));
// when
String gps1 = "2020-02-02T02:02:05Z";
@@ -608,12 +608,12 @@ public class TrackRecordingServiceRecordingTest {
// when
String sensor3 = "2020-02-02T02:02:06Z";
trackPointCreator.setClock(sensor3);
remoteSensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(12)));
sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(12)));
// when
String sensor4 = "2020-02-02T02:02:07Z";
trackPointCreator.setClock(sensor4);
remoteSensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(14))); //Should be ignored
sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(14))); //Should be ignored
// when
String gps2 = "2020-02-02T02:02:08Z";
@@ -622,7 +622,7 @@ public class TrackRecordingServiceRecordingTest {
// when
String sensor5 = "2020-02-02T02:02:10Z";
trackPointCreator.setClock(sensor5);
remoteSensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(16))); //Should be ignored
sensorManager.onChanged(new SensorDataRunning("", "", Speed.of(5), null, Distance.of(16))); //Should be ignored
// when
String gps3 = "2020-02-02T02:02:12Z";
@@ -38,14 +38,13 @@ import de.dennisguse.opentracks.sensors.sensorData.SensorData;
/**
* Manages connection to a Bluetooth LE sensor and subscribes for onChange-notifications.
* Also parses the transferred data into {@link SensorDataObserver}.
*/
@SuppressLint("MissingPermission")
public abstract class AbstractBluetoothConnectionManager<DataType> {
private static final String TAG = AbstractBluetoothConnectionManager.class.getSimpleName();
private final SensorDataObserver observer;
private final SensorManager.SensorDataChangedObserver observer;
private final List<ServiceMeasurementUUID> serviceMeasurementUUIDs;
private BluetoothGatt bluetoothGatt;
@@ -123,22 +122,17 @@ public abstract class AbstractBluetoothConnectionManager<DataType> {
SensorData<DataType> sensorData = parsePayload(serviceMeasurementUUID.get(), gatt.getDevice().getName(), gatt.getDevice().getAddress(), characteristic);
if (sensorData != null) {
Log.d(TAG, "Decoded data from " + gatt.getDevice().getAddress() + ": " + sensorData);
observer.onChanged(sensorData);
observer.onChange(sensorData);
}
}
};
AbstractBluetoothConnectionManager(ServiceMeasurementUUID serviceUUUID, SensorDataObserver observer) {
this.serviceMeasurementUUIDs = List.of(serviceUUUID);
this.observer = observer;
}
AbstractBluetoothConnectionManager(List<ServiceMeasurementUUID> serviceUUUID, SensorDataObserver observer) {
AbstractBluetoothConnectionManager(List<ServiceMeasurementUUID> serviceUUUID, SensorManager.SensorDataChangedObserver observer) {
this.serviceMeasurementUUIDs = serviceUUUID;
this.observer = observer;
}
synchronized void connect(Context context, @NonNull BluetoothDevice device) {
synchronized void connect(Context context, Handler handler, @NonNull BluetoothDevice device) {
if (bluetoothGatt != null) {
Log.w(TAG, "Already connected; ignoring.");
return;
@@ -146,14 +140,14 @@ public abstract class AbstractBluetoothConnectionManager<DataType> {
Log.d(TAG, "Connecting to: " + device);
bluetoothGatt = device.connectGatt(context, false, connectCallback, BluetoothDevice.TRANSPORT_AUTO, 0, this.observer.getHandler());
bluetoothGatt = device.connectGatt(context, false, connectCallback, BluetoothDevice.TRANSPORT_AUTO, 0, handler);
SensorData<?> sensorData = createEmptySensorData(bluetoothGatt.getDevice().getAddress());
observer.onChanged(sensorData);
observer.onChange(sensorData);
}
private synchronized void clearData() {
observer.onDisconnecting(createEmptySensorData(bluetoothGatt.getDevice().getAddress()));
observer.onDisconnect(createEmptySensorData(bluetoothGatt.getDevice().getAddress()));
}
synchronized void disconnect() {
@@ -180,15 +174,4 @@ public abstract class AbstractBluetoothConnectionManager<DataType> {
* @return null if data could not be parsed.
*/
protected abstract SensorData<DataType> parsePayload(@NonNull ServiceMeasurementUUID serviceMeasurementUUID, String sensorName, String address, @NonNull BluetoothGattCharacteristic characteristic);
@Deprecated //TODO REMOVE
interface SensorDataObserver {
void onChanged(SensorData<?> sensorData);
void onDisconnecting(SensorData<?> sensorData);
@NonNull
Handler getHandler();
}
}
@@ -12,7 +12,7 @@ public class BluetoothConnectionManagerCyclingCadence extends AbstractBluetoothC
private static final String TAG = BluetoothConnectionManagerCyclingCadence.class.getSimpleName();
BluetoothConnectionManagerCyclingCadence(SensorDataObserver observer) {
BluetoothConnectionManagerCyclingCadence(SensorManager.SensorDataChangedObserver observer) {
super(BluetoothUtils.CYCLING_CADENCE, observer);
}
@@ -2,13 +2,15 @@ package de.dennisguse.opentracks.sensors;
import android.bluetooth.BluetoothGattCharacteristic;
import java.util.List;
import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingCadenceAndDistanceSpeed;
import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingDistanceSpeed;
public class BluetoothConnectionManagerCyclingDistanceSpeed extends AbstractBluetoothConnectionManager<SensorDataCyclingDistanceSpeed.Data> {
BluetoothConnectionManagerCyclingDistanceSpeed(SensorDataObserver observer) {
super(BluetoothUtils.CYCLING_SPEED_CADENCE, observer);
BluetoothConnectionManagerCyclingDistanceSpeed(SensorManager.SensorDataChangedObserver observer) {
super(List.of(BluetoothUtils.CYCLING_SPEED_CADENCE), observer);
}
@Override
@@ -4,13 +4,15 @@ import android.bluetooth.BluetoothGattCharacteristic;
import androidx.annotation.NonNull;
import java.util.List;
import de.dennisguse.opentracks.data.models.Power;
import de.dennisguse.opentracks.sensors.sensorData.SensorDataCyclingPower;
public class BluetoothConnectionManagerCyclingPower extends AbstractBluetoothConnectionManager<Power> {
BluetoothConnectionManagerCyclingPower(@NonNull SensorDataObserver observer) {
super(BluetoothUtils.CYCLING_POWER, observer);
BluetoothConnectionManagerCyclingPower(@NonNull SensorManager.SensorDataChangedObserver observer) {
super(List.of(BluetoothUtils.CYCLING_POWER), observer);
}
@Override
@@ -4,13 +4,15 @@ import android.bluetooth.BluetoothGattCharacteristic;
import androidx.annotation.NonNull;
import java.util.List;
import de.dennisguse.opentracks.data.models.HeartRate;
import de.dennisguse.opentracks.sensors.sensorData.SensorDataHeartRate;
public class BluetoothConnectionManagerHeartRate extends AbstractBluetoothConnectionManager<HeartRate> {
BluetoothConnectionManagerHeartRate(@NonNull SensorDataObserver observer) {
super(BluetoothUtils.HEARTRATE, observer);
BluetoothConnectionManagerHeartRate(@NonNull SensorManager.SensorDataChangedObserver observer) {
super(List.of(BluetoothUtils.HEARTRATE), observer);
}
@Override
@@ -4,12 +4,14 @@ import android.bluetooth.BluetoothGattCharacteristic;
import androidx.annotation.NonNull;
import java.util.List;
import de.dennisguse.opentracks.sensors.sensorData.SensorDataRunning;
public class BluetoothConnectionRunningSpeedAndCadence extends AbstractBluetoothConnectionManager<SensorDataRunning.Data> {
BluetoothConnectionRunningSpeedAndCadence(@NonNull SensorDataObserver observer) {
super(BluetoothUtils.RUNNING_SPEED_CADENCE, observer);
BluetoothConnectionRunningSpeedAndCadence(@NonNull SensorManager.SensorDataChangedObserver observer) {
super(List.of(BluetoothUtils.RUNNING_SPEED_CADENCE), observer);
}
@Override
@@ -29,7 +29,6 @@ import androidx.annotation.Nullable;
import java.time.Duration;
import de.dennisguse.opentracks.R;
import de.dennisguse.opentracks.sensors.sensorData.SensorData;
import de.dennisguse.opentracks.settings.PreferencesUtils;
import de.dennisguse.opentracks.util.PermissionRequester;
@@ -47,7 +46,7 @@ import de.dennisguse.opentracks.util.PermissionRequester;
*
* @author Sandor Dornbush
*/
public class BluetoothRemoteSensorManager implements SensorConnector, AbstractBluetoothConnectionManager.SensorDataObserver, SharedPreferences.OnSharedPreferenceChangeListener {
public class BluetoothRemoteSensorManager implements SensorConnector, SharedPreferences.OnSharedPreferenceChangeListener {
private static final String TAG = BluetoothRemoteSensorManager.class.getSimpleName();
@@ -56,20 +55,25 @@ public class BluetoothRemoteSensorManager implements SensorConnector, AbstractBl
private final BluetoothAdapter bluetoothAdapter;
private final Context context;
private final Handler handler;
private final SensorManager.SensorDataChangedObserver observer;
private boolean started = false;
private final BluetoothConnectionManagerHeartRate heartRate = new BluetoothConnectionManagerHeartRate(this);
private final BluetoothConnectionManagerCyclingCadence cyclingCadence = new BluetoothConnectionManagerCyclingCadence(this);
private final BluetoothConnectionManagerCyclingDistanceSpeed cyclingSpeed = new BluetoothConnectionManagerCyclingDistanceSpeed(this);
private final BluetoothConnectionManagerCyclingPower cyclingPower = new BluetoothConnectionManagerCyclingPower(this);
private final BluetoothConnectionRunningSpeedAndCadence runningSpeedAndCadence = new BluetoothConnectionRunningSpeedAndCadence(this);
private final BluetoothConnectionManagerHeartRate heartRate;
private final BluetoothConnectionManagerCyclingCadence cyclingCadence;
private final BluetoothConnectionManagerCyclingDistanceSpeed cyclingSpeed;
private final BluetoothConnectionManagerCyclingPower cyclingPower;
private final BluetoothConnectionRunningSpeedAndCadence runningSpeedAndCadence;
public BluetoothRemoteSensorManager(@NonNull Context context, @NonNull Handler handler, @Nullable SensorManager.SensorDataChangedObserver observer) {
this.context = context;
this.handler = handler;
this.observer = observer;
bluetoothAdapter = BluetoothUtils.getAdapter(context);
this.heartRate = new BluetoothConnectionManagerHeartRate(observer);
this.cyclingCadence = new BluetoothConnectionManagerCyclingCadence(observer);
this.cyclingSpeed = new BluetoothConnectionManagerCyclingDistanceSpeed(observer);
this.cyclingPower = new BluetoothConnectionManagerCyclingPower(observer);
this.runningSpeedAndCadence = new BluetoothConnectionRunningSpeedAndCadence(observer);
}
@Override
@@ -120,28 +124,12 @@ public class BluetoothRemoteSensorManager implements SensorConnector, AbstractBl
Log.i(TAG, "Connecting to bluetooth address: " + address);
try {
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(address);
connectionManager.connect(context, device);
connectionManager.connect(context, handler, device);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Unable to get remote device for: " + address, e);
}
}
@Override
public synchronized void onChanged(SensorData<?> sensorData) {
observer.onChange(sensorData);
}
@Override
public void onDisconnecting(SensorData<?> sensorData) {
observer.onDisconnect(sensorData);
}
@NonNull
@Override
public Handler getHandler() {
return handler;
}
@Override
public void onSharedPreferenceChanged(SharedPreferences unused, @Nullable String key) {
if (!started) return;
@@ -91,8 +91,8 @@ public class SensorManager implements SharedPreferences.OnSharedPreferenceChange
@Deprecated
@VisibleForTesting
public BluetoothRemoteSensorManager getBluetoothSensorManager() {
return bluetoothSensorManager;
public void onChanged(SensorData<?> data) {
listener.onChange(data);
}
public GPSManager getGpsManager() {