Bug 599591 - Geolocation provider not turned off when navigating away from site. r=jdm a=blocking-fennec

--HG--
extra : rebase_source : 7f10d1d8486500e569cffea937d7a06bfa67dded
This commit is contained in:
Doug Turner 2010-09-27 14:23:35 -07:00
parent b70453821a
commit ae138d0b78
4 changed files with 82 additions and 27 deletions

View File

@ -512,22 +512,27 @@ ContentParent::RecvAsyncMessage(const nsString& aMsg, const nsString& aJSON)
bool
ContentParent::RecvGeolocationStart()
{
nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
if (!geo) {
return true;
if (mGeolocationWatchID == -1) {
nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
if (!geo) {
return true;
}
geo->WatchPosition(this, nsnull, nsnull, &mGeolocationWatchID);
}
geo->WatchPosition(this, nsnull, nsnull, &mGeolocationWatchID);
return true;
}
bool
ContentParent::RecvGeolocationStop()
{
nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
if (!geo) {
return true;
if (mGeolocationWatchID != -1) {
nsCOMPtr<nsIDOMGeoGeolocation> geo = do_GetService("@mozilla.org/geolocation;1");
if (!geo) {
return true;
}
geo->ClearWatch(mGeolocationWatchID);
mGeolocationWatchID = -1;
}
geo->ClearWatch(mGeolocationWatchID);
return true;
}

View File

@ -741,6 +741,11 @@ nsGeolocationService::StartDevice()
if (!sGeoEnabled)
return NS_ERROR_NOT_AVAILABLE;
// we do not want to keep the geolocation devices online
// indefinitely. Close them down after a reasonable period of
// inactivivity
SetDisconnectTimer();
#ifdef MOZ_IPC
if (XRE_GetProcessType() == GeckoProcessType_Content) {
ContentChild* cpc = ContentChild::GetSingleton();
@ -750,26 +755,18 @@ nsGeolocationService::StartDevice()
#endif
// Start them up!
nsresult rv = NS_ERROR_NOT_AVAILABLE;
for (PRUint32 i = mProviders.Count() - 1; i != PRUint32(-1); --i) {
// If any provder gets started without error, go ahead
// and proceed without error
nsresult temp = mProviders[i]->Startup();
if (NS_SUCCEEDED(temp)) {
rv = NS_OK;
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs)
return NS_ERROR_FAILURE;
mProviders[i]->Watch(this);
}
for (PRUint32 i = 0; i < mProviders.Count(); i++) {
mProviders[i]->Startup();
mProviders[i]->Watch(this);
obs->NotifyObservers(mProviders[i],
"geolocation-device-events",
NS_LITERAL_STRING("starting").get());
}
if (NS_FAILED(rv))
return NS_ERROR_NOT_AVAILABLE;
// we do not want to keep the geolocation devices online
// indefinitely. Close them down after a reasonable period of
// inactivivity
SetDisconnectTimer();
return NS_OK;
}
@ -802,8 +799,15 @@ nsGeolocationService::StopDevice()
}
#endif
for (PRUint32 i = mProviders.Count() - 1; i != PRUint32(-1); --i) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (!obs)
return;
for (PRUint32 i = 0; i <mProviders.Count(); i++) {
mProviders[i]->Shutdown();
obs->NotifyObservers(mProviders[i],
"geolocation-device-events",
NS_LITERAL_STRING("shutdown").get());
}
}
@ -944,7 +948,11 @@ nsGeolocation::Shutdown()
PRBool
nsGeolocation::HasActiveCallbacks()
{
return mWatchingCallbacks.Length() != 0;
for (PRUint32 i = 0; i < mWatchingCallbacks.Length(); i++)
if (mWatchingCallbacks[i]->IsActive())
return PR_TRUE;
return PR_FALSE;
}
void

View File

@ -97,6 +97,7 @@ class nsGeolocationRequest
void SendLocation(nsIDOMGeoPosition* location);
void MarkCleared();
PRBool IsActive() {return !mCleared;}
PRBool Allowed() {return mAllowed;}
void SetTimeoutTimer();

View File

@ -0,0 +1,41 @@
const Ci = Components.interfaces;
const Cc = Components.classes;
function successCallback(pos){}
var observer = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsISupports) ||
iid.equals(Components.interfaces.nsIObserver))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
observe: function(subject, topic, data) {
if (data == "shutdown") {
do_check_true(1)
do_test_finished();
}
else if (data == "starting") {
do_check_true(1)
}
},
};
function run_test()
{
// only kill this test when shutdown is called on the provider.
do_test_pending();
var obs = Cc["@mozilla.org/observer-service;1"].getService();
obs = obs.QueryInterface(Ci.nsIObserverService);
obs.addObserver(observer, "geolocation-device-events", false);
var geolocation = Cc["@mozilla.org/geolocation;1"].getService(Ci.nsIDOMGeoGeolocation);
var watchID = geolocation.watchPosition(successCallback);
do_timeout(1000, function() { geolocation.clearWatch(watchID);})
}