Bluetooth: use TrackRecording handler for callback.

Otherwise the thread is not defined and a SecurityException may be triggered when inserting data into the ContentProvider.
Sadly, below API26 this needs to be done manually.

Fixes #1165.
This commit is contained in:
Dennis Guse
2022-05-05 19:14:19 +02:00
parent a77b7a0626
commit 40d2bf0c22
7 changed files with 35 additions and 12 deletions
@@ -162,7 +162,7 @@ public class ExportImportTest {
service.insertMarker("Marker 2", "Marker 2 category", "Marker 2 desc", null);
trackPointCreator.setClock("2020-02-02T02:02:06Z");
trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context, trackPointCreator));
trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context, null, trackPointCreator));
service.pauseCurrentTrack();
trackPointCreator.setClock("2020-02-02T02:02:20Z");
@@ -175,7 +175,7 @@ public class ExportImportTest {
sendLocation(trackPointCreator, "2020-02-02T02:02:23Z", 3, 16.001, 10, 27, 15, 10, 0);
trackPointCreator.setClock("2020-02-02T02:02:24Z");
trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context, trackPointCreator));
trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context, null, trackPointCreator));
service.endCurrentTrack();
Track track = contentProviderUtils.getTrack(trackId);
@@ -492,7 +492,7 @@ public class ExportImportTest {
}
private void mockBLESensorData(TrackPointCreator trackPointCreator, Float speed, Distance distance, float heartRate, float cadence, Float power) {
trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context, trackPointCreator) {
trackPointCreator.setRemoteSensorManager(new BluetoothRemoteSensorManager(context, null, trackPointCreator) {
@Override
public SensorDataSet fill(@NonNull TrackPoint trackPoint) {
SensorDataSet sensorDataSet = new SensorDataSet();
@@ -27,7 +27,7 @@ public class TrackRecordingServiceTestUtils {
TrackRecordingService service = ((TrackRecordingService.Binder) mServiceRule.bindService(new Intent(context, TrackRecordingService.class)))
.getService();
service.getTrackPointCreator().setRemoteSensorManager(new BluetoothRemoteSensorManager(context, service.getTrackPointCreator()));
service.getTrackPointCreator().setRemoteSensorManager(new BluetoothRemoteSensorManager(context, null, service.getTrackPointCreator()));
service.getTrackPointCreator().setClock(Clock.systemUTC());
service.endCurrentTrack();
}
@@ -32,7 +32,7 @@ public class TrackPointCreatorTest {
@Before
public void setUp() {
subject = new TrackPointCreator(locationHandler, server);
subject.start(context);
subject.start(context, null);
}
@After
@@ -24,6 +24,8 @@ import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.os.Build;
import android.os.Handler;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -110,7 +112,12 @@ public abstract class BluetoothConnectionManager<DataType> {
SensorData<DataType> sensorData = parsePayload(gatt.getDevice().getName(), gatt.getDevice().getAddress(), characteristic);
if (sensorData != null) {
Log.d(TAG, "Decoded data from " + gatt.getDevice().getAddress() + ": " + sensorData);
observer.onChanged(sensorData);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
observer.onChanged(sensorData);
} else {
//TODO This might lead to NPEs in case of race conditions due to shutdown.
observer.getHandler().post(() -> observer.onChanged(sensorData));
}
}
}
};
@@ -128,7 +135,11 @@ public abstract class BluetoothConnectionManager<DataType> {
Log.d(TAG, "Connecting to: " + device);
bluetoothGatt = device.connectGatt(context, true, connectCallback);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
bluetoothGatt = device.connectGatt(context, true, connectCallback, BluetoothDevice.TRANSPORT_AUTO, 0, this.observer.getHandler());
} else {
bluetoothGatt = device.connectGatt(context, true, connectCallback);
}
SensorData<?> sensorData = createEmptySensorData(bluetoothGatt.getDevice().getAddress());
observer.onChanged(sensorData);
}
@@ -275,5 +286,8 @@ public abstract class BluetoothConnectionManager<DataType> {
void onChanged(SensorData<?> sensorData);
void onDisconnecting(SensorData<?> sensorData);
@NonNull
Handler getHandler();
}
}
@@ -20,6 +20,7 @@ import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Handler;
import android.util.Log;
import androidx.annotation.NonNull;
@@ -57,7 +58,7 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
private final BluetoothAdapter bluetoothAdapter;
private final Context context;
private final Handler handler;
private boolean started = false;
private Distance preferenceWheelCircumference;
@@ -111,8 +112,9 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
}
};
public BluetoothRemoteSensorManager(@NonNull Context context, @NonNull SensorDataSetChangeObserver observer) {
public BluetoothRemoteSensorManager(@NonNull Context context, @NonNull Handler handler, @NonNull SensorDataSetChangeObserver observer) {
this.context = context;
this.handler = handler;
this.observer = observer;
bluetoothAdapter = BluetoothUtils.getAdapter(context);
}
@@ -218,6 +220,12 @@ public class BluetoothRemoteSensorManager implements BluetoothConnectionManager.
sensorDataSet.remove(sensorData);
}
@NonNull
@Override
public Handler getHandler() {
return handler;
}
public interface SensorDataSetChangeObserver {
void onChange(SensorDataSet sensorDataSet);
}
@@ -211,7 +211,7 @@ public class TrackRecordingService extends Service implements TrackPointCreator.
private void startSensors() {
wakeLock = SystemUtils.acquireWakeLock(this, wakeLock);
trackPointCreator.start(this);
trackPointCreator.start(this, handler);
showNotification(true);
}
@@ -2,6 +2,7 @@ package de.dennisguse.opentracks.services.handlers;
import android.content.Context;
import android.location.Location;
import android.os.Handler;
import android.util.Log;
import android.util.Pair;
@@ -48,12 +49,12 @@ public class TrackPointCreator implements BluetoothRemoteSensorManager.SensorDat
this.gpsHandler = gpsHandler;
}
public synchronized void start(@NonNull Context context) {
public synchronized void start(@NonNull Context context, @NonNull Handler handler) {
this.context = context;
gpsHandler.onStart(context);
remoteSensorManager = new BluetoothRemoteSensorManager(context, this);
remoteSensorManager = new BluetoothRemoteSensorManager(context, handler, this);
altitudeSumManager = new AltitudeSumManager();
remoteSensorManager.start();