Bug 977725 - MLS Geolocation seeding GONK GPS Provider. r=kanru

This commit is contained in:
Doug Turner 2014-03-22 00:42:55 -07:00
parent 55787600ac
commit c11d4eaa2b
6 changed files with 114 additions and 15 deletions

View File

@ -187,7 +187,8 @@ pref("privacy.item.syncAccount", true);
// base url for the wifi geolocation network provider
pref("geo.provider.use_mls", false);
pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
pref("geo.cell.scan", true);
pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZ_MOZILLA_API_KEY%");
// enable geo
pref("geo.enabled", true);

View File

@ -1369,6 +1369,11 @@ pref("dom.debug.propagate_gesture_events_through_content", false);
// The request URL of the GeoLocation backend.
pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_API_KEY%");
#ifdef RELEASE_BUILD
pref("geo.wifi.logging.enabled", false);
#else
pref("geo.wifi.logging.enabled", true);
#endif
// Necko IPC security checks only needed for app isolation for cookies/cache/etc:
// currently irrelevant for desktop e10s

View File

@ -684,7 +684,7 @@ nsresult nsGeolocationService::Init()
#endif
#ifdef MOZ_WIDGET_GONK
mProvider = do_GetService(GONK_GPS_GEOLOCATION_PROVIDER_CONTRACTID);
mProvider = do_CreateInstance(GONK_GPS_GEOLOCATION_PROVIDER_CONTRACTID);
#endif
#ifdef MOZ_WIDGET_COCOA
@ -694,7 +694,7 @@ nsresult nsGeolocationService::Init()
#endif
if (Preferences::GetBool("geo.provider.use_mls", false)) {
mProvider = do_GetService("@mozilla.org/geolocation/mls-provider;1");
mProvider = do_CreateInstance("@mozilla.org/geolocation/mls-provider;1");
}
// Override platform-specific providers with the default (network)

View File

@ -87,6 +87,8 @@ WifiGeoPositionProvider.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIGeolocationProvider,
Ci.nsIWifiListener,
Ci.nsITimerCallback]),
listener: null,
startup: function() {
if (this.started)
return;
@ -104,6 +106,7 @@ WifiGeoPositionProvider.prototype = {
},
watch: function(c) {
this.listener = c;
},
shutdown: function() {
@ -121,6 +124,7 @@ WifiGeoPositionProvider.prototype = {
this.wifiService.stopWatching(this);
this.wifiService = null;
}
this.listener = null;
this.started = false;
},
@ -186,17 +190,18 @@ WifiGeoPositionProvider.prototype = {
notify: function (timeoutTimer) {
let url = Services.urlFormatter.formatURLPref("geo.wifi.uri");
let listener = this.listener;
LOG("Sending request: " + url + "\n");
let xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
getGeoService().locationUpdatePending();
listener.locationUpdatePending();
try {
xhr.open("POST", url, true);
} catch (e) {
getGeoService().notifyError(POSITION_UNAVAILABLE);
listener.notifyError(POSITION_UNAVAILABLE);
return;
}
xhr.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
@ -204,13 +209,13 @@ WifiGeoPositionProvider.prototype = {
xhr.mozBackgroundRequest = true;
xhr.channel.loadFlags = Ci.nsIChannel.LOAD_ANONYMOUS;
xhr.onerror = function() {
getGeoService().notifyError(POSITION_UNAVAILABLE);
listener.notifyError(POSITION_UNAVAILABLE);
};
xhr.onload = function() {
LOG("gls returned status: " + xhr.status + " --> " + JSON.stringify(xhr.response));
if ((xhr.channel instanceof Ci.nsIHttpChannel && xhr.status != 200) ||
!xhr.response || !xhr.response.location) {
getGeoService().notifyError(POSITION_UNAVAILABLE);
listener.notifyError(POSITION_UNAVAILABLE);
return;
}
@ -218,7 +223,7 @@ WifiGeoPositionProvider.prototype = {
xhr.response.location.lng,
xhr.response.accuracy);
getGeoService().update(newLocation);
listener.update(newLocation);
};
if (gCellScanningEnabled) {
@ -239,8 +244,4 @@ WifiGeoPositionProvider.prototype = {
},
};
function getGeoService() {
return Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationUpdate);
}
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([WifiGeoPositionProvider]);

View File

@ -26,6 +26,7 @@
#include "nsServiceManagerUtils.h"
#include "nsThreadUtils.h"
#include "nsContentUtils.h"
#include "prtime.h"
#ifdef MOZ_B2G_RIL
#include "nsIDOMIccInfo.h"
@ -98,6 +99,7 @@ GonkGPSGeolocationProvider::LocationCallback(GpsLocation* location)
NS_IMETHOD Run() {
nsRefPtr<GonkGPSGeolocationProvider> provider =
GonkGPSGeolocationProvider::GetSingleton();
provider->mLastGPSDerivedLocationTime = PR_Now();
nsCOMPtr<nsIGeolocationUpdate> callback = provider->mLocationCallback;
if (callback) {
callback->Update(mPosition);
@ -285,8 +287,8 @@ GonkGPSGeolocationProvider::GonkGPSGeolocationProvider()
: mStarted(false)
, mSupportsScheduling(false)
#ifdef MOZ_B2G_RIL
, mSupportsMSB(false)
, mSupportsMSA(false)
, mSupportsMSB(false)
, mSupportsMSA(false)
#endif
, mSupportsSingleShot(false)
, mSupportsTimeInjection(false)
@ -523,8 +525,29 @@ GonkGPSGeolocationProvider::SetReferenceLocation()
}
}
}
#endif // MOZ_B2G_RIL
void
GonkGPSGeolocationProvider::InjectLocation(double latitude,
double longitude,
float accuracy)
{
#ifdef DEBUG_GPS
printf_stderr("*** injecting location\n");
printf_stderr("*** lat: %f\n", latitude);
printf_stderr("*** lon: %f\n", longitude);
printf_stderr("*** accuracy: %f\n", accuracy);
#endif
MOZ_ASSERT(NS_IsMainThread());
if (!mGpsInterface) {
return;
}
mGpsInterface->inject_location(latitude, longitude, accuracy);
}
void
GonkGPSGeolocationProvider::Init()
{
@ -626,6 +649,49 @@ GonkGPSGeolocationProvider::SetupAGPS()
}
#endif // MOZ_B2G_RIL
NS_IMPL_ISUPPORTS1(GonkGPSGeolocationProvider::NetworkLocationUpdate,
nsIGeolocationUpdate)
NS_IMETHODIMP
GonkGPSGeolocationProvider::NetworkLocationUpdate::Update(nsIDOMGeoPosition *position)
{
nsRefPtr<GonkGPSGeolocationProvider> provider =
GonkGPSGeolocationProvider::GetSingleton();
nsCOMPtr<nsIDOMGeoPositionCoords> coords;
position->GetCoords(getter_AddRefs(coords));
if (!coords) {
return NS_ERROR_FAILURE;
}
// if we haven't seen anything from the GPS device for 1s,
// use this network derived location.
int64_t diff = PR_Now() - provider->mLastGPSDerivedLocationTime;
if (provider->mLocationCallback && diff > kDefaultPeriod) {
provider->mLocationCallback->Update(position);
}
double lat, lon, acc;
coords->GetLatitude(&lat);
coords->GetLongitude(&lon);
coords->GetAccuracy(&acc);
provider->InjectLocation(lat, lon, acc);
return NS_OK;
}
NS_IMETHODIMP
GonkGPSGeolocationProvider::NetworkLocationUpdate::LocationUpdatePending()
{
return NS_OK;
}
NS_IMETHODIMP
GonkGPSGeolocationProvider::NetworkLocationUpdate::NotifyError(uint16_t error)
{
return NS_OK;
}
NS_IMETHODIMP
GonkGPSGeolocationProvider::Startup()
{
@ -643,6 +709,16 @@ GonkGPSGeolocationProvider::Startup()
mInitThread->Dispatch(NS_NewRunnableMethod(this, &GonkGPSGeolocationProvider::Init),
NS_DISPATCH_NORMAL);
mNetworkLocationProvider = do_CreateInstance("@mozilla.org/geolocation/mls-provider;1");
if (mNetworkLocationProvider) {
nsresult rv = mNetworkLocationProvider->Startup();
if (NS_SUCCEEDED(rv)) {
nsRefPtr<NetworkLocationUpdate> update = new NetworkLocationUpdate();
mNetworkLocationProvider->Watch(update);
}
}
mLastGPSDerivedLocationTime = 0;
mStarted = true;
return NS_OK;
}
@ -665,6 +741,7 @@ GonkGPSGeolocationProvider::Shutdown()
return NS_OK;
}
mStarted = false;
mNetworkLocationProvider = nullptr;
#ifdef MOZ_B2G_RIL
if (mRadioInterface) {

View File

@ -55,7 +55,7 @@ private:
GonkGPSGeolocationProvider();
GonkGPSGeolocationProvider(const GonkGPSGeolocationProvider &);
GonkGPSGeolocationProvider & operator = (const GonkGPSGeolocationProvider &);
~GonkGPSGeolocationProvider();
virtual ~GonkGPSGeolocationProvider();
static void LocationCallback(GpsLocation* location);
static void StatusCallback(GpsStatus* status);
@ -81,6 +81,7 @@ private:
void Init();
void StartGPS();
void ShutdownGPS();
void InjectLocation(double latitude, double longitude, float accuracy);
#ifdef MOZ_B2G_RIL
void SetupAGPS();
int32_t GetDataConnectionState();
@ -113,7 +114,21 @@ private:
nsCOMPtr<nsIRadioInterface> mRadioInterface;
#endif
nsCOMPtr<nsIGeolocationUpdate> mLocationCallback;
PRTime mLastGPSDerivedLocationTime;
nsCOMPtr<nsIThread> mInitThread;
nsCOMPtr<nsIGeolocationProvider> mNetworkLocationProvider;
class NetworkLocationUpdate : public nsIGeolocationUpdate
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGEOLOCATIONUPDATE
NetworkLocationUpdate() {}
private:
virtual ~NetworkLocationUpdate() {}
};
};
#endif /* GonkGPSGeolocationProvider_h */