зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1134019 - Extract MLS fallback to its own class for reuse - r=jdm
This commit is contained in:
Родитель
e941340ce5
Коммит
8f8b1e0ac7
|
@ -0,0 +1,82 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim:set ts=2 sw=2 sts=2 et cindent: */
|
||||
/* 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 "MLSFallback.h"
|
||||
#include "nsGeoPosition.h"
|
||||
#include "nsIGeolocationProvider.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(MLSFallback, nsITimerCallback)
|
||||
|
||||
MLSFallback::MLSFallback(uint32_t delay)
|
||||
: mDelayMs(delay)
|
||||
{
|
||||
}
|
||||
|
||||
MLSFallback::~MLSFallback()
|
||||
{
|
||||
}
|
||||
|
||||
nsresult
|
||||
MLSFallback::Startup(nsIGeolocationUpdate* aWatcher)
|
||||
{
|
||||
if (mHandoffTimer || mMLSFallbackProvider) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mUpdateWatcher = aWatcher;
|
||||
nsresult rv;
|
||||
mHandoffTimer = do_CreateInstance("@mozilla.org/timer;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mHandoffTimer->InitWithCallback(this, mDelayMs, nsITimer::TYPE_ONE_SHOT);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MLSFallback::Shutdown()
|
||||
{
|
||||
mUpdateWatcher = nullptr;
|
||||
|
||||
if (mHandoffTimer) {
|
||||
mHandoffTimer->Cancel();
|
||||
mHandoffTimer = nullptr;
|
||||
}
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
if (mMLSFallbackProvider) {
|
||||
rv = mMLSFallbackProvider->Shutdown();
|
||||
mMLSFallbackProvider = nullptr;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
MLSFallback::Notify(nsITimer* aTimer)
|
||||
{
|
||||
return CreateMLSFallbackProvider();
|
||||
}
|
||||
|
||||
nsresult
|
||||
MLSFallback::CreateMLSFallbackProvider()
|
||||
{
|
||||
if (mMLSFallbackProvider || !mUpdateWatcher) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
mMLSFallbackProvider = do_CreateInstance("@mozilla.org/geolocation/mls-provider;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (mMLSFallbackProvider) {
|
||||
rv = mMLSFallbackProvider->Startup();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mMLSFallbackProvider->Watch(mUpdateWatcher);
|
||||
}
|
||||
}
|
||||
mUpdateWatcher = nullptr;
|
||||
return rv;
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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 "nsCOMPtr.h"
|
||||
#include "nsITimer.h"
|
||||
|
||||
class nsIGeolocationUpdate;
|
||||
class nsIGeolocationProvider;
|
||||
|
||||
/*
|
||||
This class wraps the NetworkGeolocationProvider in a delayed startup.
|
||||
It is for providing a fallback to MLS when:
|
||||
1) using another provider as the primary provider, and
|
||||
2) that primary provider may fail to return a result (i.e. the error returned
|
||||
is indeterminate, or no error callback occurs)
|
||||
|
||||
The intent is that the primary provider is started, then MLSFallback
|
||||
is started with sufficient delay that the primary provider will respond first
|
||||
if successful (in the majority of cases).
|
||||
|
||||
MLS has an average response of 3s, so with the 2s default delay, a response can
|
||||
be expected in 5s.
|
||||
|
||||
Telemetry is recommended to monitor that the primary provider is responding
|
||||
first when expected to do so.
|
||||
*/
|
||||
class MLSFallback : public nsITimerCallback
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
|
||||
explicit MLSFallback(uint32_t delayMs = 2000);
|
||||
nsresult Startup(nsIGeolocationUpdate* aWatcher);
|
||||
nsresult Shutdown();
|
||||
|
||||
private:
|
||||
nsresult CreateMLSFallbackProvider();
|
||||
virtual ~MLSFallback();
|
||||
nsCOMPtr<nsITimer> mHandoffTimer;
|
||||
nsCOMPtr<nsIGeolocationProvider> mMLSFallbackProvider;
|
||||
nsCOMPtr<nsIGeolocationUpdate> mUpdateWatcher;
|
||||
const uint32_t mDelayMs;
|
||||
};
|
||||
|
|
@ -15,6 +15,7 @@ SOURCES += [
|
|||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'MLSFallback.cpp',
|
||||
'nsGeoGridFuzzer.cpp',
|
||||
'nsGeolocationSettings.cpp',
|
||||
'nsGeoPosition.cpp',
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include "nsCOMPtr.h"
|
||||
#include "nsIGeolocationProvider.h"
|
||||
|
||||
|
||||
/*
|
||||
* The CoreLocationObjects class contains the CoreLocation objects
|
||||
* we'll need.
|
||||
|
@ -21,6 +22,7 @@
|
|||
* for nsGeolocation.cpp, which is C++-only, to include this header.
|
||||
*/
|
||||
class CoreLocationObjects;
|
||||
class MLSFallback;
|
||||
|
||||
class CoreLocationLocationProvider
|
||||
: public nsIGeolocationProvider
|
||||
|
@ -36,11 +38,11 @@ public:
|
|||
void CancelMLSFallbackProvider();
|
||||
|
||||
private:
|
||||
virtual ~CoreLocationLocationProvider() {};
|
||||
virtual ~CoreLocationLocationProvider();
|
||||
|
||||
CoreLocationObjects* mCLObjects;
|
||||
nsCOMPtr<nsIGeolocationUpdate> mCallback;
|
||||
nsCOMPtr<nsIGeolocationProvider> mMLSFallbackProvider;
|
||||
nsRefPtr<MLSFallback> mMLSFallbackProvider;
|
||||
|
||||
class MLSUpdate : public nsIGeolocationUpdate
|
||||
{
|
||||
|
@ -52,6 +54,6 @@ private:
|
|||
|
||||
private:
|
||||
CoreLocationLocationProvider& mParentLocationProvider;
|
||||
virtual ~MLSUpdate() {}
|
||||
virtual ~MLSUpdate();
|
||||
};
|
||||
};
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "nsCocoaFeatures.h"
|
||||
#include "prtime.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
#include "MLSFallback.h"
|
||||
|
||||
#include <CoreLocation/CLError.h>
|
||||
#include <CoreLocation/CLLocation.h>
|
||||
|
@ -32,7 +33,6 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
|
|||
@interface LocationDelegate : NSObject <CLLocationManagerDelegate>
|
||||
{
|
||||
CoreLocationLocationProvider* mProvider;
|
||||
NSTimer* mHandoffTimer;
|
||||
}
|
||||
|
||||
- (id)init:(CoreLocationLocationProvider*)aProvider;
|
||||
|
@ -52,23 +52,6 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void)shutdownHandoffTimer
|
||||
{
|
||||
if (!mHandoffTimer) {
|
||||
return;
|
||||
}
|
||||
|
||||
[mHandoffTimer invalidate];
|
||||
[mHandoffTimer release];
|
||||
mHandoffTimer = nil;
|
||||
}
|
||||
|
||||
- (void)handoffToGeoIPProvider
|
||||
{
|
||||
[self shutdownHandoffTimer];
|
||||
mProvider->CreateMLSFallbackProvider();
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager*)aManager
|
||||
didFailWithError:(NSError *)aError
|
||||
{
|
||||
|
@ -87,21 +70,15 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
|
|||
return;
|
||||
}
|
||||
|
||||
if (!mHandoffTimer) {
|
||||
// The CL provider does not fallback to GeoIP, so use NetworkGeolocationProvider for this.
|
||||
// The concept here is: on error, hand off geolocation to MLS, which will then report
|
||||
// back a location or error. We can't call this with no delay however, as this method
|
||||
// is called with an error code of 0 in both failed geolocation cases, and also when
|
||||
// geolocation is not immediately available.
|
||||
// The 2 sec delay is arbitrarily large enough that CL has a reasonable head start and
|
||||
// if it is likely to succeed, it should complete before the MLS provider.
|
||||
// Take note that in locationManager:didUpdateLocations: the handoff to MLS is stopped.
|
||||
mHandoffTimer = [[NSTimer scheduledTimerWithTimeInterval:2.0
|
||||
target:self
|
||||
selector:@selector(handoffToGeoIPProvider)
|
||||
userInfo:nil
|
||||
repeats:NO] retain];
|
||||
}
|
||||
// The CL provider does not fallback to GeoIP, so use NetworkGeolocationProvider for this.
|
||||
// The concept here is: on error, hand off geolocation to MLS, which will then report
|
||||
// back a location or error. We can't call this with no delay however, as this method
|
||||
// is called with an error code of 0 in both failed geolocation cases, and also when
|
||||
// geolocation is not immediately available.
|
||||
// The 2 sec delay is arbitrarily large enough that CL has a reasonable head start and
|
||||
// if it is likely to succeed, it should complete before the MLS provider.
|
||||
// Take note that in locationManager:didUpdateLocations: the handoff to MLS is stopped.
|
||||
mProvider->CreateMLSFallbackProvider();
|
||||
}
|
||||
|
||||
- (void)locationManager:(CLLocationManager*)aManager didUpdateLocations:(NSArray*)aLocations
|
||||
|
@ -110,7 +87,6 @@ static const CLLocationAccuracy kDEFAULT_ACCURACY = kCLLocationAccuracyNearestTe
|
|||
return;
|
||||
}
|
||||
|
||||
[self shutdownHandoffTimer];
|
||||
mProvider->CancelMLSFallbackProvider();
|
||||
|
||||
CLLocation* location = [aLocations objectAtIndex:0];
|
||||
|
@ -137,6 +113,10 @@ CoreLocationLocationProvider::MLSUpdate::MLSUpdate(CoreLocationLocationProvider&
|
|||
{
|
||||
}
|
||||
|
||||
CoreLocationLocationProvider::MLSUpdate::~MLSUpdate()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CoreLocationLocationProvider::MLSUpdate::Update(nsIDOMGeoPosition *position)
|
||||
{
|
||||
|
@ -200,6 +180,10 @@ CoreLocationLocationProvider::CoreLocationLocationProvider()
|
|||
{
|
||||
}
|
||||
|
||||
CoreLocationLocationProvider::~CoreLocationLocationProvider()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
CoreLocationLocationProvider::Startup()
|
||||
{
|
||||
|
@ -234,7 +218,6 @@ CoreLocationLocationProvider::Shutdown()
|
|||
{
|
||||
NS_ENSURE_STATE(mCLObjects);
|
||||
|
||||
[mCLObjects->mLocationDelegate shutdownHandoffTimer];
|
||||
[mCLObjects->mLocationManager stopUpdatingLocation];
|
||||
|
||||
delete mCLObjects;
|
||||
|
@ -280,13 +263,8 @@ CoreLocationLocationProvider::CreateMLSFallbackProvider()
|
|||
return;
|
||||
}
|
||||
|
||||
mMLSFallbackProvider = do_CreateInstance("@mozilla.org/geolocation/mls-provider;1");
|
||||
if (mMLSFallbackProvider) {
|
||||
nsresult rv = mMLSFallbackProvider->Startup();
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
mMLSFallbackProvider->Watch(new CoreLocationLocationProvider::MLSUpdate(*this));
|
||||
}
|
||||
}
|
||||
mMLSFallbackProvider = new MLSFallback();
|
||||
mMLSFallbackProvider->Startup(new MLSUpdate(*this));
|
||||
}
|
||||
|
||||
void
|
||||
|
|
Загрузка…
Ссылка в новой задаче