summaryrefslogtreecommitdiff
path: root/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/position/corelocation/qgeopositioninfosource_cl.mm')
-rw-r--r--src/plugins/position/corelocation/qgeopositioninfosource_cl.mm336
1 files changed, 0 insertions, 336 deletions
diff --git a/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm b/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm
deleted file mode 100644
index c7e02443..00000000
--- a/src/plugins/position/corelocation/qgeopositioninfosource_cl.mm
+++ /dev/null
@@ -1,336 +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 <QTimerEvent>
-#include <QDebug>
-#include <QtCore/qglobal.h>
-#include <QtCore/private/qglobal_p.h>
-
-#include "qgeopositioninfosource_cl_p.h"
-
-#define MINIMUM_UPDATE_INTERVAL 1000
-
-@interface PositionLocationDelegate : NSObject <CLLocationManagerDelegate>
-@end
-
-@implementation PositionLocationDelegate
-{
- QGeoPositionInfoSourceCL *m_positionInfoSource;
-}
-
-- (instancetype)initWithInfoSource:(QGeoPositionInfoSourceCL*) positionInfoSource
-{
- if ((self = [self init])) {
- m_positionInfoSource = positionInfoSource;
- }
- return self;
-}
-- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status
-{
- Q_UNUSED(manager);
- if (status == kCLAuthorizationStatusNotDetermined)
- m_positionInfoSource->requestUpdate(MINIMUM_UPDATE_INTERVAL);
-}
-
-- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
-{
- Q_UNUSED(manager);
- Q_UNUSED(oldLocation);
-
- // Convert location timestamp to QDateTime
- NSTimeInterval locationTimeStamp = [newLocation.timestamp timeIntervalSince1970];
- const QDateTime timeStamp = QDateTime::fromMSecsSinceEpoch(qRound64(locationTimeStamp * 1000), Qt::UTC);
-
- // Construct position info from location data
- QGeoPositionInfo location(QGeoCoordinate(newLocation.coordinate.latitude,
- newLocation.coordinate.longitude,
- newLocation.altitude),
- timeStamp);
- if (newLocation.horizontalAccuracy >= 0)
- location.setAttribute(QGeoPositionInfo::HorizontalAccuracy, newLocation.horizontalAccuracy);
- if (newLocation.verticalAccuracy >= 0)
- location.setAttribute(QGeoPositionInfo::VerticalAccuracy, newLocation.verticalAccuracy);
-#ifndef Q_OS_TVOS
- if (newLocation.course >= 0)
- location.setAttribute(QGeoPositionInfo::Direction, newLocation.course);
- if (newLocation.speed >= 0)
- location.setAttribute(QGeoPositionInfo::GroundSpeed, newLocation.speed);
-#endif
-
- m_positionInfoSource->locationDataAvailable(location);
-}
-
-- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error
-{
- Q_UNUSED(manager);
- m_positionInfoSource->setError(QGeoPositionInfoSource::AccessError);
-
- qWarning() << QString::fromNSString([error localizedDescription]);
-
- if ([error code] == 0
- && QString::fromNSString([error domain]) == QStringLiteral("kCLErrorDomain"))
- qWarning() << "(is Wi-Fi turned on?)";
-}
-@end
-
-QT_BEGIN_NAMESPACE
-
-QGeoPositionInfoSourceCL::QGeoPositionInfoSourceCL(QObject *parent)
- : QGeoPositionInfoSource(parent)
- , m_locationManager(0)
- , m_started(false)
- , m_updateTimer(0)
- , m_updateTimeout(0)
- , m_positionError(QGeoPositionInfoSource::NoError)
-{
-}
-
-QGeoPositionInfoSourceCL::~QGeoPositionInfoSourceCL()
-{
- stopUpdates();
- [m_locationManager release];
-}
-
-void QGeoPositionInfoSourceCL::setUpdateInterval(int msec)
-{
- // If msec is 0 we send updates as data becomes available, otherwise we force msec to be equal
- // to or larger than the minimum update interval.
- if (msec != 0 && msec < minimumUpdateInterval())
- msec = minimumUpdateInterval();
-
- QGeoPositionInfoSource::setUpdateInterval(msec);
-
- // Must timeout if update takes longer than specified interval
- m_updateTimeout = msec;
- if (m_started) setTimeoutInterval(m_updateTimeout);
-}
-
-bool QGeoPositionInfoSourceCL::enableLocationManager()
-{
- if (!m_locationManager) {
- if ([CLLocationManager locationServicesEnabled]) {
- // Location Services Are Enabled
- switch ([CLLocationManager authorizationStatus]) {
- case kCLAuthorizationStatusNotDetermined:
- // User has not yet made a choice with regards to this application
- break;
- case kCLAuthorizationStatusRestricted:
- // This application is not authorized to use location services. Due
- // to active restrictions on location services, the user cannot change
- // this status, and may not have personally denied authorization
- return false;
- case kCLAuthorizationStatusDenied:
- // User has explicitly denied authorization for this application, or
- // location services are disabled in Settings
- return false;
- case kCLAuthorizationStatusAuthorizedAlways:
- // This app is authorized to start location services at any time.
- break;
-#ifndef Q_OS_MACOS
- case kCLAuthorizationStatusAuthorizedWhenInUse:
- // This app is authorized to start most location services while running in the foreground.
- break;
-#endif
- default:
- // By default, try to enable it
- break;
- }
- } else {
- // Location Services Disabled
- return false;
- }
-
- m_locationManager = [[CLLocationManager alloc] init];
-
-#if defined(Q_OS_IOS) || defined(Q_OS_WATCHOS)
- if (__builtin_available(watchOS 4.0, *)) {
- NSDictionary<NSString *, id> *infoDict = [[NSBundle mainBundle] infoDictionary];
- if (id value = [infoDict objectForKey:@"UIBackgroundModes"]) {
- if ([value isKindOfClass:[NSArray class]]) {
- NSArray *modes = static_cast<NSArray *>(value);
- for (id mode in modes) {
- if ([@"location" isEqualToString:mode]) {
- m_locationManager.allowsBackgroundLocationUpdates = YES;
- break;
- }
- }
- }
- }
- }
-#endif
-
- m_locationManager.desiredAccuracy = kCLLocationAccuracyBest;
- m_locationManager.delegate = [[PositionLocationDelegate alloc] initWithInfoSource:this];
-
- // -requestAlwaysAuthorization is available on iOS (>= 8.0) and watchOS (>= 2.0).
- // This method requires both NSLocationAlwaysAndWhenInUseUsageDescription and
- // NSLocationWhenInUseUsageDescription entries present in Info.plist (otherwise,
- // while probably a noop, the call generates a warning).
- // -requestWhenInUseAuthorization only requires NSLocationWhenInUseUsageDescription
- // entry in Info.plist (available on iOS (>= 8.0), tvOS (>= 9.0) and watchOS (>= 2.0).
- }
-
-#ifndef Q_OS_MACOS
- NSDictionary<NSString *, id> *infoDict = NSBundle.mainBundle.infoDictionary;
- const bool hasAlwaysUseUsage = !![infoDict objectForKey:@"NSLocationAlwaysAndWhenInUseUsageDescription"];
- const bool hasWhenInUseUsage = !![infoDict objectForKey:@"NSLocationWhenInUseUsageDescription"];
-#ifndef Q_OS_TVOS
- if (hasAlwaysUseUsage && hasWhenInUseUsage)
- [m_locationManager requestAlwaysAuthorization];
- else
-#endif // !Q_OS_TVOS
- if (hasWhenInUseUsage)
- [m_locationManager requestWhenInUseAuthorization];
-#endif // !Q_OS_MACOS
-
- return (m_locationManager != nullptr);
-}
-
-void QGeoPositionInfoSourceCL::setTimeoutInterval(int msec)
-{
- // Start timeout timer
- if (m_updateTimer) killTimer(m_updateTimer);
- if (msec > 0) m_updateTimer = startTimer(msec);
- else m_updateTimer = 0;
-}
-
-void QGeoPositionInfoSourceCL::startUpdates()
-{
- m_positionError = QGeoPositionInfoSource::NoError;
- if (enableLocationManager()) {
-#ifdef Q_OS_TVOS
- [m_locationManager requestLocation]; // service will run long enough for one location update
-#else
- [m_locationManager startUpdatingLocation];
-#endif
- m_started = true;
-
- setTimeoutInterval(m_updateTimeout);
- } else setError(QGeoPositionInfoSource::AccessError);
-}
-
-void QGeoPositionInfoSourceCL::stopUpdates()
-{
- if (m_locationManager) {
- [m_locationManager stopUpdatingLocation];
- m_started = false;
-
- // Stop timeout timer
- setTimeoutInterval(0);
- } else setError(QGeoPositionInfoSource::AccessError);
-}
-
-void QGeoPositionInfoSourceCL::requestUpdate(int timeout)
-{
- // Get a single update within timeframe
- m_positionError = QGeoPositionInfoSource::NoError;
- if (timeout < minimumUpdateInterval() && timeout != 0)
- setError(QGeoPositionInfoSource::UpdateTimeoutError);
- else if (enableLocationManager()) {
- // This will force LM to generate a new update
- [m_locationManager stopUpdatingLocation];
-#ifdef Q_OS_TVOS
- [m_locationManager requestLocation]; // service will run long enough for one location update
-#else
- [m_locationManager startUpdatingLocation];
-#endif
-
- setTimeoutInterval(timeout);
- } else setError(QGeoPositionInfoSource::AccessError);
-}
-
-void QGeoPositionInfoSourceCL::timerEvent( QTimerEvent * event )
-{
- // Update timed out?
- if (event->timerId() == m_updateTimer) {
- setError(QGeoPositionInfoSource::UpdateTimeoutError);
-
- // Only timeout once since last data
- setTimeoutInterval(0);
-
- // Started for single update?
- if (!m_started) stopUpdates();
- }
-}
-
-QGeoPositionInfoSource::PositioningMethods QGeoPositionInfoSourceCL::supportedPositioningMethods() const
-{
- // CoreLocation doesn't say which positioning method(s) it used
- return QGeoPositionInfoSource::AllPositioningMethods;
-}
-
-int QGeoPositionInfoSourceCL::minimumUpdateInterval() const
-{
- return MINIMUM_UPDATE_INTERVAL;
-}
-
-void QGeoPositionInfoSourceCL::locationDataAvailable(QGeoPositionInfo location)
-{
- // Signal position data available
- m_lastUpdate = location;
- emit positionUpdated(location);
-
- // Started for single update?
- if (!m_started) stopUpdates();
- // ...otherwise restart timeout timer
- else setTimeoutInterval(m_updateTimeout);
-}
-
-QGeoPositionInfo QGeoPositionInfoSourceCL::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
-{
- Q_UNUSED(fromSatellitePositioningMethodsOnly);
-
- return m_lastUpdate;
-}
-
-QGeoPositionInfoSource::Error QGeoPositionInfoSourceCL::error() const
-{
- return m_positionError;
-}
-
-void QGeoPositionInfoSourceCL::setError(QGeoPositionInfoSource::Error positionError)
-{
- m_positionError = positionError;
- if (m_positionError != QGeoPositionInfoSource::NoError)
- emit QGeoPositionInfoSource::errorOccurred(positionError);
-}
-
-QT_END_NAMESPACE
-
-#include "moc_qgeopositioninfosource_cl_p.cpp"