mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-29 15:52:07 +00:00
Bug 1129633 - part1. Use win8 geolocation with a fallback to MLS - r=m_kato
This commit is contained in:
parent
3d1dca594c
commit
7ca28cc267
@ -51,6 +51,7 @@ class nsIPrincipal;
|
||||
|
||||
#ifdef XP_WIN
|
||||
#include "WindowsLocationProvider.h"
|
||||
#include "mozilla/WindowsVersion.h"
|
||||
#endif
|
||||
|
||||
// Some limit to the number of get or watch geolocation requests
|
||||
@ -815,7 +816,8 @@ nsresult nsGeolocationService::Init()
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
if (Preferences::GetBool("geo.provider.ms-windows-location", false)) {
|
||||
if (Preferences::GetBool("geo.provider.ms-windows-location", false) &&
|
||||
IsWin8OrLater()) {
|
||||
mProvider = new WindowsLocationProvider();
|
||||
}
|
||||
#endif
|
||||
|
@ -5,16 +5,59 @@
|
||||
#include "WindowsLocationProvider.h"
|
||||
#include "nsGeoPosition.h"
|
||||
#include "nsIDOMGeoPositionError.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "prtime.h"
|
||||
#include "MLSFallback.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
NS_IMPL_ISUPPORTS(WindowsLocationProvider::MLSUpdate, nsIGeolocationUpdate);
|
||||
|
||||
WindowsLocationProvider::MLSUpdate::MLSUpdate(nsIGeolocationUpdate* aCallback)
|
||||
: mCallback(aCallback)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WindowsLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *aPosition)
|
||||
{
|
||||
if (!mCallback) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMGeoPositionCoords> coords;
|
||||
aPosition->GetCoords(getter_AddRefs(coords));
|
||||
if (!coords) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// TODO add telemetry here to track volume of MLS vs native geo responses
|
||||
|
||||
return mCallback->Update(aPosition);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WindowsLocationProvider::MLSUpdate::LocationUpdatePending()
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WindowsLocationProvider::MLSUpdate::NotifyError(uint16_t aError)
|
||||
{
|
||||
if (!mCallback) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return mCallback->NotifyError(aError);
|
||||
}
|
||||
|
||||
|
||||
class LocationEvent MOZ_FINAL : public ILocationEvents
|
||||
{
|
||||
public:
|
||||
LocationEvent(nsIGeolocationUpdate* aCallback)
|
||||
: mCallback(aCallback), mCount(0) {
|
||||
LocationEvent(nsIGeolocationUpdate* aCallback, WindowsLocationProvider *aProvider)
|
||||
: mCallback(aCallback), mProvider(aProvider), mCount(0) {
|
||||
}
|
||||
|
||||
// IUnknown interface
|
||||
@ -30,6 +73,7 @@ public:
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIGeolocationUpdate> mCallback;
|
||||
nsRefPtr<WindowsLocationProvider> mProvider;
|
||||
ULONG mCount;
|
||||
};
|
||||
|
||||
@ -73,18 +117,34 @@ LocationEvent::OnStatusChanged(REFIID aReportType,
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// When registering event, REPORT_INITIALIZING is fired at first.
|
||||
// Then, when the location is found, REPORT_RUNNING is fired.
|
||||
if (aStatus == REPORT_RUNNING) {
|
||||
// location is found by Windows Location provider, we use it.
|
||||
mProvider->CancelMLSProvider();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Cannot get current location at this time. We use MLS instead until
|
||||
// Location API returns RUNNING status.
|
||||
if (NS_SUCCEEDED(mProvider->CreateAndWatchMLSProvider(mCallback))) {
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
// Cannot watch location by MLS provider. We must return error by
|
||||
// Location API.
|
||||
uint16_t err;
|
||||
switch (aStatus) {
|
||||
case REPORT_ACCESS_DENIED:
|
||||
err = nsIDOMGeoPositionError::PERMISSION_DENIED;
|
||||
break;
|
||||
case REPORT_NOT_SUPPORTED:
|
||||
case REPORT_ERROR:
|
||||
err = nsIDOMGeoPositionError::POSITION_UNAVAILABLE;
|
||||
break;
|
||||
default:
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
mCallback->NotifyError(err);
|
||||
return S_OK;
|
||||
}
|
||||
@ -132,6 +192,10 @@ WindowsLocationProvider::WindowsLocationProvider()
|
||||
{
|
||||
}
|
||||
|
||||
WindowsLocationProvider::~WindowsLocationProvider()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
WindowsLocationProvider::Startup()
|
||||
{
|
||||
@ -139,12 +203,14 @@ WindowsLocationProvider::Startup()
|
||||
if (FAILED(::CoCreateInstance(CLSID_Location, nullptr, CLSCTX_INPROC_SERVER,
|
||||
IID_ILocation,
|
||||
getter_AddRefs(location)))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
// We will use MLS provider
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
IID reportTypes[] = { IID_ILatLongReport };
|
||||
if (FAILED(location->RequestPermissions(nullptr, reportTypes, 1, FALSE))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
// We will use MLS provider
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mLocation = location;
|
||||
@ -154,11 +220,17 @@ WindowsLocationProvider::Startup()
|
||||
NS_IMETHODIMP
|
||||
WindowsLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
|
||||
{
|
||||
nsRefPtr<LocationEvent> event = new LocationEvent(aCallback);
|
||||
if (FAILED(mLocation->RegisterForReport(event, IID_ILatLongReport, 0))) {
|
||||
return NS_ERROR_FAILURE;
|
||||
if (mLocation) {
|
||||
nsRefPtr<LocationEvent> event = new LocationEvent(aCallback, this);
|
||||
if (SUCCEEDED(mLocation->RegisterForReport(event, IID_ILatLongReport, 0))) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
|
||||
// Cannot use Location API. We will use MLS instead.
|
||||
mLocation = nullptr;
|
||||
|
||||
return CreateAndWatchMLSProvider(aCallback);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -169,6 +241,8 @@ WindowsLocationProvider::Shutdown()
|
||||
mLocation = nullptr;
|
||||
}
|
||||
|
||||
CancelMLSProvider();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -176,7 +250,8 @@ NS_IMETHODIMP
|
||||
WindowsLocationProvider::SetHighAccuracy(bool enable)
|
||||
{
|
||||
if (!mLocation) {
|
||||
return NS_ERROR_FAILURE;
|
||||
// MLS provider doesn't support HighAccuracy
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
LOCATION_DESIRED_ACCURACY desiredAccuracy;
|
||||
@ -192,5 +267,28 @@ WindowsLocationProvider::SetHighAccuracy(bool enable)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
WindowsLocationProvider::CreateAndWatchMLSProvider(
|
||||
nsIGeolocationUpdate* aCallback)
|
||||
{
|
||||
if (mMLSProvider) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mMLSProvider = new MLSFallback();
|
||||
return mMLSProvider->Startup(new MLSUpdate(aCallback));
|
||||
}
|
||||
|
||||
void
|
||||
WindowsLocationProvider::CancelMLSProvider()
|
||||
{
|
||||
if (!mMLSProvider) {
|
||||
return;
|
||||
}
|
||||
|
||||
mMLSProvider->Shutdown();
|
||||
mMLSProvider = nullptr;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -10,6 +10,8 @@
|
||||
|
||||
#include <locationapi.h>
|
||||
|
||||
class MLSFallback;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
|
||||
@ -21,10 +23,25 @@ public:
|
||||
|
||||
WindowsLocationProvider();
|
||||
|
||||
nsresult CreateAndWatchMLSProvider(nsIGeolocationUpdate* aCallback);
|
||||
void CancelMLSProvider();
|
||||
|
||||
class MLSUpdate : public nsIGeolocationUpdate
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIGEOLOCATIONUPDATE
|
||||
explicit MLSUpdate(nsIGeolocationUpdate* aCallback);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIGeolocationUpdate> mCallback;
|
||||
virtual ~MLSUpdate() {}
|
||||
};
|
||||
private:
|
||||
~WindowsLocationProvider() {}
|
||||
~WindowsLocationProvider();
|
||||
|
||||
nsRefPtr<ILocation> mLocation;
|
||||
nsRefPtr<MLSFallback> mMLSProvider;
|
||||
};
|
||||
|
||||
} // namespace dom
|
||||
|
@ -9,6 +9,10 @@ SOURCES += [
|
||||
'WindowsLocationProvider.cpp'
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/dom/geolocation'
|
||||
]
|
||||
|
||||
FAIL_ON_WARNINGS = True
|
||||
|
||||
FINAL_LIBRARY = 'xul'
|
||||
|
Loading…
Reference in New Issue
Block a user