mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1216148 - Handle how geolocation acts when the app's visibility changes. r=kchen.
Add the wake lock api to geolocation. If your app holds a lock, you can continue use geolocation service when your app is invisible. Otherwise, your invisible app can't get any updated location.
This commit is contained in:
parent
f86b489302
commit
d75819d824
@ -20,15 +20,20 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsContentPermissionHelper.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMEvent.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/HalWakeLock.h"
|
||||
#include "mozilla/Hal.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/dom/Event.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/SettingChangeNotificationBinding.h"
|
||||
#include "mozilla/dom/WakeLock.h"
|
||||
|
||||
#include "nsJSUtils.h"
|
||||
#include "prdtoa.h"
|
||||
@ -66,6 +71,7 @@ class nsIPrincipal;
|
||||
using mozilla::Unused; // <snicker>
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::hal;
|
||||
|
||||
class nsGeolocationRequest final
|
||||
: public nsIContentPermissionRequest
|
||||
@ -499,6 +505,10 @@ nsGeolocationRequest::Allow(JS::HandleValue aChoices)
|
||||
}
|
||||
}
|
||||
|
||||
if (mLocator->ContainsRequest(this)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mIsWatchPositionRequest || !canUseCache) {
|
||||
// let the locator know we're pending
|
||||
// we will now be owned by the locator
|
||||
@ -1044,6 +1054,16 @@ nsGeolocationService::StartDevice(nsIPrincipal *aPrincipal)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsGeolocationService::StopDisconnectTimer()
|
||||
{
|
||||
if (mDisconnectTimer) {
|
||||
mDisconnectTimer->Cancel();
|
||||
mDisconnectTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
nsGeolocationService::SetDisconnectTimer()
|
||||
{
|
||||
@ -1096,10 +1116,7 @@ nsGeolocationService::UpdateAccuracy(bool aForceHigh)
|
||||
void
|
||||
nsGeolocationService::StopDevice()
|
||||
{
|
||||
if(mDisconnectTimer) {
|
||||
mDisconnectTimer->Cancel();
|
||||
mDisconnectTimer = nullptr;
|
||||
}
|
||||
StopDisconnectTimer();
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
ContentChild* cpc = ContentChild::GetSingleton();
|
||||
@ -1209,6 +1226,14 @@ Geolocation::Init(nsIDOMWindow* aContentDom)
|
||||
}
|
||||
|
||||
mPrincipal = doc->NodePrincipal();
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
doc->AddSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
|
||||
/* listener */ this,
|
||||
/* use capture */ true,
|
||||
/* wants untrusted */ false);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// If no aContentDom was passed into us, we are being used
|
||||
@ -1221,6 +1246,58 @@ Geolocation::Init(nsIDOMWindow* aContentDom)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
Geolocation::ContainsRequest(nsGeolocationRequest* aRequest)
|
||||
{
|
||||
if (aRequest->IsWatch()) {
|
||||
if (mWatchingCallbacks.Contains(aRequest)) {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
if (mPendingCallbacks.Contains(aRequest)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
Geolocation::HandleEvent(nsIDOMEvent* aEvent)
|
||||
{
|
||||
|
||||
nsAutoString type;
|
||||
aEvent->GetType(type);
|
||||
if (!type.EqualsLiteral("visibilitychange")) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> doc = do_QueryInterface(aEvent->InternalDOMEvent()->GetTarget());
|
||||
MOZ_ASSERT(doc);
|
||||
|
||||
if (doc->Hidden()) {
|
||||
WakeLockInformation info;
|
||||
GetWakeLockInfo(NS_LITERAL_STRING("gps"), &info);
|
||||
|
||||
MOZ_ASSERT(XRE_IsContentProcess());
|
||||
ContentChild* cpc = ContentChild::GetSingleton();
|
||||
if (!info.lockingProcesses().Contains(cpc->GetID())) {
|
||||
cpc->SendRemoveGeolocationListener();
|
||||
mService->StopDisconnectTimer();
|
||||
}
|
||||
} else {
|
||||
mService->SetDisconnectTimer();
|
||||
for (uint32_t i = 0, length = mWatchingCallbacks.Length(); i < length; ++i) {
|
||||
mWatchingCallbacks[i]->Allow(JS::UndefinedHandleValue);
|
||||
}
|
||||
for (uint32_t i = 0, length = mPendingCallbacks.Length(); i < length; ++i) {
|
||||
mPendingCallbacks[i]->Allow(JS::UndefinedHandleValue);
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
Geolocation::Shutdown()
|
||||
{
|
||||
@ -1228,6 +1305,18 @@ Geolocation::Shutdown()
|
||||
mPendingCallbacks.Clear();
|
||||
mWatchingCallbacks.Clear();
|
||||
|
||||
if (XRE_IsContentProcess()) {
|
||||
nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mOwner);
|
||||
if (window) {
|
||||
nsCOMPtr<nsIDocument> doc = window->GetExtantDoc();
|
||||
if (doc) {
|
||||
doc->RemoveSystemEventListener(NS_LITERAL_STRING("visibilitychange"),
|
||||
this,
|
||||
/* useCapture = */ true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mService) {
|
||||
mService->RemoveLocator(this);
|
||||
mService->UpdateAccuracy();
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
#include "nsGeoPosition.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMGeoGeolocation.h"
|
||||
#include "nsIDOMGeoPosition.h"
|
||||
#include "nsIDOMGeoPositionError.h"
|
||||
@ -91,6 +92,7 @@ public:
|
||||
|
||||
// create, or reinitalize the callback timer
|
||||
void SetDisconnectTimer();
|
||||
void StopDisconnectTimer();
|
||||
|
||||
// Update the accuracy and notify the provider if changed
|
||||
void UpdateAccuracy(bool aForceHigh = false);
|
||||
@ -128,7 +130,8 @@ namespace dom {
|
||||
*/
|
||||
class Geolocation final : public nsIDOMGeoGeolocation,
|
||||
public nsIGeolocationUpdate,
|
||||
public nsWrapperCache
|
||||
public nsWrapperCache,
|
||||
public nsIDOMEventListener
|
||||
{
|
||||
public:
|
||||
|
||||
@ -138,6 +141,8 @@ public:
|
||||
NS_DECL_NSIGEOLOCATIONUPDATE
|
||||
NS_DECL_NSIDOMGEOGEOLOCATION
|
||||
|
||||
NS_DECL_NSIDOMEVENTLISTENER
|
||||
|
||||
Geolocation();
|
||||
|
||||
nsresult Init(nsIDOMWindow* contentDom=nullptr);
|
||||
@ -154,6 +159,9 @@ public:
|
||||
// Register an allowed request
|
||||
void NotifyAllowedRequest(nsGeolocationRequest* aRequest);
|
||||
|
||||
// Check if callbacks arrays already contain this request
|
||||
bool ContainsRequest(nsGeolocationRequest* aRequest);
|
||||
|
||||
// Remove request from all callbacks arrays
|
||||
void RemoveRequest(nsGeolocationRequest* request);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user