Bug 512407 - Support Windows Location API. r=jdm,jmathies

This commit is contained in:
Makoto Kato 2015-01-23 18:43:46 +09:00
parent 6091c10e20
commit 57e5a10eae
6 changed files with 249 additions and 2 deletions

View File

@ -10,9 +10,12 @@ EXPORTS += [
'nsGeoPositionIPCSerialiser.h',
]
SOURCES += [
'nsGeolocation.cpp',
]
UNIFIED_SOURCES += [
'nsGeoGridFuzzer.cpp',
'nsGeolocation.cpp',
'nsGeolocationSettings.cpp',
'nsGeoPosition.cpp',
]
@ -45,4 +48,7 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
LOCAL_INCLUDES += [
'/dom/system/mac',
]
elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
LOCAL_INCLUDES += [
'/dom/system/windows',
]

View File

@ -49,6 +49,10 @@ class nsIPrincipal;
#include "CoreLocationLocationProvider.h"
#endif
#ifdef XP_WIN
#include "WindowsLocationProvider.h"
#endif
// Some limit to the number of get or watch geolocation requests
// that a window can make.
#define MAX_GEO_REQUESTS_PER_WINDOW 1500
@ -810,6 +814,12 @@ nsresult nsGeolocationService::Init()
}
#endif
#ifdef XP_WIN
if (Preferences::GetBool("geo.provider.ms-windows-location", false)) {
mProvider = new WindowsLocationProvider();
}
#endif
if (Preferences::GetBool("geo.provider.use_mls", false)) {
mProvider = do_CreateInstance("@mozilla.org/geolocation/mls-provider;1");
}

View File

@ -0,0 +1,198 @@
/* 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 "WindowsLocationProvider.h"
#include "nsGeoPosition.h"
#include "nsIDOMGeoPositionError.h"
#include "prtime.h"
#include <LocationApi.h>
namespace mozilla {
namespace dom {
class LocationEvent MOZ_FINAL : public ILocationEvents
{
public:
LocationEvent(nsIGeolocationUpdate* aCallback)
: mCallback(aCallback), mCount(0) {
}
// IUnknown interface
STDMETHODIMP_(ULONG) AddRef() MOZ_OVERRIDE;
STDMETHODIMP_(ULONG) Release() MOZ_OVERRIDE;
STDMETHODIMP QueryInterface(REFIID iid, void** ppv) MOZ_OVERRIDE;
// ILocationEvents interface
STDMETHODIMP OnStatusChanged(REFIID aReportType,
LOCATION_REPORT_STATUS aStatus) MOZ_OVERRIDE;
STDMETHODIMP OnLocationChanged(REFIID aReportType,
ILocationReport *aReport) MOZ_OVERRIDE;
private:
nsCOMPtr<nsIGeolocationUpdate> mCallback;
ULONG mCount;
};
STDMETHODIMP_(ULONG)
LocationEvent::AddRef()
{
return InterlockedIncrement(&mCount);
}
STDMETHODIMP_(ULONG)
LocationEvent::Release()
{
ULONG count = InterlockedDecrement(&mCount);
if (!count) {
delete this;
return 0;
}
return count;
}
STDMETHODIMP
LocationEvent::QueryInterface(REFIID iid, void** ppv)
{
if (iid == IID_IUnknown) {
*ppv = static_cast<IUnknown*>(this);
} else if (iid == IID_ILocationEvents) {
*ppv = static_cast<ILocationEvents*>(this);
} else {
return E_NOINTERFACE;
}
AddRef();
return S_OK;
}
STDMETHODIMP
LocationEvent::OnStatusChanged(REFIID aReportType,
LOCATION_REPORT_STATUS aStatus)
{
if (aReportType != IID_ILatLongReport) {
return S_OK;
}
uint16_t err;
switch (aStatus) {
case REPORT_ACCESS_DENIED:
err = nsIDOMGeoPositionError::PERMISSION_DENIED;
break;
case REPORT_ERROR:
err = nsIDOMGeoPositionError::POSITION_UNAVAILABLE;
break;
default:
return S_OK;
}
mCallback->NotifyError(err);
return S_OK;
}
STDMETHODIMP
LocationEvent::OnLocationChanged(REFIID aReportType,
ILocationReport *aReport)
{
if (aReportType != IID_ILatLongReport) {
return S_OK;
}
nsRefPtr<ILatLongReport> latLongReport;
if (FAILED(aReport->QueryInterface(IID_ILatLongReport,
getter_AddRefs(latLongReport)))) {
return E_FAIL;
}
DOUBLE latitude = 0.0;
latLongReport->GetLatitude(&latitude);
DOUBLE longitude = 0.0;
latLongReport->GetLongitude(&longitude);
DOUBLE alt = 0.0;
latLongReport->GetAltitude(&alt);
DOUBLE herror = 0.0;
latLongReport->GetErrorRadius(&herror);
DOUBLE verror = 0.0;
latLongReport->GetAltitudeError(&verror);
nsRefPtr<nsGeoPosition> position =
new nsGeoPosition(latitude, longitude, alt, herror, verror, 0.0, 0.0,
PR_Now());
mCallback->Update(position);
return S_OK;
}
NS_IMPL_ISUPPORTS(WindowsLocationProvider, nsIGeolocationProvider)
WindowsLocationProvider::WindowsLocationProvider()
{
}
NS_IMETHODIMP
WindowsLocationProvider::Startup()
{
nsRefPtr<ILocation> location;
if (FAILED(::CoCreateInstance(CLSID_Location, nullptr, CLSCTX_INPROC_SERVER,
IID_ILocation,
getter_AddRefs(location)))) {
return NS_ERROR_FAILURE;
}
IID reportTypes[] = { IID_ILatLongReport };
if (FAILED(location->RequestPermissions(nullptr, reportTypes, 1, FALSE))) {
return NS_ERROR_FAILURE;
}
mLocation = location;
return NS_OK;
}
NS_IMETHODIMP
WindowsLocationProvider::Watch(nsIGeolocationUpdate* aCallback)
{
nsRefPtr<LocationEvent> event = new LocationEvent(aCallback);
if (FAILED(mLocation->RegisterForReport(event, IID_ILatLongReport, 0))) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
WindowsLocationProvider::Shutdown()
{
if (mLocation) {
mLocation->UnregisterForReport(IID_ILatLongReport);
mLocation = nullptr;
}
return NS_OK;
}
NS_IMETHODIMP
WindowsLocationProvider::SetHighAccuracy(bool enable)
{
if (!mLocation) {
return NS_ERROR_FAILURE;
}
LOCATION_DESIRED_ACCURACY desiredAccuracy;
if (enable) {
desiredAccuracy = LOCATION_DESIRED_ACCURACY_HIGH;
} else {
desiredAccuracy = LOCATION_DESIRED_ACCURACY_DEFAULT;
}
if (FAILED(mLocation->SetDesiredAccuracy(IID_ILatLongReport,
desiredAccuracy))) {
return NS_ERROR_FAILURE;
}
return NS_OK;
}
} // namespace dom
} // namespace mozilla

View File

@ -0,0 +1,31 @@
/* 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/. */
#ifndef mozilla_dom_WindowsLocationProvider_h__
#define mozilla_dom_WindowsLocationProvider_h__
#include "nsAutoPtr.h"
#include "nsIGeolocationProvider.h"
#include <LocationApi.h>
namespace mozilla {
namespace dom {
class WindowsLocationProvider MOZ_FINAL : public nsIGeolocationProvider
{
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGEOLOCATIONPROVIDER
WindowsLocationProvider();
private:
nsRefPtr<ILocation> mLocation;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_WindowsLocationProvider_h__

View File

@ -6,6 +6,7 @@
SOURCES += [
'nsHapticFeedback.cpp',
'WindowsLocationProvider.cpp'
]
FAIL_ON_WARNINGS = True

View File

@ -350,6 +350,7 @@ if CONFIG['OS_ARCH'] == 'WINNT':
'wbemuuid',
'wintrust',
'wtsapi32',
'locationapi'
]
if CONFIG['ACCESSIBILITY']:
OS_LIBS += [