GeolocationServiceAndroid.cpp [plain text]
#include "config.h"
#include "GeolocationServiceAndroid.h"
#include "GeolocationServiceBridge.h"
#include "Geoposition.h"
#include "PositionError.h"
#include "PositionOptions.h"
#include <wtf/CurrentTime.h>
using JSC::Bindings::getJNIEnv;
using namespace std;
namespace WebCore {
PassOwnPtr<GeolocationService> GeolocationServiceAndroid::create(GeolocationServiceClient* client)
{
return new GeolocationServiceAndroid(client);
}
GeolocationService::FactoryFunction* GeolocationService::s_factoryFunction = &GeolocationServiceAndroid::create;
GeolocationServiceAndroid::GeolocationServiceAndroid(GeolocationServiceClient* client)
: GeolocationService(client)
, m_timer(this, &GeolocationServiceAndroid::timerFired)
, m_javaBridge(0)
{
}
bool GeolocationServiceAndroid::startUpdating(PositionOptions* options)
{
if (m_lastPosition || m_lastError) {
ASSERT(m_javaBridge);
m_timer.startOneShot(0);
}
bool haveJavaBridge = m_javaBridge;
if (!haveJavaBridge)
m_javaBridge.set(new GeolocationServiceBridge(this));
ASSERT(m_javaBridge);
ASSERT(options);
if (options->enableHighAccuracy())
m_javaBridge->setEnableGps(true);
if (!haveJavaBridge)
m_javaBridge->start();
return true;
}
void GeolocationServiceAndroid::stopUpdating()
{
m_javaBridge.clear();
m_lastPosition = 0;
m_lastError = 0;
}
void GeolocationServiceAndroid::suspend()
{
ASSERT(m_javaBridge);
m_javaBridge->stop();
}
void GeolocationServiceAndroid::resume()
{
ASSERT(m_javaBridge);
m_javaBridge->start();
}
void GeolocationServiceAndroid::newPositionAvailable(PassRefPtr<Geoposition> position)
{
ASSERT(position);
if (!m_lastPosition
|| isPositionMovement(m_lastPosition.get(), position.get())
|| isPositionMoreAccurate(m_lastPosition.get(), position.get())
|| isPositionMoreTimely(m_lastPosition.get(), position.get())) {
m_lastPosition = position;
m_lastError = 0;
positionChanged();
}
}
void GeolocationServiceAndroid::newErrorAvailable(PassRefPtr<PositionError> error)
{
ASSERT(error);
m_lastError = error;
errorOccurred();
}
void GeolocationServiceAndroid::timerFired(Timer<GeolocationServiceAndroid>* timer)
{
ASSERT(&m_timer == timer);
ASSERT(m_lastPosition || m_lastError);
if (m_lastPosition)
positionChanged();
else
errorOccurred();
}
bool GeolocationServiceAndroid::isPositionMovement(Geoposition* position1, Geoposition* position2)
{
ASSERT(position1 && position2);
double delta = fabs(position1->coords()->latitude() - position2->coords()->latitude())
+ fabs(position1->coords()->longitude() - position2->coords()->longitude());
delta *= 60 * 1852;
int maxAccuracy = max(position1->coords()->accuracy(), position2->coords()->accuracy());
return delta > maxAccuracy;
}
bool GeolocationServiceAndroid::isPositionMoreAccurate(Geoposition* position1, Geoposition* position2)
{
ASSERT(position1 && position2);
return position2->coords()->accuracy() < position1->coords()->accuracy();
}
bool GeolocationServiceAndroid::isPositionMoreTimely(Geoposition* position1, Geoposition* position2)
{
ASSERT(position1 && position2);
DOMTimeStamp currentTime = convertSecondsToDOMTimeStamp(WTF::currentTime());
DOMTimeStamp maximumAge = convertSecondsToDOMTimeStamp(10 * 60); return currentTime - position1->timestamp() > maximumAge;
}
}