diff options
Diffstat (limited to 'src/plugins/position/android')
17 files changed, 0 insertions, 2401 deletions
diff --git a/src/plugins/position/android/CMakeLists.txt b/src/plugins/position/android/CMakeLists.txt deleted file mode 100644 index 22fe2b6b..00000000 --- a/src/plugins/position/android/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Generated from android.pro. - -add_subdirectory(jar) -add_subdirectory(src) diff --git a/src/plugins/position/android/android.pro b/src/plugins/position/android/android.pro deleted file mode 100644 index 0dc6a3fc..00000000 --- a/src/plugins/position/android/android.pro +++ /dev/null @@ -1,2 +0,0 @@ -TEMPLATE = subdirs -SUBDIRS += jar src diff --git a/src/plugins/position/android/jar/AndroidManifest.xml b/src/plugins/position/android/jar/AndroidManifest.xml deleted file mode 100644 index 2e847fd1..00000000 --- a/src/plugins/position/android/jar/AndroidManifest.xml +++ /dev/null @@ -1,6 +0,0 @@ -<manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="org.qtproject.qt.android.positioning" - android:versionCode="1" - android:versionName="1.0" > - <supports-screens android:smallScreens="true" android:largeScreens="true" android:anyDensity="true" android:normalScreens="true"/> -</manifest> diff --git a/src/plugins/position/android/jar/CMakeLists.txt b/src/plugins/position/android/jar/CMakeLists.txt deleted file mode 100644 index 8eadc79c..00000000 --- a/src/plugins/position/android/jar/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# Generated from jar.pro. - -set(java_sources - src/org/qtproject/qt/android/positioning/QtPositioning.java # special case -) - -qt_internal_add_jar(Qt${QtLocation_VERSION_MAJOR}AndroidPositioning # special case - INCLUDE_JARS ${QT_ANDROID_JAR} - SOURCES ${java_sources} - OUTPUT_DIR "${QT_BUILD_DIR}/jar" -) - -install_jar(Qt${QtLocation_VERSION_MAJOR}AndroidPositioning # special case - DESTINATION jar - COMPONENT Devel -) - diff --git a/src/plugins/position/android/jar/jar.pro b/src/plugins/position/android/jar/jar.pro deleted file mode 100644 index fae1f855..00000000 --- a/src/plugins/position/android/jar/jar.pro +++ /dev/null @@ -1,16 +0,0 @@ -TARGET = Qt$${QT_MAJOR_VERSION}AndroidPositioning - -load(qt_build_paths) - -CONFIG += java -DESTDIR = $$MODULE_BASE_OUTDIR/jar - -JAVACLASSPATH += $$PWD/src - -JAVASOURCES += \ - $$PWD/src/org/qtproject/qt/android/positioning/QtPositioning.java - -# install -target.path = $$[QT_INSTALL_PREFIX]/jar -INSTALLS += target - diff --git a/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java b/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java deleted file mode 100644 index 18ef40a2..00000000 --- a/src/plugins/position/android/jar/src/org/qtproject/qt/android/positioning/QtPositioning.java +++ /dev/null @@ -1,658 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtLocation of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -package org.qtproject.qt.android.positioning; - -import android.content.Context; -import android.location.GpsSatellite; -import android.location.GpsStatus; -import android.location.Location; -import android.location.LocationListener; -import android.location.LocationManager; -import android.location.GnssStatus; -import android.location.GnssStatus.Callback; -import android.os.Bundle; -import android.os.Handler; -import android.os.Looper; -import android.os.Build; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; - -import android.util.Log; - -public class QtPositioning implements LocationListener -{ - - private static final String TAG = "qt.positioning.android"; - static LocationManager locationManager = null; - static Object m_syncObject = new Object(); - static HashMap<Integer, QtPositioning> runningListeners = new HashMap<Integer, QtPositioning>(); - - /* - The positionInfo instance to which this - QtPositioning instance is attached to. - */ - private int nativeClassReference = 0; - - /* - The provider type requested by Qt - */ - private int expectedProviders = 0; - - public static final int QT_GPS_PROVIDER = 1; - public static final int QT_NETWORK_PROVIDER = 2; - - /* The following values must match the corresponding error enums in the Qt API*/ - public static final int QT_ACCESS_ERROR = 0; - public static final int QT_CLOSED_ERROR = 1; - public static final int QT_POSITION_UNKNOWN_SOURCE_ERROR = 2; - public static final int QT_POSITION_NO_ERROR = 3; - public static final int QT_SATELLITE_NO_ERROR = 2; - public static final int QT_SATELLITE_UNKNOWN_SOURCE_ERROR = -1; - - /* True, if updates were caused by requestUpdate() */ - private boolean isSingleUpdate = false; - /* The length requested for regular intervals in msec. */ - private int updateIntervalTime = 0; - - /* The last received GPS update */ - private Location lastGps = null; - /* The last received network update */ - private Location lastNetwork = null; - /* If true this class acts as satellite signal monitor rather than location monitor */ - private boolean isSatelliteUpdate = false; - - private PositioningLooperBase looperThread; - - private boolean isLocationProvidersDisabledInvoked = false; - - static public void setContext(Context context) - { - try { - locationManager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE); - } catch(Exception e) { - e.printStackTrace(); - } - } - - static private int[] providerList() - { - if (locationManager == null) { - Log.w(TAG, "No locationManager available in QtPositioning"); - return new int[0]; - } - List<String> providers = locationManager.getProviders(true); - int retList[] = new int[providers.size()]; - for (int i = 0; i < providers.size(); i++) { - if (providers.get(i).equals(LocationManager.GPS_PROVIDER)) { - //must be in sync with AndroidPositioning::PositionProvider::PROVIDER_GPS - retList[i] = 0; - } else if (providers.get(i).equals(LocationManager.NETWORK_PROVIDER)) { - //must be in sync with AndroidPositioning::PositionProvider::PROVIDER_NETWORK - retList[i] = 1; - } else if (providers.get(i).equals(LocationManager.PASSIVE_PROVIDER)) { - //must be in sync with AndroidPositioning::PositionProvider::PROVIDER_PASSIVE - retList[i] = 2; - } else { - retList[i] = -1; - } - } - return retList; - } - - static public Location lastKnownPosition(boolean fromSatelliteOnly) - { - Location gps = null; - Location network = null; - try { - gps = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); - if (!fromSatelliteOnly) - network = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER); - } catch(Exception e) { - e.printStackTrace(); - gps = network = null; - } - - if (gps != null && network != null) { - //we return the most recent location but slightly prefer GPS - //prefer GPS if it is max 4 hrs older than network - long delta = network.getTime() - gps.getTime(); - if (delta < 4*60*60*1000) { - return gps; - } else { - return network; - } - } else if (gps != null ) { - return gps; - } else if (network != null) { - return network; - } - - return null; - } - - /* Returns true if at least on of the given providers is enabled. */ - static private boolean expectedProvidersAvailable(int desiredProviders) - { - List<String> enabledProviders = locationManager.getProviders(true); - if ((desiredProviders & QT_GPS_PROVIDER) > 0) { //gps desired - if (enabledProviders.contains(LocationManager.GPS_PROVIDER)) { - return true; - } - } - if ((desiredProviders & QT_NETWORK_PROVIDER) > 0) { //network desired - if (enabledProviders.contains(LocationManager.NETWORK_PROVIDER)) { - return true; - } - } - - return false; - } - - - static private void addActiveListener(QtPositioning listener, String provider) - { - int androidClassKey = listener.nativeClassReference; - //start update thread - listener.setActiveLooper(true); - - if (runningListeners.containsKey(androidClassKey) && runningListeners.get(androidClassKey) != listener) { - removeActiveListener(androidClassKey); - } - - locationManager.requestSingleUpdate(provider, - listener, - listener.looper()); - - runningListeners.put(androidClassKey, listener); - } - - - static private void addActiveListener(QtPositioning listener, String provider, long minTime, float minDistance) - { - int androidClassKey = listener.nativeClassReference; - //start update thread - listener.setActiveLooper(true); - - if (runningListeners.containsKey(androidClassKey) && runningListeners.get(androidClassKey) != listener) { - removeActiveListener(androidClassKey); - } - - locationManager.requestLocationUpdates(provider, - minTime, minDistance, - listener, - listener.looper()); - - runningListeners.put(androidClassKey, listener); - } - - - static private void removeActiveListener(QtPositioning listener) - { - removeActiveListener(listener.nativeClassReference); - } - - - static private void removeActiveListener(int androidClassKey) - { - QtPositioning listener = runningListeners.remove(androidClassKey); - - if (listener != null) { - locationManager.removeUpdates(listener); - listener.setActiveLooper(false); - } - } - - - static public int startUpdates(int androidClassKey, int locationProvider, int updateInterval) - { - synchronized (m_syncObject) { - try { - boolean exceptionOccurred = false; - QtPositioning positioningListener = new QtPositioning(); - positioningListener.nativeClassReference = androidClassKey; - positioningListener.expectedProviders = locationProvider; - positioningListener.isSatelliteUpdate = false; - - if (updateInterval == 0) - updateInterval = 50; //don't update more often than once per 50ms - - positioningListener.updateIntervalTime = updateInterval; - if ((locationProvider & QT_GPS_PROVIDER) > 0) { - Log.d(TAG, "Regular updates using GPS " + updateInterval); - try { - addActiveListener(positioningListener, - LocationManager.GPS_PROVIDER, - updateInterval, 0); - } catch (SecurityException se) { - se.printStackTrace(); - exceptionOccurred = true; - } - } - - if ((locationProvider & QT_NETWORK_PROVIDER) > 0) { - Log.d(TAG, "Regular updates using network " + updateInterval); - try { - addActiveListener(positioningListener, - LocationManager.NETWORK_PROVIDER, - updateInterval, 0); - } catch (SecurityException se) { - se.printStackTrace(); - exceptionOccurred = true; - } - } - if (exceptionOccurred) { - removeActiveListener(positioningListener); - return QT_ACCESS_ERROR; - } - - if (!expectedProvidersAvailable(locationProvider)) { - //all location providers unavailbe -> when they come back we resume automatically - return QT_CLOSED_ERROR; - } - - } catch(Exception e) { - e.printStackTrace(); - return QT_POSITION_UNKNOWN_SOURCE_ERROR; - } - - return QT_POSITION_NO_ERROR; - } - } - - static public void stopUpdates(int androidClassKey) - { - synchronized (m_syncObject) { - try { - Log.d(TAG, "Stopping updates"); - removeActiveListener(androidClassKey); - } catch(Exception e) { - e.printStackTrace(); - return; - } - } - } - - static public int requestUpdate(int androidClassKey, int locationProvider) - { - synchronized (m_syncObject) { - try { - boolean exceptionOccurred = false; - QtPositioning positioningListener = new QtPositioning(); - positioningListener.nativeClassReference = androidClassKey; - positioningListener.isSingleUpdate = true; - positioningListener.expectedProviders = locationProvider; - positioningListener.isSatelliteUpdate = false; - - if ((locationProvider & QT_GPS_PROVIDER) > 0) { - Log.d(TAG, "Single update using GPS"); - try { - addActiveListener(positioningListener, LocationManager.GPS_PROVIDER); - } catch (SecurityException se) { - se.printStackTrace(); - exceptionOccurred = true; - } - } - - if ((locationProvider & QT_NETWORK_PROVIDER) > 0) { - Log.d(TAG, "Single update using network"); - try { - addActiveListener(positioningListener, LocationManager.NETWORK_PROVIDER); - } catch (SecurityException se) { - se.printStackTrace(); - exceptionOccurred = true; - } - } - if (exceptionOccurred) { - removeActiveListener(positioningListener); - return QT_ACCESS_ERROR; - } - - if (!expectedProvidersAvailable(locationProvider)) { - //all location providers unavailable -> when they come back we resume automatically - //in the mean time return ClosedError - return QT_CLOSED_ERROR; - } - - } catch(Exception e) { - e.printStackTrace(); - return QT_POSITION_UNKNOWN_SOURCE_ERROR; - } - - return QT_POSITION_NO_ERROR; - } - } - - static public int startSatelliteUpdates(int androidClassKey, int updateInterval, boolean isSingleRequest) - { - synchronized (m_syncObject) { - try { - boolean exceptionOccurred = false; - QtPositioning positioningListener = new QtPositioning(); - positioningListener.isSatelliteUpdate = true; - positioningListener.nativeClassReference = androidClassKey; - positioningListener.expectedProviders = 1; //always satellite provider - positioningListener.isSingleUpdate = isSingleRequest; - - if (updateInterval == 0) - updateInterval = 50; //don't update more often than once per 50ms - - if (isSingleRequest) - Log.d(TAG, "Single update for Satellites " + updateInterval); - else - Log.d(TAG, "Regular updates for Satellites " + updateInterval); - try { - addActiveListener(positioningListener, LocationManager.GPS_PROVIDER, - updateInterval, 0); - } catch (SecurityException se) { - se.printStackTrace(); - exceptionOccurred = true; - } - - if (exceptionOccurred) { - removeActiveListener(positioningListener); - return QT_ACCESS_ERROR; - } - - if (!expectedProvidersAvailable(positioningListener.expectedProviders)) { - //all location providers unavailable -> when they come back we resume automatically - //in the mean time return ClosedError - return QT_CLOSED_ERROR; - } - - } catch(Exception e) { - e.printStackTrace(); - return QT_SATELLITE_UNKNOWN_SOURCE_ERROR; - } - - return QT_SATELLITE_NO_ERROR; - } - } - - public QtPositioning() - { - // Use GpsStatus for API Level <= 23 (version M and below) and - // GnssStatus for other API levels. - if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) - looperThread = new PositioningLooperGps(); - else - looperThread = new PositioningLooperGnss(); - } - - public Looper looper() - { - return looperThread.looper(); - } - - private void setActiveLooper(boolean setActive) - { - try{ - if (setActive) { - if (looperThread.isAlive()) - return; - - if (isSatelliteUpdate) - looperThread.isSatelliteListener(true); - - long start = System.currentTimeMillis(); - looperThread.start(); - - //busy wait but lasts ~20-30 ms only - while (!looperThread.isReady()); - - long stop = System.currentTimeMillis(); - Log.d(TAG, "Looper Thread startup time in ms: " + (stop-start)); - } else { - looperThread.quitLooper(); - } - } catch(Exception e) { - e.printStackTrace(); - } - } - - private abstract class PositioningLooperBase extends Thread - { - private boolean looperRunning; - private Looper posLooper; - private boolean isSatelliteLooper = false; - - abstract protected void addSatelliteInfoListener(); - abstract protected void removeSatelliteInfoListener(); - - private PositioningLooperBase() - { - looperRunning = false; - } - - public void run() - { - Looper.prepare(); - Handler handler = new Handler(); - - if (isSatelliteLooper) - addSatelliteInfoListener(); - - posLooper = Looper.myLooper(); - synchronized (this) { - looperRunning = true; - } - Looper.loop(); - synchronized (this) { - looperRunning = false; - } - } - - public void quitLooper() - { - if (isSatelliteLooper) - removeSatelliteInfoListener(); - looper().quit(); - } - - public synchronized boolean isReady() - { - return looperRunning; - } - - public void isSatelliteListener(boolean isListener) - { - isSatelliteLooper = isListener; - } - - public Looper looper() - { - return posLooper; - } - - } - - private class PositioningLooperGps extends PositioningLooperBase implements GpsStatus.Listener - { - @Override - protected void addSatelliteInfoListener() - { - try { - locationManager.addGpsStatusListener(this); - } catch(Exception e) { - e.printStackTrace(); - } - } - - @Override - protected void removeSatelliteInfoListener() - { - locationManager.removeGpsStatusListener(this); - } - - @Override - public void onGpsStatusChanged(int event) { - switch (event) { - case GpsStatus.GPS_EVENT_FIRST_FIX: - break; - case GpsStatus.GPS_EVENT_SATELLITE_STATUS: - GpsStatus status = locationManager.getGpsStatus(null); - Iterable<GpsSatellite> iterable = status.getSatellites(); - Iterator<GpsSatellite> it = iterable.iterator(); - - ArrayList<GpsSatellite> list = new ArrayList<GpsSatellite>(); - while (it.hasNext()) { - GpsSatellite sat = (GpsSatellite) it.next(); - list.add(sat); - } - GpsSatellite[] sats = list.toArray(new GpsSatellite[list.size()]); - satelliteGpsUpdated(sats, nativeClassReference, isSingleUpdate); - - break; - case GpsStatus.GPS_EVENT_STARTED: - break; - case GpsStatus.GPS_EVENT_STOPPED: - break; - } - } - } - - private class PositioningGnssListener extends GnssStatus.Callback - { - @Override - public void onSatelliteStatusChanged(GnssStatus status) - { - satelliteGnssUpdated(status, nativeClassReference, isSingleUpdate); - } - } - - private class PositioningLooperGnss extends PositioningLooperBase - { - private PositioningGnssListener gnssListener; - - private PositioningLooperGnss() - { - gnssListener = new PositioningGnssListener(); - } - - @Override - protected void addSatelliteInfoListener() - { - try { - locationManager.registerGnssStatusCallback(gnssListener); - } catch(Exception e) { - e.printStackTrace(); - } - } - - @Override - protected void removeSatelliteInfoListener() - { - locationManager.unregisterGnssStatusCallback(gnssListener); - } - } - - public static native void positionUpdated(Location update, int androidClassKey, boolean isSingleUpdate); - public static native void locationProvidersDisabled(int androidClassKey); - public static native void locationProvidersChanged(int androidClassKey); - public static native void satelliteGpsUpdated(GpsSatellite[] update, int androidClassKey, boolean isSingleUpdate); - public static native void satelliteGnssUpdated(GnssStatus update, int androidClassKey, boolean isSingleUpdate); - - @Override - public void onLocationChanged(Location location) { - //Log.d(TAG, "**** Position Update ****: " + location.toString() + " " + isSingleUpdate); - if (location == null) - return; - - if (isSatelliteUpdate) //we are a QGeoSatelliteInfoSource -> ignore - return; - - if (isSingleUpdate || expectedProviders < 3) { - positionUpdated(location, nativeClassReference, isSingleUpdate); - return; - } - - /* - We can use GPS and Network, pick the better location provider. - Generally we prefer GPS data due to their higher accurancy but we - let Network data pass until GPS fix is available - */ - - if (location.getProvider().equals(LocationManager.GPS_PROVIDER)) { - lastGps = location; - - // assumption: GPS always better -> pass it on - positionUpdated(location, nativeClassReference, isSingleUpdate); - } else if (location.getProvider().equals(LocationManager.NETWORK_PROVIDER)) { - lastNetwork = location; - - if (lastGps == null) { //no GPS fix yet use network location - positionUpdated(location, nativeClassReference, isSingleUpdate); - return; - } - - long delta = location.getTime() - lastGps.getTime(); - - // Ignore if network update is older than last GPS (delta < 0) - // Ignore if gps update still has time to provide next location (delta < updateInterval) - if (delta < updateIntervalTime) - return; - - // Use network data -> GPS has timed out on updateInterval - positionUpdated(location, nativeClassReference, isSingleUpdate); - } - } - - @Override - public void onStatusChanged(String provider, int status, Bundle extras) {} - - @Override - public void onProviderEnabled(String provider) { - Log.d(TAG, "Enabled provider: " + provider); - locationProvidersChanged(nativeClassReference); - if (isLocationProvidersDisabledInvoked && expectedProvidersAvailable(expectedProviders)) - isLocationProvidersDisabledInvoked = false; - } - - @Override - public void onProviderDisabled(String provider) { - Log.d(TAG, "Disabled provider: " + provider); - locationProvidersChanged(nativeClassReference); - if (!isLocationProvidersDisabledInvoked && !expectedProvidersAvailable(expectedProviders)) { - isLocationProvidersDisabledInvoked = true; - locationProvidersDisabled(nativeClassReference); - } - } -} diff --git a/src/plugins/position/android/src/CMakeLists.txt b/src/plugins/position/android/src/CMakeLists.txt deleted file mode 100644 index b91181f4..00000000 --- a/src/plugins/position/android/src/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -# Generated from src.pro. - -##################################################################### -## QGeoPositionInfoSourceFactoryAndroid Plugin: -##################################################################### - -qt_internal_add_plugin(QGeoPositionInfoSourceFactoryAndroidPlugin - OUTPUT_NAME qtposition_android - CLASS_NAME QGeoPositionInfoSourceFactoryAndroid - PLUGIN_TYPE position - SOURCES - jnipositioning.cpp jnipositioning.h - positionfactory_android.cpp positionfactory_android.h - qgeopositioninfosource_android.cpp qgeopositioninfosource_android_p.h - qgeosatelliteinfosource_android.cpp qgeosatelliteinfosource_android_p.h - LIBRARIES - Qt::Core - Qt::CorePrivate - Qt::Positioning -) - -#### Keys ignored in scope 1:.:.:src.pro:<TRUE>: -# OTHER_FILES = "plugin.json" diff --git a/src/plugins/position/android/src/jnipositioning.cpp b/src/plugins/position/android/src/jnipositioning.cpp deleted file mode 100644 index 5f87d08b..00000000 --- a/src/plugins/position/android/src/jnipositioning.cpp +++ /dev/null @@ -1,741 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QDateTime> -#include <QMap> -#include <QRandomGenerator> -#include <QGeoPositionInfo> -#include <QJniEnvironment> -#include <QJniObject> -#include <QtCore/private/qandroidextras_p.h> -#include <QCoreApplication> -#include <android/log.h> -#include "qgeopositioninfosource_android_p.h" -#include "qgeosatelliteinfosource_android_p.h" -#include "jnipositioning.h" - -class GlobalClassRefWrapper -{ -public: - GlobalClassRefWrapper() = default; - ~GlobalClassRefWrapper() - { - if (m_classRef) { - QJniEnvironment env; - if (env.jniEnv()) - env->DeleteGlobalRef(m_classRef); - } - } - - bool init(const char *className) - { - QJniEnvironment env; - if (env.jniEnv()) { - if (m_classRef) { - env->DeleteGlobalRef(m_classRef); - m_classRef = nullptr; - } - - m_classRef = env.findClass(className); // it returns global ref! - } - return m_classRef != nullptr; - } - - jclass operator()() { return m_classRef; } - -private: - jclass m_classRef = nullptr; -}; - -static GlobalClassRefWrapper positioningClass; - -static jmethodID providerListMethodId; -static jmethodID lastKnownPositionMethodId; -static jmethodID startUpdatesMethodId; -static jmethodID stopUpdatesMethodId; -static jmethodID requestUpdateMethodId; -static jmethodID startSatelliteUpdatesMethodId; - -static const char logTag[] = "qt.positioning.android"; -static const char methodErrorMsg[] = "Can't find method \"%s%s\""; - -Q_LOGGING_CATEGORY(lcPositioning, logTag) - -namespace { - -/*! - \internal - This class encapsulates satellite system types, as defined by Android - GnssStatus API. Initialize during JNI_OnLoad() by the init() method, from - the Java side, rather than hard-coding. -*/ -class ConstellationMapper -{ -public: - static bool init() - { - m_gnssStatusObject = nullptr; - if (QNativeInterface::QAndroidApplication::sdkVersion() > 23) { - m_gnssStatusObject = QJniEnvironment().findClass("android/location/GnssStatus"); - if (!m_gnssStatusObject) - return false; - } - // no need to query it for API level <= 23 - return true; - } - - static QGeoSatelliteInfo::SatelliteSystem toSatelliteSystem(int constellationType) - { - if (!m_gnssStatusObject) - return QGeoSatelliteInfo::Undefined; - - static const int gps = - QJniObject::getStaticField<jint>(m_gnssStatusObject, "CONSTELLATION_GPS"); - static const int glonass = - QJniObject::getStaticField<jint>(m_gnssStatusObject, "CONSTELLATION_GLONASS"); - static const int galileo = - QJniObject::getStaticField<jint>(m_gnssStatusObject, "CONSTELLATION_GALILEO"); - static const int beidou = - QJniObject::getStaticField<jint>(m_gnssStatusObject, "CONSTELLATION_BEIDOU"); - static const int qzss = - QJniObject::getStaticField<jint>(m_gnssStatusObject, "CONSTELLATION_QZSS"); - - if (constellationType == gps) { - return QGeoSatelliteInfo::GPS; - } else if (constellationType == glonass) { - return QGeoSatelliteInfo::GLONASS; - } else if (constellationType == galileo) { - return QGeoSatelliteInfo::GALILEO; - } else if (constellationType == beidou) { - return QGeoSatelliteInfo::BEIDOU; - } else if (constellationType == qzss){ - return QGeoSatelliteInfo::QZSS; - } else { - qCWarning(lcPositioning) << "Unknown satellite system" << constellationType; - return QGeoSatelliteInfo::Undefined; - } - } - -private: - static jclass m_gnssStatusObject; -}; - -jclass ConstellationMapper::m_gnssStatusObject = nullptr; - -} // anonymous namespace - -namespace AndroidPositioning { - typedef QMap<int, QGeoPositionInfoSourceAndroid * > PositionSourceMap; - typedef QMap<int, QGeoSatelliteInfoSourceAndroid * > SatelliteSourceMap; - - Q_GLOBAL_STATIC(PositionSourceMap, idToPosSource) - - Q_GLOBAL_STATIC(SatelliteSourceMap, idToSatSource) - - int registerPositionInfoSource(QObject *obj) - { - int key = -1; - if (obj->inherits("QGeoPositionInfoSource")) { - QGeoPositionInfoSourceAndroid *src = qobject_cast<QGeoPositionInfoSourceAndroid *>(obj); - Q_ASSERT(src); - do { - key = qAbs(int(QRandomGenerator::global()->generate())); - } while (idToPosSource()->contains(key)); - - idToPosSource()->insert(key, src); - } else if (obj->inherits("QGeoSatelliteInfoSource")) { - QGeoSatelliteInfoSourceAndroid *src = qobject_cast<QGeoSatelliteInfoSourceAndroid *>(obj); - Q_ASSERT(src); - do { - key = qAbs(int(QRandomGenerator::global()->generate())); - } while (idToSatSource()->contains(key)); - - idToSatSource()->insert(key, src); - } - - return key; - } - - void unregisterPositionInfoSource(int key) - { - idToPosSource()->remove(key); - idToSatSource()->remove(key); - } - - enum PositionProvider - { - PROVIDER_GPS = 0, - PROVIDER_NETWORK = 1, - PROVIDER_PASSIVE = 2 - }; - - - QGeoPositionInfoSource::PositioningMethods availableProviders() - { - QGeoPositionInfoSource::PositioningMethods ret = QGeoPositionInfoSource::NoPositioningMethods; - QJniEnvironment env; - if (!env.jniEnv()) - return ret; - QJniObject jniProvidersObj = - QJniObject::callStaticObjectMethod(positioningClass(), providerListMethodId); - jintArray jProviders = jniProvidersObj.object<jintArray>(); - jint *providers = env->GetIntArrayElements(jProviders, nullptr); - const int size = env->GetArrayLength(jProviders); - for (int i = 0; i < size; i++) { - switch (providers[i]) { - case PROVIDER_GPS: - ret |= QGeoPositionInfoSource::SatellitePositioningMethods; - break; - case PROVIDER_NETWORK: - ret |= QGeoPositionInfoSource::NonSatellitePositioningMethods; - break; - case PROVIDER_PASSIVE: - //we ignore as Qt doesn't have interface for it right now - break; - default: - __android_log_print(ANDROID_LOG_INFO, logTag, "Unknown positioningMethod"); - } - } - - env->ReleaseIntArrayElements(jProviders, providers, 0); - - return ret; - } - - QGeoPositionInfo positionInfoFromJavaLocation(const jobject &location) - { - QGeoPositionInfo info; - - QJniObject jniObject(location); - if (!jniObject.isValid()) - return QGeoPositionInfo(); - - const jdouble latitude = jniObject.callMethod<jdouble>("getLatitude"); - const jdouble longitude = jniObject.callMethod<jdouble>("getLongitude"); - - QGeoCoordinate coordinate(latitude, longitude); - - // altitude - jboolean attributeExists = jniObject.callMethod<jboolean>("hasAltitude"); - if (attributeExists) { - const jdouble value = jniObject.callMethod<jdouble>("getAltitude"); - if (!qFuzzyIsNull(value)) - coordinate.setAltitude(value); - } - - info.setCoordinate(coordinate); - - // time stamp - const jlong timestamp = jniObject.callMethod<jlong>("getTime"); - info.setTimestamp(QDateTime::fromMSecsSinceEpoch(timestamp, Qt::UTC)); - - // horizontal accuracy - attributeExists = jniObject.callMethod<jboolean>("hasAccuracy"); - if (attributeExists) { - const jfloat accuracy = jniObject.callMethod<jfloat>("getAccuracy"); - if (!qFuzzyIsNull(accuracy)) - info.setAttribute(QGeoPositionInfo::HorizontalAccuracy, qreal(accuracy)); - } - - // vertical accuracy - // The check for method existence happens inside QJniObject. If the - // method is not found, 0 (or 0.0, or false) is returned, so we do not - // need to handle it specially. - attributeExists = jniObject.callMethod<jboolean>("hasVerticalAccuracy"); - if (attributeExists) { - const jfloat accuracy = jniObject.callMethod<jfloat>("getVerticalAccuracyMeters"); - if (!qFuzzyIsNull(accuracy)) - info.setAttribute(QGeoPositionInfo::VerticalAccuracy, qreal(accuracy)); - } - - // ground speed - attributeExists = jniObject.callMethod<jboolean>("hasSpeed"); - if (attributeExists) { - const jfloat speed = jniObject.callMethod<jfloat>("getSpeed"); - if (!qFuzzyIsNull(speed)) - info.setAttribute(QGeoPositionInfo::GroundSpeed, qreal(speed)); - } - - // bearing - attributeExists = jniObject.callMethod<jboolean>("hasBearing"); - if (attributeExists) { - const jfloat bearing = jniObject.callMethod<jfloat>("getBearing"); - if (!qFuzzyIsNull(bearing)) - info.setAttribute(QGeoPositionInfo::Direction, qreal(bearing)); - } - - return info; - } - - QList<QGeoSatelliteInfo> satelliteInfoFromJavaLocation(JNIEnv *jniEnv, - jobjectArray satellites, - QList<QGeoSatelliteInfo>* usedInFix) - { - QList<QGeoSatelliteInfo> sats; - jsize length = jniEnv->GetArrayLength(satellites); - for (int i = 0; i<length; i++) { - jobject element = jniEnv->GetObjectArrayElement(satellites, i); - if (QJniEnvironment::checkAndClearExceptions(jniEnv)) { - qCWarning(lcPositioning) << "Cannot process all satellite data due to exception."; - break; - } - - QJniObject jniObj = QJniObject::fromLocalRef(element); - if (!jniObj.isValid()) - continue; - - QGeoSatelliteInfo info; - - // signal strength - const jfloat snr = jniObj.callMethod<jfloat>("getSnr"); - info.setSignalStrength(int(snr)); - - // ignore any satellite with no signal whatsoever - if (qFuzzyIsNull(snr)) - continue; - - // prn - const jint prn = jniObj.callMethod<jint>("getPrn"); - info.setSatelliteIdentifier(prn); - - if (prn >= 1 && prn <= 32) - info.setSatelliteSystem(QGeoSatelliteInfo::GPS); - else if (prn >= 65 && prn <= 96) - info.setSatelliteSystem(QGeoSatelliteInfo::GLONASS); - else if (prn >= 193 && prn <= 200) - info.setSatelliteSystem(QGeoSatelliteInfo::QZSS); - else if ((prn >= 201 && prn <= 235) || (prn >= 401 && prn <= 437)) - info.setSatelliteSystem(QGeoSatelliteInfo::BEIDOU); - else if (prn >= 301 && prn <= 336) - info.setSatelliteSystem(QGeoSatelliteInfo::GALILEO); - - // azimuth - const jfloat azimuth = jniObj.callMethod<jfloat>("getAzimuth"); - info.setAttribute(QGeoSatelliteInfo::Azimuth, qreal(azimuth)); - - // elevation - const jfloat elevation = jniObj.callMethod<jfloat>("getElevation"); - info.setAttribute(QGeoSatelliteInfo::Elevation, qreal(elevation)); - - // Used in fix - true if this satellite is actually used in - // determining the position. - const jboolean inFix = jniObj.callMethod<jboolean>("usedInFix"); - - sats.append(info); - - if (inFix) - usedInFix->append(info); - } - - return sats; - } - - QList<QGeoSatelliteInfo> satelliteInfoFromJavaGnssStatus(jobject gnssStatus, - QList<QGeoSatelliteInfo>* usedInFix) - { - QJniObject jniStatus(gnssStatus); - QList<QGeoSatelliteInfo> sats; - - const int satellitesCount = jniStatus.callMethod<jint>("getSatelliteCount"); - for (int i = 0; i < satellitesCount; ++i) { - QGeoSatelliteInfo info; - - // signal strength - this is actually a carrier-to-noise density, - // but the values are very close to what was previously returned by - // getSnr() method of the GpsSatellite API. - const jfloat cn0 = jniStatus.callMethod<jfloat>("getCn0DbHz", "(I)F", i); - info.setSignalStrength(static_cast<int>(cn0)); - - // satellite system - const jint constellationType = - jniStatus.callMethod<jint>("getConstellationType", "(I)I", i); - info.setSatelliteSystem(ConstellationMapper::toSatelliteSystem(constellationType)); - - // satellite identifier - const jint svId = jniStatus.callMethod<jint>("getSvid", "(I)I", i); - info.setSatelliteIdentifier(svId); - - // azimuth - const jfloat azimuth = jniStatus.callMethod<jfloat>("getAzimuthDegrees", "(I)F", i); - info.setAttribute(QGeoSatelliteInfo::Azimuth, static_cast<qreal>(azimuth)); - - // elevation - const jfloat elevation = jniStatus.callMethod<jfloat>("getElevationDegrees", "(I)F", i); - info.setAttribute(QGeoSatelliteInfo::Elevation, static_cast<qreal>(elevation)); - - // Used in fix - true if this satellite is actually used in - // determining the position. - const jboolean inFix = jniStatus.callMethod<jboolean>("usedInFix", "(I)Z", i); - - sats.append(info); - - if (inFix) - usedInFix->append(info); - } - - return sats; - } - - QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly) - { - QJniEnvironment env; - if (!env.jniEnv()) - return QGeoPositionInfo(); - - if (!requestionPositioningPermissions()) - return {}; - - QJniObject locationObj = QJniObject::callStaticObjectMethod( - positioningClass(), lastKnownPositionMethodId, fromSatellitePositioningMethodsOnly); - jobject location = locationObj.object(); - if (location == nullptr) - return QGeoPositionInfo(); - - const QGeoPositionInfo info = positionInfoFromJavaLocation(location); - - return info; - } - - inline int positioningMethodToInt(QGeoPositionInfoSource::PositioningMethods m) - { - int providerSelection = 0; - if (m & QGeoPositionInfoSource::SatellitePositioningMethods) - providerSelection |= 1; - if (m & QGeoPositionInfoSource::NonSatellitePositioningMethods) - providerSelection |= 2; - - return providerSelection; - } - - QGeoPositionInfoSource::Error startUpdates(int androidClassKey) - { - QJniEnvironment env; - if (!env.jniEnv()) - return QGeoPositionInfoSource::UnknownSourceError; - - QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); - - if (source) { - if (!requestionPositioningPermissions()) - return QGeoPositionInfoSource::AccessError; - - int errorCode = QJniObject::callStaticMethod<jint>( - positioningClass(), startUpdatesMethodId, androidClassKey, - positioningMethodToInt(source->preferredPositioningMethods()), - source->updateInterval()); - switch (errorCode) { - case 0: - case 1: - case 2: - case 3: - return static_cast<QGeoPositionInfoSource::Error>(errorCode); - default: - break; - } - } - - return QGeoPositionInfoSource::UnknownSourceError; - } - - //used for stopping regular and single updates - void stopUpdates(int androidClassKey) - { - QJniObject::callStaticMethod<void>(positioningClass(), stopUpdatesMethodId, - androidClassKey); - } - - QGeoPositionInfoSource::Error requestUpdate(int androidClassKey) - { - QJniEnvironment env; - if (!env.jniEnv()) - return QGeoPositionInfoSource::UnknownSourceError; - - QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); - - if (source) { - if (!requestionPositioningPermissions()) - return QGeoPositionInfoSource::AccessError; - - int errorCode = QJniObject::callStaticMethod<jint>( - positioningClass(), requestUpdateMethodId, androidClassKey, - positioningMethodToInt(source->preferredPositioningMethods())); - switch (errorCode) { - case 0: - case 1: - case 2: - case 3: - return static_cast<QGeoPositionInfoSource::Error>(errorCode); - default: - break; - } - } - return QGeoPositionInfoSource::UnknownSourceError; - } - - QGeoSatelliteInfoSource::Error startSatelliteUpdates(int androidClassKey, bool isSingleRequest, int requestTimeout) - { - QJniEnvironment env; - if (!env.jniEnv()) - return QGeoSatelliteInfoSource::UnknownSourceError; - - QGeoSatelliteInfoSourceAndroid *source = AndroidPositioning::idToSatSource()->value(androidClassKey); - - if (source) { - if (!requestionPositioningPermissions()) - return QGeoSatelliteInfoSource::AccessError; - - int interval = source->updateInterval(); - if (isSingleRequest) - interval = requestTimeout; - int errorCode = QJniObject::callStaticMethod<jint>(positioningClass(), - startSatelliteUpdatesMethodId, - androidClassKey, interval, - isSingleRequest); - switch (errorCode) { - case -1: - case 0: - case 1: - case 2: - return static_cast<QGeoSatelliteInfoSource::Error>(errorCode); - default: - qCWarning(lcPositioning) - << "startSatelliteUpdates: Unknown error code" << errorCode; - break; - } - } - return QGeoSatelliteInfoSource::UnknownSourceError; - } - - bool requestionPositioningPermissions() - { - // If the code is running as a service, we can't request permissions. - // We can only check if we have the needed permissions. Also make sure - // to request the background location permissions. - if (!QNativeInterface::QAndroidApplication::isActivityContext()) { - const auto permission = QtAndroidPrivate::PreciseBackgroundLocation; - const auto result = QtAndroidPrivate::checkPermission(permission).result(); - if (result != QtAndroidPrivate::Authorized) { - qCWarning(lcPositioning) - << "Position data not available due to missing permission" << permission; - } - return result == QtAndroidPrivate::Authorized; - } else { - // Running from a normal Activity. Checking and requesting the - // permissions if necessary. - - // Android v23+ requires runtime permission check and requests - const auto permission = QtAndroidPrivate::PreciseLocation; - auto checkFuture = QtAndroidPrivate::checkPermission(permission); - if (checkFuture.result() == QtAndroidPrivate::Denied) { - auto requestFuture = QtAndroidPrivate::requestPermission(permission); - if (requestFuture.result() != QtAndroidPrivate::Authorized) { - qCWarning(lcPositioning) - << "Position data not available due to missing permission" - << permission; - return false; - } - } - - return true; - } - } -} - -static void positionUpdated(JNIEnv *env, jobject thiz, jobject location, - jint androidClassKey, jboolean isSingleUpdate) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QGeoPositionInfo info = AndroidPositioning::positionInfoFromJavaLocation(location); - - QGeoPositionInfoSourceAndroid *source = AndroidPositioning::idToPosSource()->value(androidClassKey); - if (!source) { - qCWarning(lcPositioning) << "positionUpdated: source == 0"; - return; - } - - //we need to invoke indirectly as the Looper thread is likely to be not the same thread - if (!isSingleUpdate) - QMetaObject::invokeMethod(source, "processPositionUpdate", Qt::AutoConnection, - Q_ARG(QGeoPositionInfo, info)); - else - QMetaObject::invokeMethod(source, "processSinglePositionUpdate", Qt::AutoConnection, - Q_ARG(QGeoPositionInfo, info)); -} - -static void locationProvidersDisabled(JNIEnv *env, jobject thiz, jint androidClassKey) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QObject *source = AndroidPositioning::idToPosSource()->value(androidClassKey); - if (!source) - source = AndroidPositioning::idToSatSource()->value(androidClassKey); - if (!source) { - qCWarning(lcPositioning) << "locationProvidersDisabled: source == 0"; - return; - } - - QMetaObject::invokeMethod(source, "locationProviderDisabled", Qt::AutoConnection); -} - -static void locationProvidersChanged(JNIEnv *env, jobject thiz, jint androidClassKey) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - QObject *source = AndroidPositioning::idToPosSource()->value(androidClassKey); - if (!source) { - qCWarning(lcPositioning) << "locationProvidersChanged: source == 0"; - return; - } - - QMetaObject::invokeMethod(source, "locationProvidersChanged", Qt::AutoConnection); -} - -static void notifySatelliteInfoUpdated(const QList<QGeoSatelliteInfo> &inView, - const QList<QGeoSatelliteInfo> &inUse, - jint androidClassKey, jboolean isSingleUpdate) -{ - QGeoSatelliteInfoSourceAndroid *source = AndroidPositioning::idToSatSource()->value(androidClassKey); - if (!source) { - qCWarning(lcPositioning) << "notifySatelliteInfoUpdated: source == 0"; - return; - } - - QMetaObject::invokeMethod(source, "processSatelliteUpdateInView", Qt::AutoConnection, - Q_ARG(QList<QGeoSatelliteInfo>, inView), Q_ARG(bool, isSingleUpdate)); - - QMetaObject::invokeMethod(source, "processSatelliteUpdateInUse", Qt::AutoConnection, - Q_ARG(QList<QGeoSatelliteInfo>, inUse), Q_ARG(bool, isSingleUpdate)); -} - -static void satelliteGpsUpdated(JNIEnv *env, jobject thiz, jobjectArray satellites, - jint androidClassKey, jboolean isSingleUpdate) -{ - Q_UNUSED(thiz); - QList<QGeoSatelliteInfo> inUse; - QList<QGeoSatelliteInfo> sats = - AndroidPositioning::satelliteInfoFromJavaLocation(env, satellites, &inUse); - - notifySatelliteInfoUpdated(sats, inUse, androidClassKey, isSingleUpdate); -} - -static void satelliteGnssUpdated(JNIEnv *env, jobject thiz, jobject gnssStatus, - jint androidClassKey, jboolean isSingleUpdate) -{ - Q_UNUSED(env); - Q_UNUSED(thiz); - - QList<QGeoSatelliteInfo> inUse; - QList<QGeoSatelliteInfo> sats = - AndroidPositioning::satelliteInfoFromJavaGnssStatus(gnssStatus, &inUse); - - notifySatelliteInfoUpdated(sats, inUse, androidClassKey, isSingleUpdate); -} - -#define GET_AND_CHECK_STATIC_METHOD(VAR, CLASS, METHOD_NAME, METHOD_SIGNATURE) \ - VAR = env.findStaticMethod(CLASS, METHOD_NAME, METHOD_SIGNATURE); \ - if (!VAR) { \ - __android_log_print(ANDROID_LOG_FATAL, logTag, methodErrorMsg, METHOD_NAME, \ - METHOD_SIGNATURE); \ - return false; \ - } - -static bool registerNatives() -{ - const JNINativeMethod methods[] = { - {"positionUpdated", "(Landroid/location/Location;IZ)V", (void *)positionUpdated}, - {"locationProvidersDisabled", "(I)V", (void *) locationProvidersDisabled}, - {"satelliteGpsUpdated", "([Landroid/location/GpsSatellite;IZ)V", (void *)satelliteGpsUpdated}, - {"locationProvidersChanged", "(I)V", (void *) locationProvidersChanged}, - {"satelliteGnssUpdated", "(Landroid/location/GnssStatus;IZ)V", (void *)satelliteGnssUpdated} - }; - - QJniEnvironment env; - if (!env.jniEnv()) { - __android_log_print(ANDROID_LOG_FATAL, logTag, "Failed to create environment"); - return false; - } - - if (!positioningClass.init("org/qtproject/qt/android/positioning/QtPositioning")) { - __android_log_print(ANDROID_LOG_FATAL, logTag, "Failed to create global class ref"); - return false; - } - - if (!env.registerNativeMethods(positioningClass(), methods, - sizeof(methods) / sizeof(methods[0]))) { - __android_log_print(ANDROID_LOG_FATAL, logTag, "Failed to register native methods"); - return false; - } - - GET_AND_CHECK_STATIC_METHOD(providerListMethodId, positioningClass(), "providerList", "()[I"); - GET_AND_CHECK_STATIC_METHOD(lastKnownPositionMethodId, positioningClass(), "lastKnownPosition", - "(Z)Landroid/location/Location;"); - GET_AND_CHECK_STATIC_METHOD(startUpdatesMethodId, positioningClass(), "startUpdates", "(III)I"); - GET_AND_CHECK_STATIC_METHOD(stopUpdatesMethodId, positioningClass(), "stopUpdates", "(I)V"); - GET_AND_CHECK_STATIC_METHOD(requestUpdateMethodId, positioningClass(), "requestUpdate", - "(II)I"); - GET_AND_CHECK_STATIC_METHOD(startSatelliteUpdatesMethodId, positioningClass(), - "startSatelliteUpdates", "(IIZ)I"); - - return true; -} - -Q_DECL_EXPORT jint JNICALL JNI_OnLoad(JavaVM * /*vm*/, void * /*reserved*/) -{ - static bool initialized = false; - if (initialized) - return JNI_VERSION_1_6; - initialized = true; - - __android_log_print(ANDROID_LOG_INFO, logTag, "Positioning start"); - - if (!registerNatives()) { - __android_log_print(ANDROID_LOG_FATAL, logTag, "registerNatives() failed"); - return -1; - } - - if (!ConstellationMapper::init()) { - __android_log_print(ANDROID_LOG_ERROR, logTag, - "Failed to extract constellation type constants. " - "Satellite system will be undefined!"); - } - - return JNI_VERSION_1_6; -} - diff --git a/src/plugins/position/android/src/jnipositioning.h b/src/plugins/position/android/src/jnipositioning.h deleted file mode 100644 index a9a72ecb..00000000 --- a/src/plugins/position/android/src/jnipositioning.h +++ /dev/null @@ -1,64 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2021 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef JNIPOSITIONING_H -#define JNIPOSITIONING_H - -#include <QGeoPositionInfoSource> -#include <QGeoSatelliteInfoSource> - -namespace AndroidPositioning -{ - int registerPositionInfoSource(QObject *obj); - void unregisterPositionInfoSource(int key); - - QGeoPositionInfoSource::PositioningMethods availableProviders(); - QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly); - - QGeoPositionInfoSource::Error startUpdates(int androidClassKey); - void stopUpdates(int androidClassKey); - QGeoPositionInfoSource::Error requestUpdate(int androidClassKey); - - QGeoSatelliteInfoSource::Error startSatelliteUpdates(int androidClassKey, - bool isSingleRequest, - int updateRequestTimeout); - bool requestionPositioningPermissions(); -} - -#endif // JNIPOSITIONING_H diff --git a/src/plugins/position/android/src/plugin.json b/src/plugins/position/android/src/plugin.json deleted file mode 100644 index 4fd87892..00000000 --- a/src/plugins/position/android/src/plugin.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "Keys": ["android"], - "Provider": "android", - "Position": true, - "Satellite": true, - "Monitor": false, - "Priority": 1000, - "Testable": false -} diff --git a/src/plugins/position/android/src/positionfactory_android.cpp b/src/plugins/position/android/src/positionfactory_android.cpp deleted file mode 100644 index 436b1df6..00000000 --- a/src/plugins/position/android/src/positionfactory_android.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "positionfactory_android.h" -#include "qgeopositioninfosource_android_p.h" -#include "qgeosatelliteinfosource_android_p.h" - -QGeoPositionInfoSource *QGeoPositionInfoSourceFactoryAndroid::positionInfoSource(QObject *parent, const QVariantMap ¶meters) -{ - Q_UNUSED(parameters) - QGeoPositionInfoSourceAndroid *src = new QGeoPositionInfoSourceAndroid(parent); - return src; -} - -QGeoSatelliteInfoSource *QGeoPositionInfoSourceFactoryAndroid::satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) -{ - Q_UNUSED(parameters) - QGeoSatelliteInfoSourceAndroid *src = new QGeoSatelliteInfoSourceAndroid(parent); - return src; -} - -QGeoAreaMonitorSource *QGeoPositionInfoSourceFactoryAndroid::areaMonitor(QObject *parent, const QVariantMap ¶meters) -{ - Q_UNUSED(parent) - Q_UNUSED(parameters) - return nullptr; -} diff --git a/src/plugins/position/android/src/positionfactory_android.h b/src/plugins/position/android/src/positionfactory_android.h deleted file mode 100644 index 0494b533..00000000 --- a/src/plugins/position/android/src/positionfactory_android.h +++ /dev/null @@ -1,58 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef POSITIONPOLLFACTORY_H -#define POSITIONPOLLFACTORY_H - -#include <QObject> -#include <QGeoPositionInfoSourceFactory> - -class QGeoPositionInfoSourceFactoryAndroid : public QObject, public QGeoPositionInfoSourceFactory -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.qt-project.qt.position.sourcefactory/6.0" - FILE "plugin.json") - Q_INTERFACES(QGeoPositionInfoSourceFactory) -public: - QGeoPositionInfoSource *positionInfoSource(QObject *parent, const QVariantMap ¶meters) override; - QGeoSatelliteInfoSource *satelliteInfoSource(QObject *parent, const QVariantMap ¶meters) override; - QGeoAreaMonitorSource *areaMonitor(QObject *parent, const QVariantMap ¶meters) override; -}; - -#endif // POSITIONPOLLFACTORY_H diff --git a/src/plugins/position/android/src/qgeopositioninfosource_android.cpp b/src/plugins/position/android/src/qgeopositioninfosource_android.cpp deleted file mode 100644 index b1a41e92..00000000 --- a/src/plugins/position/android/src/qgeopositioninfosource_android.cpp +++ /dev/null @@ -1,296 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include "qgeopositioninfosource_android_p.h" -#include "jnipositioning.h" -#include <QGeoPositionInfo> - -static constexpr int kUpdateFromColdStart = 2 * 60 * 1000; -static constexpr int kRegularUpdatesTimerInterval = 30 * 1000; - -QGeoPositionInfoSourceAndroid::QGeoPositionInfoSourceAndroid(QObject *parent) : - QGeoPositionInfoSource(parent) -{ - androidClassKeyForUpdate = AndroidPositioning::registerPositionInfoSource(this); - androidClassKeyForSingleRequest = AndroidPositioning::registerPositionInfoSource(this); - - //by default use all methods - setPreferredPositioningMethods(AllPositioningMethods); - - m_requestTimer.setSingleShot(true); - connect(&m_requestTimer, &QTimer::timeout, this, - &QGeoPositionInfoSourceAndroid::requestTimeout); - - m_regularUpdatesTimer.setSingleShot(false); - connect(&m_regularUpdatesTimer, &QTimer::timeout, this, - &QGeoPositionInfoSourceAndroid::regularUpdatesTimeout); -} - -QGeoPositionInfoSourceAndroid::~QGeoPositionInfoSourceAndroid() -{ - stopUpdates(); - - if (m_requestTimer.isActive()) { - m_requestTimer.stop(); - AndroidPositioning::stopUpdates(androidClassKeyForSingleRequest); - } - - AndroidPositioning::unregisterPositionInfoSource(androidClassKeyForUpdate); - AndroidPositioning::unregisterPositionInfoSource(androidClassKeyForSingleRequest); -} - -void QGeoPositionInfoSourceAndroid::setUpdateInterval(int msec) -{ - int previousInterval = updateInterval(); - msec = (((msec > 0) && (msec < minimumUpdateInterval())) || msec < 0)? minimumUpdateInterval() : msec; - - if (msec == previousInterval) - return; - - QGeoPositionInfoSource::setUpdateInterval(msec); - - if (updatesRunning) - reconfigureRunningSystem(); -} - -QGeoPositionInfo QGeoPositionInfoSourceAndroid::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const -{ - return AndroidPositioning::lastKnownPosition(fromSatellitePositioningMethodsOnly); -} - -QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceAndroid::supportedPositioningMethods() const -{ - return AndroidPositioning::availableProviders(); -} - -void QGeoPositionInfoSourceAndroid::setPreferredPositioningMethods(QGeoPositionInfoSource::PositioningMethods methods) -{ - PositioningMethods previousPreferredPositioningMethods = preferredPositioningMethods(); - QGeoPositionInfoSource::setPreferredPositioningMethods(methods); - if (previousPreferredPositioningMethods == preferredPositioningMethods()) - return; - - if (updatesRunning) - reconfigureRunningSystem(); -} - -int QGeoPositionInfoSourceAndroid::minimumUpdateInterval() const -{ - return 50; -} - -QGeoPositionInfoSource::Error QGeoPositionInfoSourceAndroid::error() const -{ - return m_error; -} - -void QGeoPositionInfoSourceAndroid::setError(Error error) -{ - m_error = error; - if (error != QGeoPositionInfoSource::NoError) - emit QGeoPositionInfoSource::errorOccurred(m_error); -} - -void QGeoPositionInfoSourceAndroid::startUpdates() -{ - if (updatesRunning) - return; - - m_error = QGeoPositionInfoSource::NoError; - - if (preferredPositioningMethods() == 0) { - setError(UnknownSourceError); - return; - } - - updatesRunning = true; - // Start calculating updates from now. - m_lastUpdateTime = QDateTime::currentMSecsSinceEpoch(); - m_regularUpdatesErrorRaised = false; - QGeoPositionInfoSource::Error error = AndroidPositioning::startUpdates(androidClassKeyForUpdate); - if (error != QGeoPositionInfoSource::NoError) { - updatesRunning = false; - setError(error); - } else { - m_regularUpdatesTimer.start(kRegularUpdatesTimerInterval); - } -} - -void QGeoPositionInfoSourceAndroid::stopUpdates() -{ - if (!updatesRunning) - return; - - updatesRunning = false; - m_regularUpdatesTimer.stop(); - AndroidPositioning::stopUpdates(androidClassKeyForUpdate); -} - -void QGeoPositionInfoSourceAndroid::requestUpdate(int timeout) -{ - if (m_requestTimer.isActive()) - return; - - m_error = QGeoPositionInfoSource::NoError; - - if (timeout != 0 && timeout < minimumUpdateInterval()) { - setError(QGeoPositionInfoSource::UpdateTimeoutError); - return; - } - - if (timeout == 0) - timeout = kUpdateFromColdStart; - - m_requestTimer.start(timeout); - - // if updates already running with interval equal to timeout - // then we wait for next update coming through - // assume that a single update will not be quicker than regular updates anyway - if (updatesRunning && updateInterval() <= timeout) - return; - - QGeoPositionInfoSource::Error error = AndroidPositioning::requestUpdate(androidClassKeyForSingleRequest); - if (error != QGeoPositionInfoSource::NoError) { - m_requestTimer.stop(); - setError(error); - } -} - -void QGeoPositionInfoSourceAndroid::processPositionUpdate(const QGeoPositionInfo &pInfo) -{ - //single update request and served as part of regular update - if (m_requestTimer.isActive()) - m_requestTimer.stop(); - - m_lastUpdateTime = QDateTime::currentMSecsSinceEpoch(); - m_regularUpdatesErrorRaised = false; - - emit positionUpdated(pInfo); -} - -// Might still be called multiple times (once for each provider) -void QGeoPositionInfoSourceAndroid::processSinglePositionUpdate(const QGeoPositionInfo &pInfo) -{ - //timeout but we received a late update -> ignore - if (!m_requestTimer.isActive()) - return; - - queuedSingleUpdates.append(pInfo); -} - -void QGeoPositionInfoSourceAndroid::locationProviderDisabled() -{ - if (updatesRunning && !m_regularUpdatesErrorRaised) { - m_regularUpdatesErrorRaised = true; - setError(QGeoPositionInfoSource::UpdateTimeoutError); - } - - setError(QGeoPositionInfoSource::ClosedError); -} - -void QGeoPositionInfoSourceAndroid::locationProvidersChanged() -{ - emit supportedPositioningMethodsChanged(); -} - -void QGeoPositionInfoSourceAndroid::requestTimeout() -{ - AndroidPositioning::stopUpdates(androidClassKeyForSingleRequest); - //no queued update to process -> timeout - const int count = queuedSingleUpdates.count(); - - if (!count) { - setError(QGeoPositionInfoSource::UpdateTimeoutError); - return; - } - - //pick best - QGeoPositionInfo best = queuedSingleUpdates[0]; - for (int i = 1; i < count; i++) { - const QGeoPositionInfo info = queuedSingleUpdates[i]; - - //anything newer by 20s is always better - const qint64 timeDelta = best.timestamp().secsTo(info.timestamp()); - if (abs(timeDelta) > 20) { - if (timeDelta > 0) - best = info; - continue; - } - - //compare accuracy - if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy) && - best.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) - { - best = info.attribute(QGeoPositionInfo::HorizontalAccuracy) < - best.attribute(QGeoPositionInfo::HorizontalAccuracy) ? info : best; - continue; - } - - //prefer info with accuracy information - if (info.hasAttribute(QGeoPositionInfo::HorizontalAccuracy)) - best = info; - } - - queuedSingleUpdates.clear(); - emit positionUpdated(best); -} - -void QGeoPositionInfoSourceAndroid::regularUpdatesTimeout() -{ - if (!m_regularUpdatesErrorRaised) { - const auto now = QDateTime::currentMSecsSinceEpoch(); - if ((now - m_lastUpdateTime) > (updateInterval() + kUpdateFromColdStart)) { - m_regularUpdatesErrorRaised = true; - setError(QGeoPositionInfoSource::UpdateTimeoutError); - } - } -} - -/* - Updates the system assuming that updateInterval - and/or preferredPositioningMethod have changed. - */ -void QGeoPositionInfoSourceAndroid::reconfigureRunningSystem() -{ - if (!updatesRunning) - return; - - stopUpdates(); - startUpdates(); -} diff --git a/src/plugins/position/android/src/qgeopositioninfosource_android_p.h b/src/plugins/position/android/src/qgeopositioninfosource_android_p.h deleted file mode 100644 index 44cb2799..00000000 --- a/src/plugins/position/android/src/qgeopositioninfosource_android_p.h +++ /dev/null @@ -1,102 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QGEOPOSITIONINFOSOURCE_ANDROID_P_H -#define QGEOPOSITIONINFOSOURCE_ANDROID_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QGeoPositionInfoSource> -#include <QTimer> - -class QGeoPositionInfoSourceAndroid : public QGeoPositionInfoSource -{ - Q_OBJECT -public: - QGeoPositionInfoSourceAndroid(QObject *parent = 0); - ~QGeoPositionInfoSourceAndroid(); - - // From QGeoPositionInfoSource - void setUpdateInterval(int msec) override; - QGeoPositionInfo lastKnownPosition(bool fromSatellitePositioningMethodsOnly = false) const override; - PositioningMethods supportedPositioningMethods() const override; - void setPreferredPositioningMethods(PositioningMethods methods) override; - int minimumUpdateInterval() const override; - Error error() const override; - -public Q_SLOTS: - virtual void startUpdates() override; - virtual void stopUpdates() override; - - virtual void requestUpdate(int timeout = 0) override; - - void processPositionUpdate(const QGeoPositionInfo& pInfo); - void processSinglePositionUpdate(const QGeoPositionInfo& pInfo); - - void locationProviderDisabled(); - void locationProvidersChanged(); -private Q_SLOTS: - void requestTimeout(); - void regularUpdatesTimeout(); - -private: - void reconfigureRunningSystem(); - void setError(Error error); - - bool updatesRunning = false; - int androidClassKeyForUpdate; - int androidClassKeyForSingleRequest; - QList<QGeoPositionInfo> queuedSingleUpdates; - Error m_error = NoError; - QTimer m_requestTimer; - QTimer m_regularUpdatesTimer; - qint64 m_lastUpdateTime = 0; - bool m_regularUpdatesErrorRaised = false; -}; - -#endif // QGEOPOSITIONINFOSOURCE_ANDROID_P_H diff --git a/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp b/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp deleted file mode 100644 index 13c09680..00000000 --- a/src/plugins/position/android/src/qgeosatelliteinfosource_android.cpp +++ /dev/null @@ -1,223 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#include <QDebug> - -#include "qgeosatelliteinfosource_android_p.h" -#include "jnipositioning.h" - -Q_DECLARE_METATYPE(QList<QGeoSatelliteInfo>) - -#define UPDATE_FROM_COLD_START 2*60*1000 - -QGeoSatelliteInfoSourceAndroid::QGeoSatelliteInfoSourceAndroid(QObject *parent) : - QGeoSatelliteInfoSource(parent), m_error(NoError), updatesRunning(false) -{ - qRegisterMetaType< QGeoSatelliteInfo >(); - qRegisterMetaType< QList<QGeoSatelliteInfo> >(); - androidClassKeyForUpdate = AndroidPositioning::registerPositionInfoSource(this); - androidClassKeyForSingleRequest = AndroidPositioning::registerPositionInfoSource(this); - - requestTimer.setSingleShot(true); - QObject::connect(&requestTimer, SIGNAL(timeout()), - this, SLOT(requestTimeout())); -} - -QGeoSatelliteInfoSourceAndroid::~QGeoSatelliteInfoSourceAndroid() -{ - stopUpdates(); - - if (requestTimer.isActive()) { - requestTimer.stop(); - AndroidPositioning::stopUpdates(androidClassKeyForSingleRequest); - } - - AndroidPositioning::unregisterPositionInfoSource(androidClassKeyForUpdate); - AndroidPositioning::unregisterPositionInfoSource(androidClassKeyForSingleRequest); -} - - -void QGeoSatelliteInfoSourceAndroid::setUpdateInterval(int msec) -{ - int previousInterval = updateInterval(); - msec = (((msec > 0) && (msec < minimumUpdateInterval())) || msec < 0)? minimumUpdateInterval() : msec; - - if (msec == previousInterval) - return; - - QGeoSatelliteInfoSource::setUpdateInterval(msec); - - if (updatesRunning) - reconfigureRunningSystem(); -} - -int QGeoSatelliteInfoSourceAndroid::minimumUpdateInterval() const -{ - return 50; -} - -QGeoSatelliteInfoSource::Error QGeoSatelliteInfoSourceAndroid::error() const -{ - return m_error; -} - -void QGeoSatelliteInfoSourceAndroid::startUpdates() -{ - if (updatesRunning) - return; - - updatesRunning = true; - - m_error = QGeoSatelliteInfoSource::NoError; - - QGeoSatelliteInfoSource::Error error = AndroidPositioning::startSatelliteUpdates( - androidClassKeyForUpdate, false, updateInterval()); - if (error != QGeoSatelliteInfoSource::NoError) { - updatesRunning = false; - setError(error); - } -} - -void QGeoSatelliteInfoSourceAndroid::stopUpdates() -{ - if (!updatesRunning) - return; - - updatesRunning = false; - AndroidPositioning::stopUpdates(androidClassKeyForUpdate); -} - -void QGeoSatelliteInfoSourceAndroid::requestUpdate(int timeout) -{ - if (requestTimer.isActive()) - return; - - m_error = QGeoSatelliteInfoSource::NoError; - - if (timeout != 0 && timeout < minimumUpdateInterval()) { - setError(QGeoSatelliteInfoSource::UpdateTimeoutError); - return; - } - - if (timeout == 0) - timeout = UPDATE_FROM_COLD_START; - - requestTimer.start(timeout); - - // if updates already running with interval equal or less then timeout - // then we wait for next update coming through - // assume that a single update will not be quicker than regular updates anyway - if (updatesRunning && updateInterval() <= timeout) - return; - - QGeoSatelliteInfoSource::Error error = AndroidPositioning::startSatelliteUpdates( - androidClassKeyForSingleRequest, true, timeout); - if (error != QGeoSatelliteInfoSource::NoError) { - requestTimer.stop(); - setError(error); - } -} - -void QGeoSatelliteInfoSourceAndroid::processSatelliteUpdateInView(const QList<QGeoSatelliteInfo> &satsInView, bool isSingleUpdate) -{ - if (!isSingleUpdate) { - //if requested while regular updates were running - if (requestTimer.isActive()) - requestTimer.stop(); - emit QGeoSatelliteInfoSource::satellitesInViewUpdated(satsInView); - return; - } - - m_satsInView = satsInView; -} - -void QGeoSatelliteInfoSourceAndroid::processSatelliteUpdateInUse(const QList<QGeoSatelliteInfo> &satsInUse, bool isSingleUpdate) -{ - if (!isSingleUpdate) { - //if requested while regular updates were running - if (requestTimer.isActive()) - requestTimer.stop(); - emit QGeoSatelliteInfoSource::satellitesInUseUpdated(satsInUse); - return; - } - - m_satsInUse = satsInUse; -} - -void QGeoSatelliteInfoSourceAndroid::requestTimeout() -{ - AndroidPositioning::stopUpdates(androidClassKeyForSingleRequest); - - const int count = m_satsInView.count(); - if (!count) { - setError(QGeoSatelliteInfoSource::UpdateTimeoutError); - return; - } - - emit QGeoSatelliteInfoSource::satellitesInViewUpdated(m_satsInView); - emit QGeoSatelliteInfoSource::satellitesInUseUpdated(m_satsInUse); - - m_satsInUse.clear(); - m_satsInView.clear(); -} - -/* - Updates the system assuming that updateInterval - and/or preferredPositioningMethod have changed. - */ -void QGeoSatelliteInfoSourceAndroid::reconfigureRunningSystem() -{ - if (!updatesRunning) - return; - - stopUpdates(); - startUpdates(); -} - -void QGeoSatelliteInfoSourceAndroid::setError(QGeoSatelliteInfoSource::Error error) -{ - m_error = error; - if (m_error != QGeoSatelliteInfoSource::NoError) - emit QGeoSatelliteInfoSource::errorOccurred(m_error); -} - -void QGeoSatelliteInfoSourceAndroid::locationProviderDisabled() -{ - setError(QGeoSatelliteInfoSource::ClosedError); -} diff --git a/src/plugins/position/android/src/qgeosatelliteinfosource_android_p.h b/src/plugins/position/android/src/qgeosatelliteinfosource_android_p.h deleted file mode 100644 index 19b7b577..00000000 --- a/src/plugins/position/android/src/qgeosatelliteinfosource_android_p.h +++ /dev/null @@ -1,98 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtPositioning module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - - -#ifndef QGEOSATELLITEINFOSOURCEANDROID_H -#define QGEOSATELLITEINFOSOURCEANDROID_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QGeoSatelliteInfoSource> -#include <QTimer> - -class QGeoSatelliteInfoSourceAndroid : public QGeoSatelliteInfoSource -{ - Q_OBJECT -public: - explicit QGeoSatelliteInfoSourceAndroid(QObject *parent = 0); - ~QGeoSatelliteInfoSourceAndroid(); - - //From QGeoSatelliteInfoSource - void setUpdateInterval(int msec) override; - int minimumUpdateInterval() const override; - - Error error() const override; - -public Q_SLOTS: - void startUpdates() override; - void stopUpdates() override; - void requestUpdate(int timeout = 0) override; - - void processSatelliteUpdateInView(const QList<QGeoSatelliteInfo> &satsInView, bool isSingleUpdate); - void processSatelliteUpdateInUse(const QList<QGeoSatelliteInfo> &satsInUse, bool isSingleUpdate); - - void locationProviderDisabled(); -private Q_SLOTS: - void requestTimeout(); - -private: - void reconfigureRunningSystem(); - void setError(QGeoSatelliteInfoSource::Error error); - - Error m_error; - int androidClassKeyForUpdate; - int androidClassKeyForSingleRequest; - bool updatesRunning; - - QTimer requestTimer; - QList<QGeoSatelliteInfo> m_satsInUse; - QList<QGeoSatelliteInfo> m_satsInView; - -}; - -#endif // QGEOSATELLITEINFOSOURCEANDROID_H diff --git a/src/plugins/position/android/src/src.pro b/src/plugins/position/android/src/src.pro deleted file mode 100644 index 36facc55..00000000 --- a/src/plugins/position/android/src/src.pro +++ /dev/null @@ -1,21 +0,0 @@ -TARGET = qtposition_android - -QT = core core-private positioning - -HEADERS = \ - positionfactory_android.h \ - qgeopositioninfosource_android_p.h \ - jnipositioning.h \ - qgeosatelliteinfosource_android_p.h - -SOURCES = \ - positionfactory_android.cpp \ - qgeopositioninfosource_android.cpp \ - jnipositioning.cpp \ - qgeosatelliteinfosource_android.cpp - -OTHER_FILES = plugin.json - -PLUGIN_TYPE = position -PLUGIN_CLASS_NAME = QGeoPositionInfoSourceFactoryAndroid -load(qt_plugin) |