Bug 478923 - Maemo Geolocation Provider support to support latest Geolocation specification. r/sr=jst

This commit is contained in:
Doug Turner 2009-02-25 20:33:24 -08:00
Родитель b5a365d327
Коммит 4a6980c573
5 изменённых файлов: 172 добавлений и 85 удалений

Просмотреть файл

@ -433,6 +433,7 @@ enum nsDOMClassInfoID {
// Geolocation // Geolocation
eDOMClassInfo_GeoGeolocation_id, eDOMClassInfo_GeoGeolocation_id,
eDOMClassInfo_GeoPosition_id, eDOMClassInfo_GeoPosition_id,
eDOMClassInfo_GeoPositionCoords_id,
eDOMClassInfo_GeoPositionError_id, eDOMClassInfo_GeoPositionError_id,
// @font-face in CSS // @font-face in CSS

Просмотреть файл

@ -461,6 +461,7 @@
// Geolocation // Geolocation
#include "nsIDOMGeoGeolocation.h" #include "nsIDOMGeoGeolocation.h"
#include "nsIDOMGeoPosition.h" #include "nsIDOMGeoPosition.h"
#include "nsIDOMGeoPositionCoords.h"
#include "nsIDOMGeoPositionError.h" #include "nsIDOMGeoPositionError.h"
// Workers // Workers
@ -1279,6 +1280,9 @@ static nsDOMClassInfoData sClassInfoData[] = {
NS_DEFINE_CLASSINFO_DATA(GeoPosition, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(GeoPosition, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(GeoPositionCoords, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(GeoPositionError, nsDOMGenericSH, NS_DEFINE_CLASSINFO_DATA(GeoPositionError, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS) DOM_DEFAULT_SCRIPTABLE_FLAGS)
@ -3550,6 +3554,10 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPosition) DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPosition)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(GeoPositionCoords, nsIDOMGeoPositionCoords)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionCoords)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(GeoPositionError, nsIDOMGeoPositionError) DOM_CLASSINFO_MAP_BEGIN(GeoPositionError, nsIDOMGeoPositionError)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionError) DOM_CLASSINFO_MAP_ENTRY(nsIDOMGeoPositionError)
DOM_CLASSINFO_MAP_END DOM_CLASSINFO_MAP_END

Просмотреть файл

@ -34,34 +34,132 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
#include "MaemoLocationProvider.h" #include "MaemoLocationProvider.h"
#include "nsGeolocation.h" #include "nsGeolocation.h"
#include "nsIClassInfo.h" #include "nsIClassInfo.h"
#include "nsDOMClassInfoID.h" #include "nsDOMClassInfoID.h"
////////////////////////////////////////////////////
// nsGeoPositionCoords
////////////////////////////////////////////////////
class nsGeoPositionCoords : public nsIDOMGeoPositionCoords
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIDOMGEOPOSITIONCOORDS
nsGeoPositionCoords(double aLat, double aLong,
double aAlt, double aHError,
double aVError, double aHeading,
double aSpeed)
: mLat(aLat),
mLong(aLong),
mAlt(aAlt),
mHError(aHError),
mVError(aVError),
mHeading(aHeading),
mSpeed(aSpeed)
{
}
~nsGeoPositionCoords(){}
private:
double mLat, mLong, mAlt, mHError, mVError, mHeading, mSpeed;
};
NS_INTERFACE_MAP_BEGIN(nsGeoPositionCoords)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMGeoPositionCoords)
NS_INTERFACE_MAP_ENTRY(nsIDOMGeoPositionCoords)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(GeoPositionCoords)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF(nsGeoPositionCoords)
NS_IMPL_RELEASE(nsGeoPositionCoords)
NS_IMETHODIMP
nsGeoPositionCoords::GetLatitude(double *aLatitude)
{
*aLatitude = mLat;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionCoords::GetLongitude(double *aLongitude)
{
*aLongitude = mLong;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionCoords::GetAltitude(double *aAltitude)
{
*aAltitude = mAlt;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionCoords::GetAccuracy(double *aAccuracy)
{
*aAccuracy = mHError;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionCoords::GetAltitudeAccuracy(double *aAltitudeAccuracy)
{
*aAltitudeAccuracy = mVError;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionCoords::GetHeading(double *aHeading)
{
*aHeading = mHeading;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPositionCoords::GetSpeed(double *aSpeed)
{
*aSpeed = mSpeed;
return NS_OK;
}
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
// nsGeoPosition // nsGeoPosition
//////////////////////////////////////////////////// ////////////////////////////////////////////////////
/**
* Simple object that holds a single point in space.
*/
class nsGeoPosition : public nsIDOMGeoPosition class nsGeoPosition : public nsIDOMGeoPosition
{ {
public: public:
NS_DECL_ISUPPORTS NS_DECL_ISUPPORTS
NS_DECL_NSIDOMGEOPOSITION NS_DECL_NSIDOMGEOPOSITION
nsGeoPosition(double aLat, double aLong, double aAlt, double aHError, double aVError, double aHeading, double aSpeed, long long aTimestamp) nsGeoPosition(double aLat, double aLong,
: mLat(aLat), mLong(aLong), mAlt(aAlt), mHError(aHError), mVError(aVError), mHeading(aHeading), mSpeed(aSpeed), mTimestamp(aTimestamp){}; double aAlt, double aHError,
double aVError, double aHeading,
double aSpeed, long long aTimestamp)
: mLat(aLat),
mLong(aLong),
mAlt(aAlt),
mHError(aHError),
mVError(aVError),
mHeading(aHeading),
mSpeed(aSpeed),
mTimestamp(aTimestamp)
{
}
private: private:
~nsGeoPosition(){} ~nsGeoPosition()
{
}
double mLat, mLong, mAlt, mHError, mVError, mHeading, mSpeed; double mLat, mLong, mAlt, mHError, mVError, mHeading, mSpeed;
long long mTimestamp; long long mTimestamp;
nsRefPtr<nsGeoPositionCoords> mCoords;
}; };
NS_INTERFACE_MAP_BEGIN(nsGeoPosition) NS_INTERFACE_MAP_BEGIN(nsGeoPosition)
@ -70,57 +168,24 @@ NS_INTERFACE_MAP_BEGIN(nsGeoPosition)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(GeoPosition) NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(GeoPosition)
NS_INTERFACE_MAP_END NS_INTERFACE_MAP_END
NS_IMPL_THREADSAFE_ADDREF(nsGeoPosition) NS_IMPL_ADDREF(nsGeoPosition)
NS_IMPL_THREADSAFE_RELEASE(nsGeoPosition) NS_IMPL_RELEASE(nsGeoPosition)
NS_IMETHODIMP NS_IMETHODIMP
nsGeoPosition::GetLatitude(double *aLatitude) nsGeoPosition::GetCoords(nsIDOMGeoPositionCoords * *aCoords)
{ {
*aLatitude = mLat; if (mCoords == nsnull)
mCoords = new nsGeoPositionCoords(mLat,
mLong,
mAlt,
mHError,
mVError,
mHeading,
mSpeed);
NS_IF_ADDREF(*aCoords = mCoords);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsGeoPosition::GetLongitude(double *aLongitude)
{
*aLongitude = mLong;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPosition::GetAltitude(double *aAltitude)
{
*aAltitude = mAlt;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPosition::GetAccuracy(double *aAccuracy)
{
*aAccuracy = mHError;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPosition::GetAltitudeAccuracy(double *aAltitudeAccuracy)
{
*aAltitudeAccuracy = mVError;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPosition::GetHeading(double *aHeading)
{
*aHeading = mHeading;
return NS_OK;
}
NS_IMETHODIMP
nsGeoPosition::GetSpeed(double *aSpeed)
{
*aSpeed = mSpeed;
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
nsGeoPosition::GetTimestamp(DOMTimeStamp* aTimestamp) nsGeoPosition::GetTimestamp(DOMTimeStamp* aTimestamp)
@ -133,7 +198,9 @@ nsGeoPosition::GetTimestamp(DOMTimeStamp* aTimestamp)
NS_IMPL_ISUPPORTS1(MaemoLocationProvider, nsIGeolocationProvider) NS_IMPL_ISUPPORTS1(MaemoLocationProvider, nsIGeolocationProvider)
MaemoLocationProvider::MaemoLocationProvider() MaemoLocationProvider::MaemoLocationProvider()
: mGPSDevice(nsnull), mLocationCallbackHandle(0), mHasSeenLocation(PR_FALSE) : mGPSDevice(nsnull),
mHasSeenLocation(PR_FALSE),
mLastSeenTime(0)
{ {
} }
@ -141,16 +208,24 @@ MaemoLocationProvider::~MaemoLocationProvider()
{ {
} }
void location_changed (LocationGPSDevice *device, gpointer userdata) static void location_changed(LocationGPSDevice *device, gpointer userdata)
{ {
if (!userdata || !device || !device->fix) {
return;
}
// printf ("Latitude: %.5f\nLongitude: %.5f\nAltitude: %.2f\n",
// device->fix->latitude, device->fix->longitude, device->fix->altitude);
MaemoLocationProvider* provider = (MaemoLocationProvider*) userdata; MaemoLocationProvider* provider = (MaemoLocationProvider*) userdata;
nsRefPtr<nsGeoPosition> somewhere = new nsGeoPosition(device->fix->latitude, nsRefPtr<nsGeoPosition> somewhere = new nsGeoPosition(device->fix->latitude,
device->fix->longitude, device->fix->longitude,
device->fix->altitude, device->fix->altitude,
device->fix->eph, 0,
device->fix->epv, 0,
0,0, 0,
device->fix->time); 0,
PR_Now());
provider->Update(somewhere); provider->Update(somewhere);
} }
@ -158,15 +233,14 @@ NS_IMETHODIMP MaemoLocationProvider::Startup()
{ {
if (!mGPSDevice) if (!mGPSDevice)
{ {
// if we are already started, don't do anything
memset(&mGPSBT, 0, sizeof(gpsbt_t));
int result = gpsbt_start(NULL, 0, 0, 0, NULL, 0, 0, &mGPSBT);
if (result <0)
return NS_ERROR_NOT_AVAILABLE;
mGPSDevice = (LocationGPSDevice*) g_object_new (LOCATION_TYPE_GPS_DEVICE, NULL); mGPSDevice = (LocationGPSDevice*) g_object_new (LOCATION_TYPE_GPS_DEVICE, NULL);
mLocationCallbackHandle = g_signal_connect (mGPSDevice, "changed", G_CALLBACK (location_changed), this->mCallback);
mCallbackChanged = g_signal_connect(mGPSDevice,
"changed",
G_CALLBACK(location_changed),
this);
} }
return NS_OK; return NS_OK;
} }
@ -178,34 +252,38 @@ NS_IMETHODIMP MaemoLocationProvider::IsReady(PRBool *_retval NS_OUTPARAM)
NS_IMETHODIMP MaemoLocationProvider::Watch(nsIGeolocationUpdate *callback) NS_IMETHODIMP MaemoLocationProvider::Watch(nsIGeolocationUpdate *callback)
{ {
mCallback = callback; // weak ref if (mCallback)
return NS_OK; return NS_OK;
}
/* readonly attribute nsIDOMGeoPosition currentPosition; */ mCallback = callback;
NS_IMETHODIMP MaemoLocationProvider::GetCurrentPosition(nsIDOMGeoPosition * *aCurrentPosition)
{
NS_IF_ADDREF(*aCurrentPosition = mLastPosition);
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP MaemoLocationProvider::Shutdown() NS_IMETHODIMP MaemoLocationProvider::Shutdown()
{ {
if (mGPSDevice && mLocationCallbackHandle) { if (mGPSDevice)
g_signal_handler_disconnect(mGPSDevice, mLocationCallbackHandle); {
g_signal_handler_disconnect(mGPSDevice, mCallbackChanged);
g_object_unref(mGPSDevice); g_object_unref(mGPSDevice);
gpsbt_stop(&mGPSBT);
mLocationCallbackHandle = 0;
mGPSDevice = nsnull; mGPSDevice = nsnull;
mHasSeenLocation = PR_FALSE; mHasSeenLocation = PR_FALSE;
mCallback = nsnull;
} }
return NS_OK; return NS_OK;
} }
void MaemoLocationProvider::Update(nsIDOMGeoPosition* aPosition) void MaemoLocationProvider::Update(nsIDOMGeoPosition* aPosition)
{ {
if ((PR_Now() - mLastSeenTime) / PR_USEC_PER_SEC < 5)
return;
mHasSeenLocation = PR_TRUE; mHasSeenLocation = PR_TRUE;
mLastPosition = aPosition;
if (mCallback) if (mCallback)
mCallback->Update(aPosition); mCallback->Update(aPosition);
mLastSeenTime = PR_Now();
} }

Просмотреть файл

@ -36,6 +36,7 @@
#include "nsIGeolocationProvider.h" #include "nsIGeolocationProvider.h"
#include "nsIDOMGeoPosition.h" #include "nsIDOMGeoPosition.h"
#include "nsCOMPtr.h" #include "nsCOMPtr.h"
#include <glib.h> #include <glib.h>
@ -63,13 +64,13 @@ public:
private: private:
~MaemoLocationProvider(); ~MaemoLocationProvider();
nsCOMPtr<nsIDOMGeoPosition> mLastPosition; nsCOMPtr<nsIGeolocationUpdate> mCallback;
nsIGeolocationUpdate* mCallback; // weak reference by contract.
gpsbt_t mGPSBT;
LocationGPSDevice *mGPSDevice; LocationGPSDevice *mGPSDevice;
gulong mLocationCallbackHandle;
gulong mCallbackChanged;
PRBool mHasSeenLocation; PRBool mHasSeenLocation;
PRTime mLastSeenTime;
}; };

Просмотреть файл

@ -637,7 +637,6 @@ nsGeolocation::Update(nsIDOMGeoPosition *aSomewhere)
geoService->SetCachedPosition(aSomewhere); geoService->SetCachedPosition(aSomewhere);
} }
if (!OwnerStillExists()) if (!OwnerStillExists())
{ {
Shutdown(); Shutdown();