Commit 2a79efd6 authored by Dirk Steinkopf's avatar Dirk Steinkopf

add mutex around complete onLocation routine - incl. backend call

parent e6c654b7
......@@ -31,6 +31,7 @@
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/mime-0.9.6/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/mockito-2.2.3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/multi_server_socket-1.0.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/mutex-0.0.1/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/node_preamble-1.4.0/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_config-1.0.3/lib" />
<root url="file://$USER_HOME$/.pub-cache/hosted/pub.dartlang.org/package_info-0.3.0/lib" />
......
......@@ -4,6 +4,7 @@ import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'dart:async';
import 'package:synchronized/synchronized.dart';
import 'package:mutex/mutex.dart';
import 'backend.dart';
import 'user_registration.dart';
......@@ -65,6 +66,8 @@ class _TueraufHomePageState extends State<TueraufHomePage> with WidgetsBindingOb
String _fullVersion;
final TextEditingController _pinEntryController = new TextEditingController();
final locationMutex = new Mutex();
FocusNode _focusNodePinEntry;
UserRegistration _userRegistration;
......@@ -366,6 +369,14 @@ class _TueraufHomePageState extends State<TueraufHomePage> with WidgetsBindingOb
Future _initLocationTracking() async {
if (_locationSubscription == null) {
setState(() {
_gotGeolocation = false;
_neverSetGotGeolocation = true;
_isNear = false;
_isFar = false;
_nextTimeCheckLocation = null;
});
debugPrint("_initLocationTracking: listen");
_locationSubscription = _locationService.onLocationChanged.listen(_onLocationUpdate);
......@@ -387,50 +398,56 @@ class _TueraufHomePageState extends State<TueraufHomePage> with WidgetsBindingOb
}
}
void _onLocationUpdate(Map<String, double> newLocation) {
// debugPrint("${new DateTime.now().toIso8601String()}: _onLocationUpdate: newLocation=$newLocation");
// only run _onLocationUpdateSynchronized once - second parallel calls are just dropped (timeout 0)
synchronized(this, () async {
_onLocationUpdateSynchronized(newLocation);
}, timeout: Duration.zero);
}
Future _onLocationUpdate(Map<String, double> newLocation) async {
debugPrint("${new DateTime.now().toIso8601String()}: _onLocationUpdate: newLocation=$newLocation");
void _onLocationUpdateSynchronized(Map<String, double> newLocation) {
// debugPrint("${new DateTime.now().toIso8601String()}: _onLocationUpdateSynchronized: newLocation=$newLocation");
// only run once
await locationMutex.acquire();
if (_omitCheckLocation()) {
debugPrint("nextTimeChecklocation in future: no store and check location");
return;
}
var calledCheckLocation = false;
try {
if (_omitCheckLocation()) {
debugPrint("nextTimeChecklocation in future: no store and check location");
return;
}
final accuracy = newLocation["accuracy"];
final latitude = newLocation["latitude"];
final longitude = newLocation["longitude"];
// final altitude = newLocation["altitude"];
final accuracy = newLocation["accuracy"];
final latitude = newLocation["latitude"];
final longitude = newLocation["longitude"];
// final altitude = newLocation["altitude"];
if (accuracy > NEEDED_ACCURACY_IN_M) {
debugPrint("not accurate: accuracy=$accuracy - ignored");
if (accuracy > NEEDED_ACCURACY_IN_M) {
debugPrint("not accurate: accuracy=$accuracy - ignored");
setState(() {
_gotGeolocation = false;
// _neverSetGotGeolocation = false;
_isNear = false;
_isFar = false;
_updateResultLabelText("Ortsbestimmung zu ungenau");
});
return;
}
// got accurate location
setState(() {
_gotGeolocation = false;
// _neverSetGotGeolocation = false;
_isNear = false;
_isFar = false;
_updateResultLabelText("Ortsbestimmung zu ungenau");
final oldGotGeoLocation = _gotGeolocation;
_gotGeolocation = true;
if (!oldGotGeoLocation) {
_updateResultLabelText("Ort wurde bestimmt.");
}
_neverSetGotGeolocation = false;
});
return;
}
// got accurate location
setState(() {
final oldGotGeoLocation = _gotGeolocation;
_gotGeolocation = true;
if (!oldGotGeoLocation) {
_updateResultLabelText("Ort wurde bestimmt.");
// start call to backend:
_checkLocation(latitude, longitude).catchError(() {
locationMutex.release();
});
calledCheckLocation = true;
} finally {
if (!calledCheckLocation) {
locationMutex.release();
}
_neverSetGotGeolocation = false;
});
_checkLocation(latitude, longitude);
}
}
bool _omitCheckLocation() {
......@@ -441,35 +458,40 @@ class _TueraufHomePageState extends State<TueraufHomePage> with WidgetsBindingOb
return timeOver.isNegative;
}
void _checkLocation(final double geoy, final double geox) async {
Future _checkLocation(final double geoy, final double geox) async {
final UserRegistration userRegistration = await UserRegistration.getInstance();
final String installationId = await userRegistration.installationId;
Backend.getInstance().checkLocation(geoy, geox, installationId, activityHandler,
(bool isNear, bool isFar, String info) {
debugPrint("call to Backend.checkloc returned: isNear=$isNear, isFar=$isFar, info='$info'.");
final oldIsNear = _isNear;
final oldGotGeolocation = _gotGeolocation;
setState(() {
_isNear = isNear;
_isFar = isFar;
_gotGeolocation = true;
_updateResultLabelText((info != null && info.length > 4 ? info : "") +
(oldGotGeolocation ? "" : "BUG in Ortbestimmung") +
(_neverSetGotGeolocation ? "KEINE Ortsbestimmung möglich." : ""));
});
try {
debugPrint("call to Backend.checkloc returned: isNear=$isNear, isFar=$isFar, info='$info'.");
final oldIsNear = _isNear;
final oldGotGeolocation = _gotGeolocation;
setState(() {
_isNear = isNear;
_isFar = isFar;
_gotGeolocation = true;
_updateResultLabelText((info != null && info.length > 4 ? info : "") +
(oldGotGeolocation ? "" : "BUG in Ortbestimmung") +
(_neverSetGotGeolocation ? "KEINE Ortsbestimmung möglich." : ""));
});
if (_isNear) {
if (!_pendingOpenNow) {
_setFocus(true);
}
_geoy = geox;
_geox = geoy;
if (_isNear) {
if (!_pendingOpenNow) {
_setFocus(true);
}
_geoy = geox;
_geox = geoy;
if (!oldIsNear && _pendingOpenNow) {
openNow();
if (!oldIsNear && _pendingOpenNow) {
openNow();
}
}
_nextTimeCheckLocation =
new DateTime.now().add(_isNear ? TIME_TO_KEEP_NEAR_LOCATION : TIME_TO_KEEP_FAR_LOCATION);
} finally {
locationMutex.release();
}
_nextTimeCheckLocation = new DateTime.now().add(_isNear ? TIME_TO_KEEP_NEAR_LOCATION : TIME_TO_KEEP_FAR_LOCATION);
});
}
......
......@@ -221,6 +221,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
mutex:
dependency: "direct main"
description:
name: mutex
url: "https://pub.dartlang.org"
source: hosted
version: "0.0.1"
node_preamble:
dependency: transitive
description:
......
......@@ -17,6 +17,7 @@ dependencies:
shared_preferences: ^0.4.0
uuid: ^0.5.0
synchronized: ^1.4.0
mutex: ^0.0.1
dev_dependencies:
flutter_test:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment