forked from upstream-mirrors/OpenTracks
HandlerServer: use executor service to send data to TrackRecordingService.
Fixes #329.
This commit is contained in:
+63
@@ -0,0 +1,63 @@
|
|||||||
|
package de.dennisguse.opentracks.services.handlers;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
|
||||||
|
import org.junit.After;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||||
|
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class HandlerServerTest {
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private Context context;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private HandlerServer.HandlerServerInterface server;
|
||||||
|
|
||||||
|
@Mock
|
||||||
|
private LocationHandler locationHandler;
|
||||||
|
|
||||||
|
private HandlerServer subject;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() {
|
||||||
|
subject = new HandlerServer(locationHandler, server);
|
||||||
|
subject.start(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
public void tearDown() {
|
||||||
|
subject.stop(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void onSharedPreferenceChanged() {
|
||||||
|
// when
|
||||||
|
subject.onSharedPreferenceChanged(null, null, null);
|
||||||
|
|
||||||
|
// then
|
||||||
|
verify(locationHandler).onSharedPreferenceChanged(null, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void sendTrackPoint() throws InterruptedException {
|
||||||
|
// given
|
||||||
|
TrackPoint trackPoint = new TrackPoint();
|
||||||
|
int accuracy = 50;
|
||||||
|
|
||||||
|
// when
|
||||||
|
subject.sendTrackPoint(trackPoint, accuracy);
|
||||||
|
|
||||||
|
// then
|
||||||
|
Thread.sleep(10); // Wait for executor service
|
||||||
|
verify(server).newTrackPoint(trackPoint, accuracy);
|
||||||
|
}
|
||||||
|
}
|
||||||
+20
-31
@@ -5,29 +5,32 @@ import android.content.SharedPreferences;
|
|||||||
import android.location.Location;
|
import android.location.Location;
|
||||||
|
|
||||||
import androidx.test.core.app.ApplicationProvider;
|
import androidx.test.core.app.ApplicationProvider;
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
|
||||||
|
|
||||||
import org.junit.After;
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.InjectMocks;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.junit.MockitoJUnitRunner;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||||
import de.dennisguse.opentracks.services.TrackRecordingService;
|
|
||||||
import de.dennisguse.opentracks.util.PreferencesUtils;
|
import de.dennisguse.opentracks.util.PreferencesUtils;
|
||||||
|
|
||||||
import static org.mockito.ArgumentMatchers.any;
|
import static org.mockito.ArgumentMatchers.any;
|
||||||
import static org.mockito.Mockito.times;
|
import static org.mockito.Mockito.times;
|
||||||
import static org.mockito.Mockito.verify;
|
import static org.mockito.Mockito.verify;
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class LocationHandlerTest {
|
public class LocationHandlerTest {
|
||||||
|
|
||||||
private final Context context = ApplicationProvider.getApplicationContext();
|
private final Context context = ApplicationProvider.getApplicationContext();
|
||||||
|
|
||||||
|
@Mock
|
||||||
private HandlerServer handlerServer;
|
private HandlerServer handlerServer;
|
||||||
|
|
||||||
|
@InjectMocks
|
||||||
private LocationHandler locationHandler;
|
private LocationHandler locationHandler;
|
||||||
private TrackRecordingService mockService;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() {
|
public void setUp() {
|
||||||
@@ -35,18 +38,9 @@ public class LocationHandlerTest {
|
|||||||
SharedPreferences sharedPreferences = PreferencesUtils.getSharedPreferences(context);
|
SharedPreferences sharedPreferences = PreferencesUtils.getSharedPreferences(context);
|
||||||
sharedPreferences.edit().clear().commit();
|
sharedPreferences.edit().clear().commit();
|
||||||
|
|
||||||
mockService = Mockito.mock(TrackRecordingService.class);
|
|
||||||
handlerServer = new HandlerServer(mockService);
|
|
||||||
locationHandler = new LocationHandler(handlerServer);
|
|
||||||
locationHandler.onSharedPreferenceChanged(context, PreferencesUtils.getSharedPreferences(context), context.getString(R.string.recording_gps_accuracy_key));
|
locationHandler.onSharedPreferenceChanged(context, PreferencesUtils.getSharedPreferences(context), context.getString(R.string.recording_gps_accuracy_key));
|
||||||
locationHandler.onSharedPreferenceChanged(context, PreferencesUtils.getSharedPreferences(context), context.getString(R.string.min_recording_interval_key));
|
locationHandler.onSharedPreferenceChanged(context, PreferencesUtils.getSharedPreferences(context), context.getString(R.string.min_recording_interval_key));
|
||||||
}
|
locationHandler.onStart(context);
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
mockService = null;
|
|
||||||
handlerServer = null;
|
|
||||||
locationHandler = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -58,7 +52,7 @@ public class LocationHandlerTest {
|
|||||||
locationHandler.onLocationChanged(createLocation(45f, 35f, 3, 5, System.currentTimeMillis()));
|
locationHandler.onLocationChanged(createLocation(45f, 35f, 3, 5, System.currentTimeMillis()));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify(mockService, times(1)).newTrackPoint(any(TrackPoint.class), any(Integer.class));
|
verify(handlerServer, times(1)).sendTrackPoint(any(TrackPoint.class), any(Integer.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -74,7 +68,7 @@ public class LocationHandlerTest {
|
|||||||
locationHandler.onLocationChanged(createLocation(latitude, 35f, 3, 5, System.currentTimeMillis()));
|
locationHandler.onLocationChanged(createLocation(latitude, 35f, 3, 5, System.currentTimeMillis()));
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify(mockService, times(0)).newTrackPoint(any(TrackPoint.class), any(Integer.class));
|
verify(handlerServer, times(0)).sendTrackPoint(any(TrackPoint.class), any(Integer.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -91,25 +85,20 @@ public class LocationHandlerTest {
|
|||||||
|
|
||||||
// then
|
// then
|
||||||
// no newTrackPoint called
|
// no newTrackPoint called
|
||||||
verify(mockService, times(0)).newTrackPoint(any(TrackPoint.class), any(Integer.class));
|
verify(handlerServer, times(0)).sendTrackPoint(any(TrackPoint.class), any(Integer.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testOnLocationChanged_movingInaccurate() throws Exception {
|
public void testOnLocationChanged_movingInaccurate() {
|
||||||
// when
|
// when
|
||||||
locationHandler.onLocationChanged(
|
locationHandler.onLocationChanged(createLocation(45.0, 35.0, 5, 15, System.currentTimeMillis()));
|
||||||
createLocation(45.0, 35.0, 5, 15, System.currentTimeMillis()));
|
locationHandler.onLocationChanged(createLocation(45.1, 35.0, Long.MAX_VALUE, 15, System.currentTimeMillis()));
|
||||||
locationHandler.onLocationChanged(
|
locationHandler.onLocationChanged(createLocation(45.2, 35.0, Long.MAX_VALUE, 15, System.currentTimeMillis()));
|
||||||
createLocation(45.1, 35.0, Long.MAX_VALUE, 15, System.currentTimeMillis()));
|
locationHandler.onLocationChanged(createLocation(45.3, 35.0, Long.MAX_VALUE, 15, System.currentTimeMillis()));
|
||||||
locationHandler.onLocationChanged(
|
locationHandler.onLocationChanged(createLocation(99.0, 35.0, Long.MAX_VALUE, 15, System.currentTimeMillis()));
|
||||||
createLocation(45.2, 35.0, Long.MAX_VALUE, 15, System.currentTimeMillis()));
|
|
||||||
locationHandler.onLocationChanged(
|
|
||||||
createLocation(45.3, 35.0, Long.MAX_VALUE, 15, System.currentTimeMillis()));
|
|
||||||
locationHandler.onLocationChanged(
|
|
||||||
createLocation(99.0, 35.0, Long.MAX_VALUE, 15, System.currentTimeMillis()));
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
verify(mockService, times(1)).newTrackPoint(any(TrackPoint.class), any(Integer.class));
|
verify(handlerServer, times(1)).sendTrackPoint(any(TrackPoint.class), any(Integer.class));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -3,26 +3,46 @@ package de.dennisguse.opentracks.services.handlers;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.content.data.TrackPoint;
|
import de.dennisguse.opentracks.content.data.TrackPoint;
|
||||||
|
|
||||||
public class HandlerServer {
|
public class HandlerServer {
|
||||||
private String TAG = HandlerServer.class.getSimpleName();
|
|
||||||
|
private static String TAG = HandlerServer.class.getSimpleName();
|
||||||
|
|
||||||
private final LocationHandler locationHandler;
|
private final LocationHandler locationHandler;
|
||||||
private final HandlerServerInterface service;
|
private final HandlerServerInterface service;
|
||||||
|
private ExecutorService serviceExecutor;
|
||||||
|
|
||||||
public HandlerServer(HandlerServerInterface service) {
|
public HandlerServer(HandlerServerInterface service) {
|
||||||
this.locationHandler = new LocationHandler(this);
|
this.locationHandler = new LocationHandler(this);
|
||||||
this.service = service;
|
this.service = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisibleForTesting
|
||||||
|
HandlerServer(LocationHandler locationHandler, HandlerServerInterface service) {
|
||||||
|
this.locationHandler = locationHandler;
|
||||||
|
this.service = service;
|
||||||
|
}
|
||||||
|
|
||||||
public void start(Context context) {
|
public void start(Context context) {
|
||||||
|
serviceExecutor = Executors.newSingleThreadExecutor();
|
||||||
|
|
||||||
locationHandler.onStart(context);
|
locationHandler.onStart(context);
|
||||||
locationHandler.onSharedPreferenceChanged(context, null, null);
|
locationHandler.onSharedPreferenceChanged(context, null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop(Context context) {
|
public void stop(Context context) {
|
||||||
locationHandler.onStop(context);
|
locationHandler.onStop(context);
|
||||||
|
|
||||||
|
if (serviceExecutor != null) {
|
||||||
|
serviceExecutor.shutdownNow();
|
||||||
|
}
|
||||||
|
serviceExecutor = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onSharedPreferenceChanged(Context context, SharedPreferences preferences, String key) {
|
public void onSharedPreferenceChanged(Context context, SharedPreferences preferences, String key) {
|
||||||
@@ -30,7 +50,10 @@ public class HandlerServer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void sendTrackPoint(TrackPoint trackPoint, int recordingGpsAccuracy) {
|
public void sendTrackPoint(TrackPoint trackPoint, int recordingGpsAccuracy) {
|
||||||
service.newTrackPoint(trackPoint, recordingGpsAccuracy);
|
if (serviceExecutor == null || serviceExecutor.isTerminated() || serviceExecutor.isShutdown()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
serviceExecutor.execute(() -> service.newTrackPoint(trackPoint, recordingGpsAccuracy));
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface HandlerServerInterface {
|
public interface HandlerServerInterface {
|
||||||
|
|||||||
@@ -67,31 +67,13 @@ class LocationHandler implements HandlerServer.Handler, LocationListener {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onLocationChanged(@NonNull Location location) {
|
|
||||||
// TODO do we still need to process the location processing in an asynchronous manner? Let's go to check it out.
|
|
||||||
computeLocation(location);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onStatusChanged(String provider, int status, Bundle extras) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onProviderEnabled(@NonNull String provider) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onProviderDisabled(@NonNull String provider) {
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks if location is valid and builds a track point that will be send through HandlerServer.
|
* Checks if location is valid and builds a track point that will be send through HandlerServer.
|
||||||
*
|
*
|
||||||
* @param location {@link Location} object.
|
* @param location {@link Location} object.
|
||||||
*/
|
*/
|
||||||
private void computeLocation(Location location) {
|
@Override
|
||||||
|
public void onLocationChanged(@NonNull Location location) {
|
||||||
if (!LocationUtils.isValidLocation(location)) {
|
if (!LocationUtils.isValidLocation(location)) {
|
||||||
Log.w(TAG, "Ignore newTrackPoint. location is invalid.");
|
Log.w(TAG, "Ignore newTrackPoint. location is invalid.");
|
||||||
return;
|
return;
|
||||||
@@ -118,6 +100,18 @@ class LocationHandler implements HandlerServer.Handler, LocationListener {
|
|||||||
handlerServer.sendTrackPoint(trackPoint, recordingGpsAccuracy);
|
handlerServer.sendTrackPoint(trackPoint, recordingGpsAccuracy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStatusChanged(String provider, int status, Bundle extras) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProviderEnabled(@NonNull String provider) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onProviderDisabled(@NonNull String provider) {
|
||||||
|
}
|
||||||
|
|
||||||
private void registerLocationListener() {
|
private void registerLocationListener() {
|
||||||
if (locationManager == null) {
|
if (locationManager == null) {
|
||||||
Log.e(TAG, "locationManager is null.");
|
Log.e(TAG, "locationManager is null.");
|
||||||
|
|||||||
Reference in New Issue
Block a user