dom/system/qt/QTMLocationProvider.cpp
author Kartikaya Gupta <kgupta@mozilla.com>
Tue, 18 Aug 2015 14:27:18 -0400
changeset 258262 0700729ed00747937218685cd95a660a3bfc1910
parent 180485 6c1c7e45c90289a0875b74f82f39e7ecf6a65af3
child 266353 91d4539e00cecb658604e021675a923c60ef3235
permissions -rw-r--r--
Bug 1180295 - Hook up touch-based scrolling to the new DynamicToolbarAnimator. r=rbarker

/* -*- Mode: c++; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "QTMLocationProvider.h"
#include "nsGeoPosition.h"

using namespace mozilla;

NS_IMPL_ISUPPORTS(QTMLocationProvider, nsIGeolocationProvider)

QTMLocationProvider::QTMLocationProvider()
{
    if (QMetaType::type("QGeoPositionInfo") == QMetaType::UnknownType) {
        qRegisterMetaType<QGeoPositionInfo>("QGeoPositionInfo");
    }
    mLocation = QGeoPositionInfoSource::createDefaultSource(this);
    if (mLocation)
        connect(mLocation, SIGNAL(positionUpdated(QGeoPositionInfo)), this, SLOT(positionUpdated(QGeoPositionInfo)));
}

QTMLocationProvider::~QTMLocationProvider()
{
    delete mLocation;
}

void
QTMLocationProvider::positionUpdated(const QGeoPositionInfo &geoPosition)
{
    if (!geoPosition.isValid()) {
        NS_WARNING("Invalida geoposition received");
        return;
    }

    QGeoCoordinate coord = geoPosition.coordinate();
    double latitude = coord.latitude();
    double longitude = coord.longitude();
    double altitude = coord.altitude();
    double accuracy = geoPosition.attribute(QGeoPositionInfo::HorizontalAccuracy);
    double altitudeAccuracy = geoPosition.attribute(QGeoPositionInfo::VerticalAccuracy);
    double heading = geoPosition.attribute(QGeoPositionInfo::Direction);

    bool providesSpeed = geoPosition.hasAttribute(QGeoPositionInfo::GroundSpeed);
    double speed = geoPosition.attribute(QGeoPositionInfo::GroundSpeed);

    nsRefPtr<nsGeoPosition> p =
        new nsGeoPosition(latitude, longitude,
                          altitude, accuracy,
                          altitudeAccuracy, heading,
                          speed, geoPosition.timestamp().toTime_t());
    if (mCallback) {
        mCallback->Update(p);
    }
}

NS_IMETHODIMP
QTMLocationProvider::Startup()
{
    if (!mLocation)
        return NS_ERROR_NOT_IMPLEMENTED;

    // Not all versions of qt5positioning set default prefered method
    // thus this workaround initializing QGeoPositionSource explicitly
    SetHighAccuracy(false);
    mLocation->startUpdates();

    return NS_OK;
}

NS_IMETHODIMP
QTMLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
{
    mCallback = aCallback;

    return NS_OK;
}

NS_IMETHODIMP
QTMLocationProvider::Shutdown()
{
    if (!mLocation)
        return NS_ERROR_NOT_IMPLEMENTED;

    mLocation->stopUpdates();
    mCallback = nullptr;

    return NS_OK;
}

NS_IMETHODIMP
QTMLocationProvider::SetHighAccuracy(bool aHigh)
{
    if (!mLocation)
        return NS_ERROR_NOT_IMPLEMENTED;

    mLocation->setPreferredPositioningMethods(aHigh ?
                                              QGeoPositionInfoSource::SatellitePositioningMethods :
                                              QGeoPositionInfoSource::AllPositioningMethods);
    return NS_OK;
}