Bug 459893. Geolocation prompt stops working if initializer window is closed. r=smaug/gavin. relanding with leak in tests fixed

This commit is contained in:
Doug Turner 2008-10-24 09:06:27 -07:00
Родитель b01fc785a9
Коммит 295cfaa5ec
6 изменённых файлов: 111 добавлений и 107 удалений

Просмотреть файл

@ -1052,61 +1052,6 @@ function prepareForStartup() {
gGestureSupport.init(true);
}
function setupGeolocationPrompt()
{
var geolocationService = Cc["@mozilla.org/geolocation/service;1"].getService(Ci.nsIGeolocationService);
if (geolocationService.prompt)
return;
geolocationService.prompt = function(request) {
function getChromeWindow(aWindow) {
var chromeWin = aWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow)
.QueryInterface(Ci.nsIDOMChromeWindow);
return chromeWin;
}
var requestingWindow = request.requestingWindow.top;
var tabbrowser = getChromeWindow(requestingWindow).wrappedJSObject.gBrowser;
var browser = tabbrowser.getBrowserForDocument(requestingWindow.document);
var notificationBox = tabbrowser.getNotificationBox(browser);
var notification = notificationBox.getNotificationWithValue("geolocation");
if (!notification) {
var buttons = [{
label: gNavigatorBundle.getString("geolocation.exactLocation"),
accessKey: gNavigatorBundle.getString("geolocation.exactLocationKey"),
callback: function() request.allow() ,
},
{
label: gNavigatorBundle.getString("geolocation.neighborhoodLocation"),
accessKey: gNavigatorBundle.getString("geolocation.neighborhoodLocationKey"),
callback: function() request.allowButFuzz() ,
},
{
label: gNavigatorBundle.getString("geolocation.nothingLocation"),
accessKey: gNavigatorBundle.getString("geolocation.nothingLocationKey"),
callback: function() request.cancel() ,
}];
var message = gNavigatorBundle.getFormattedString("geolocation.requestMessage", [request.requestingURI.spec]);
notificationBox.appendNotification(message,
"geolocation",
"chrome://browser/skin/Info.png",
notificationBox.PRIORITY_INFO_HIGH,
buttons);
}
};
}
function delayedStartup(isLoadingBlank, mustLoadSidebar) {
var os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
os.addObserver(gSessionHistoryObserver, "browser:purge-session-history", false);
@ -1302,9 +1247,6 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
placesContext.addEventListener("popuphiding", updateEditUIVisibility, false);
#endif
// hook up the geolocation prompt to our notificationBox
setupGeolocationPrompt();
}
function BrowserShutdown()

Просмотреть файл

@ -784,7 +784,68 @@ BrowserGlue.prototype = {
]
}
function GeolocationPrompt() {}
GeolocationPrompt.prototype = {
classDescription: "Geolocation Prompting Component",
classID: Components.ID("{C6E8C44D-9F39-4AF7-BCC0-76E38A8310F5}"),
contractID: "@mozilla.org/geolocation/prompt;1",
QueryInterface: XPCOMUtils.generateQI([Ci.nsIGeolocationPrompt]),
prompt: function(request) {
function getChromeWindow(aWindow) {
var chromeWin = aWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow)
.QueryInterface(Ci.nsIDOMChromeWindow);
return chromeWin;
}
var requestingWindow = request.requestingWindow.top;
var tabbrowser = getChromeWindow(requestingWindow).wrappedJSObject.gBrowser;
var browser = tabbrowser.getBrowserForDocument(requestingWindow.document);
var notificationBox = tabbrowser.getNotificationBox(browser);
var notification = notificationBox.getNotificationWithValue("geolocation");
if (!notification) {
var bundleService = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService);
var browserBundle = bundleService.createBundle("chrome://browser/locale/browser.properties");
var buttons = [{
label: browserBundle.GetStringFromName("geolocation.exactLocation"),
accessKey: browserBundle.GetStringFromName("geolocation.exactLocationKey"),
callback: function() request.allow() ,
},
{
label: browserBundle.GetStringFromName("geolocation.neighborhoodLocation"),
accessKey: browserBundle.GetStringFromName("geolocation.neighborhoodLocationKey"),
callback: function() request.allowButFuzz() ,
},
{
label: browserBundle.GetStringFromName("geolocation.nothingLocation"),
accessKey: browserBundle.GetStringFromName("geolocation.nothingLocationKey"),
callback: function() request.cancel() ,
}];
var message = browserBundle.formatStringFromName("geolocation.requestMessage",
[request.requestingURI.spec], 1);
notificationBox.appendNotification(message,
"geolocation",
"chrome://browser/skin/Info.png",
notificationBox.PRIORITY_INFO_HIGH,
buttons);
}
},
};
//module initialization
function NSGetModule(aCompMgr, aFileSpec) {
return XPCOMUtils.generateModule([BrowserGlue]);
return XPCOMUtils.generateModule([BrowserGlue, GeolocationPrompt]);
}

Просмотреть файл

@ -43,14 +43,6 @@ interface nsIDOMWindow;
interface nsIDOMGeoPosition;
interface nsIGeolocationPrompt;
/**
* nsIGeolocationService
*/
[scriptable, uuid(68300FFD-802C-431B-BF92-0A657696B853)]
interface nsIGeolocationService : nsISupports {
attribute nsIGeolocationPrompt prompt;
};
/**
* Interface allows access to a geolocation and is passed to
* the nsIGeolocationPrompt so that the application can approve
@ -136,6 +128,15 @@ interface nsIGeolocationProvider : nsISupports {
};
%{C++
#define NS_GEOLOCATION_SERVICE_CONTRACTID "@mozilla.org/geolocation/service;1"
/*
This must be implemented by geolocation providers. It
must support nsIGeolocationProvider.
*/
#define NS_GEOLOCATION_PROVIDER_CONTRACTID "@mozilla.org/geolocation/provider;1"
/*
This must be implemented by embedders. It must support
nsIGeolocationPrompt.
*/
#define NS_GEOLOCATION_PROMPT_CONTRACTID "@mozilla.org/geolocation/prompt;1"
%}

Просмотреть файл

@ -395,7 +395,6 @@ nsGeoPosition::GetTimestamp(DOMTimeStamp* aTimestamp)
NS_INTERFACE_MAP_BEGIN(nsGeolocationService)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIGeolocationUpdate)
NS_INTERFACE_MAP_ENTRY(nsIGeolocationUpdate)
NS_INTERFACE_MAP_ENTRY(nsIGeolocationService)
NS_INTERFACE_MAP_ENTRY(nsIObserver)
NS_INTERFACE_MAP_END
@ -433,8 +432,6 @@ nsGeolocationService::Observe(nsISupports* aSubject,
StopDevice();
// Remove our reference to any prompt that may have been set.
mPrompt = nsnull;
return NS_OK;
}
@ -457,22 +454,6 @@ nsGeolocationService::Observe(nsISupports* aSubject,
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP
nsGeolocationService::GetPrompt(nsIGeolocationPrompt * *aPrompt)
{
NS_ENSURE_ARG_POINTER(aPrompt);
*aPrompt = mPrompt;
NS_IF_ADDREF(*aPrompt);
return NS_OK;
}
NS_IMETHODIMP
nsGeolocationService::SetPrompt(nsIGeolocationPrompt * aPrompt)
{
mPrompt = aPrompt;
return NS_OK;
}
NS_IMETHODIMP
nsGeolocationService::Update(nsIDOMGeoPosition *aSomewhere)
{
@ -719,7 +700,8 @@ nsGeolocation::GetCurrentPosition(nsIDOMGeoPositionCallback *callback,
nsIDOMGeoPositionErrorCallback *errorCallback,
nsIDOMGeoPositionOptions *options)
{
nsIGeolocationPrompt* prompt = mService->GetPrompt();
nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
if (prompt == nsnull)
return NS_ERROR_NOT_AVAILABLE;
@ -740,7 +722,7 @@ nsGeolocation::WatchPosition(nsIDOMGeoPositionCallback *aCallback,
nsIDOMGeoPositionOptions *aOptions,
PRUint16 *_retval NS_OUTPARAM)
{
nsIGeolocationPrompt* prompt = mService->GetPrompt();
nsCOMPtr<nsIGeolocationPrompt> prompt = do_GetService(NS_GEOLOCATION_PROMPT_CONTRACTID);
if (prompt == nsnull)
return NS_ERROR_NOT_AVAILABLE;

Просмотреть файл

@ -120,7 +120,7 @@ private:
/**
* Singleton that manages the geolocation provider
*/
class nsGeolocationService : public nsIGeolocationService, public nsIGeolocationUpdate, public nsIObserver
class nsGeolocationService : public nsIGeolocationUpdate, public nsIObserver
{
public:
@ -131,7 +131,6 @@ public:
NS_DECL_ISUPPORTS
NS_DECL_NSIGEOLOCATIONUPDATE
NS_DECL_NSIOBSERVER
NS_DECL_NSIGEOLOCATIONSERVICE
nsGeolocationService();
@ -142,9 +141,6 @@ public:
// Returns the last geolocation we have seen since calling StartDevice()
already_AddRefed<nsIDOMGeoPosition> GetLastKnownPosition();
// Returns the application defined UI prompt
nsIGeolocationPrompt* GetPrompt() { return mPrompt; } // does not addref.
// Returns true if the we have successfully found and started a
// geolocation device
PRBool IsDeviceReady();
@ -177,9 +173,6 @@ private:
// addes them to this list, and their destructor removes
// them from this list.
nsTArray<nsGeolocation*> mGeolocators;
// prompt callback, if any
nsCOMPtr<nsIGeolocationPrompt> mPrompt;
};

Просмотреть файл

@ -107,21 +107,46 @@ function delayed_prompt(request) {
setTimeout(geolocation_prompt, prompt_delay, request);
}
var TestPromptFactory = {
QueryInterface: function(iid) {
if (iid.equals(Components.interfaces.nsISupports) || iid.equals(Components.interfaces.nsIFactory))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
},
createInstance: function(outer, iid) {
if (outer)
throw Components.results.NS_ERROR_NO_AGGREGATION;
if(DELAYED_PROMPT)
return delayed_prompt;
else
return geolocation_prompt;
},
lockFactory: function(lock) {
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
},
};
function attachPrompt() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var geolocationService = Components.classes["@mozilla.org/geolocation/service;1"]
.getService(Components.interfaces.nsIGeolocationService);
old_prompt = geolocationService.prompt;
old_prompt = Components.manager.nsIComponentRegistrar.contractIDToCID("@mozilla.org/geolocation/prompt;1");
old_factory = Components.manager.getClassObjectByContractID("@mozilla.org/geolocation/prompt;1", Components.interfaces.nsIFactory)
if(DELAYED_PROMPT)
geolocationService.prompt = delayed_prompt;
else
geolocationService.prompt = geolocation_prompt;
const testing_prompt_cid = Components.ID("{20C27ECF-A22E-4022-9757-2CFDA88EAEAA}");
Components.manager.nsIComponentRegistrar.registerFactory(testing_prompt_cid,
"Test Geolocation Prompt",
"@mozilla.org/geolocation/prompt;1",
TestPromptFactory);
}
function removePrompt() {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
var geolocationService = Components.classes["@mozilla.org/geolocation/service;1"]
.getService(Components.interfaces.nsIGeolocationService);
geolocationService.prompt = old_prompt;
const testing_prompt_cid = Components.ID("{20C27ECF-A22E-4022-9757-2CFDA88EAEAA}");
Components.manager.nsIComponentRegistrar.unregisterFactory(testing_prompt_cid, TestPromptFactory);
Components.manager.nsIComponentRegistrar.registerFactory(old_prompt,
"Geolocation Prompt restored!",
"@mozilla.org/geolocation/prompt;1",
old_factory);
}