summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@digia.com>2014-05-22 12:14:11 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2014-05-23 15:28:43 +0200
commit749cdff5289412780f0bb8e351cb140ba64d85ce (patch)
tree0a218bfb326b9ab566369779495f5007815e44d0
parent5d6f97ed9450b88098e425d4cf963655b3508248 (diff)
downloadqtlocation-749cdff5289412780f0bb8e351cb140ba64d85ce.tar.gz
Fix crash on S4 when running Satellite and Position updates concurrently
This was caused due to unsynchronized access of data between two threads. The Java satellite updates were sent before the receiving Qt thread could finish its regular startup. As a consequence the received updates could not be mapped to a receiving C++ class. This patch synchronizes the startup and setup of the two threads and ensures that the relvant data setup on the C++ side is done before the update thread is started. In addition some minor debug helpers were added for future references. Task-number: QTBUG-39082 Change-Id: I1f24ddfcef038fa000801ddb6a3ea0959370f0d3 Reviewed-by: Eskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@digia.com>
-rw-r--r--src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java30
-rw-r--r--src/plugins/position/android/src/jnipositioning.cpp4
2 files changed, 23 insertions, 11 deletions
diff --git a/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java b/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java
index f5725813..f2babd08 100644
--- a/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java
+++ b/src/plugins/position/android/jar/src/org/qtproject/qt5/android/positioning/QtPositioning.java
@@ -187,17 +187,18 @@ public class QtPositioning implements LocationListener
try {
boolean exceptionOccurred = false;
QtPositioning positioningListener = new QtPositioning();
- positioningListener.setActiveLooper(true);
positioningListener.nativeClassReference = androidClassKey;
positioningListener.expectedProviders = locationProvider;
positioningListener.isSatelliteUpdate = false;
+ //start update thread
+ positioningListener.setActiveLooper(true);
if (updateInterval == 0)
updateInterval = 1000; //don't update more often than once per second
positioningListener.updateIntervalTime = updateInterval;
if ((locationProvider & QT_GPS_PROVIDER) > 0) {
- Log.d(TAG, "Regular updates using GPS");
+ Log.d(TAG, "Regular updates using GPS " + updateInterval);
try {
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
updateInterval, 0,
@@ -210,7 +211,7 @@ public class QtPositioning implements LocationListener
}
if ((locationProvider & QT_NETWORK_PROVIDER) > 0) {
- Log.d(TAG, "Regular updates using network");
+ Log.d(TAG, "Regular updates using network " + updateInterval);
try {
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
updateInterval, 0,
@@ -263,11 +264,12 @@ public class QtPositioning implements LocationListener
try {
boolean exceptionOccurred = false;
QtPositioning positioningListener = new QtPositioning();
- positioningListener.setActiveLooper(true);
positioningListener.nativeClassReference = androidClassKey;
positioningListener.isSingleUpdate = true;
positioningListener.expectedProviders = locationProvider;
positioningListener.isSatelliteUpdate = false;
+ //start update thread
+ positioningListener.setActiveLooper(true);
if ((locationProvider & QT_GPS_PROVIDER) > 0) {
Log.d(TAG, "Single update using GPS");
@@ -321,10 +323,11 @@ public class QtPositioning implements LocationListener
boolean exceptionOccurred = false;
QtPositioning positioningListener = new QtPositioning();
positioningListener.isSatelliteUpdate = true;
- positioningListener.setActiveLooper(true);
positioningListener.nativeClassReference = androidClassKey;
positioningListener.expectedProviders = 1; //always satellite provider
positioningListener.isSingleUpdate = isSingleRequest;
+ //start update thread
+ positioningListener.setActiveLooper(true);
if (updateInterval == 0)
updateInterval = 1000; //don't update more often than once per second
@@ -385,9 +388,14 @@ public class QtPositioning implements LocationListener
if (isSatelliteUpdate)
looperThread.isSatelliteListener(true);
+ long start = System.currentTimeMillis();
looperThread.start();
+
+ //busy wait but lasts ~20-30 ms only
while (!looperThread.isReady());
- Thread.sleep(1000);
+
+ long stop = System.currentTimeMillis();
+ Log.d(TAG, "Looper Thread startup time in ms: " + (stop-start));
} else {
looperThread.quitLooper();
}
@@ -411,7 +419,6 @@ public class QtPositioning implements LocationListener
{
Looper.prepare();
Handler handler = new Handler();
- looperRunning = true;
if (isSatelliteLooper) {
try {
@@ -422,8 +429,13 @@ public class QtPositioning implements LocationListener
}
posLooper = Looper.myLooper();
+ synchronized (this) {
+ looperRunning = true;
+ }
Looper.loop();
- looperRunning = false;
+ synchronized (this) {
+ looperRunning = false;
+ }
}
public void quitLooper()
@@ -433,7 +445,7 @@ public class QtPositioning implements LocationListener
looper().quit();
}
- public boolean isReady()
+ public synchronized boolean isReady()
{
return looperRunning;
}
diff --git a/src/plugins/position/android/src/jnipositioning.cpp b/src/plugins/position/android/src/jnipositioning.cpp
index afae1c8e..d3cce65b 100644
--- a/src/plugins/position/android/src/jnipositioning.cpp
+++ b/src/plugins/position/android/src/jnipositioning.cpp
@@ -459,7 +459,7 @@ static void positionUpdated(JNIEnv *env, jobject /*thiz*/, jobject location, jin
QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey);
if (!source) {
- qFatal("positionUpdated: source == 0");
+ qWarning("positionUpdated: source == 0");
return;
}
@@ -479,7 +479,7 @@ static void locationProvidersDisabled(JNIEnv *env, jobject /*thiz*/, jint androi
if (!source)
source = AndroidPositioning::idToSatSource()->value(androidClassKey);
if (!source) {
- qFatal("locationProvidersDisabled: source == 0");
+ qWarning("locationProvidersDisabled: source == 0");
return;
}