mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-14 13:55:43 +00:00
Bug 468659 - Crash [@ nsAccessNode::GetDocAccessibleFor(nsIDocShellTreeItem*, int) ], r=ginn.chen
This commit is contained in:
parent
a4528f2763
commit
deb5725f5b
@ -40,7 +40,7 @@
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsHashtable.h"
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsIAccessibleDocument.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
@ -82,27 +82,19 @@ nsIStringBundle *nsAccessNode::gStringBundle = 0;
|
||||
nsIStringBundle *nsAccessNode::gKeyStringBundle = 0;
|
||||
nsITimer *nsAccessNode::gDoCommandTimer = 0;
|
||||
nsIDOMNode *nsAccessNode::gLastFocusedNode = 0;
|
||||
#ifdef DEBUG
|
||||
PRBool nsAccessNode::gIsAccessibilityActive = PR_FALSE;
|
||||
PRBool nsAccessNode::gIsShuttingDownApp = PR_FALSE;
|
||||
#endif
|
||||
PRBool nsAccessNode::gIsCacheDisabled = PR_FALSE;
|
||||
PRBool nsAccessNode::gIsFormFillEnabled = PR_FALSE;
|
||||
nsAccessNodeHashtable nsAccessNode::gGlobalDocAccessibleCache;
|
||||
|
||||
nsApplicationAccessibleWrap *nsAccessNode::gApplicationAccessible = nsnull;
|
||||
|
||||
nsIAccessibilityService *nsAccessNode::sAccService = nsnull;
|
||||
nsIAccessibilityService *nsAccessNode::GetAccService()
|
||||
nsIAccessibilityService*
|
||||
nsAccessNode::GetAccService()
|
||||
{
|
||||
if (!gIsAccessibilityActive)
|
||||
return nsnull;
|
||||
|
||||
if (!sAccService) {
|
||||
nsresult rv = CallGetService("@mozilla.org/accessibilityService;1",
|
||||
&sAccService);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "No accessibility service");
|
||||
}
|
||||
|
||||
return sAccService;
|
||||
return nsAccessibilityService::GetAccessibilityService();
|
||||
}
|
||||
|
||||
/*
|
||||
@ -245,9 +237,7 @@ NS_IMETHODIMP nsAccessNode::GetOwnerWindow(void **aWindow)
|
||||
already_AddRefed<nsApplicationAccessibleWrap>
|
||||
nsAccessNode::GetApplicationAccessible()
|
||||
{
|
||||
if (!gIsAccessibilityActive) {
|
||||
return nsnull;
|
||||
}
|
||||
NS_ASSERTION(gIsAccessibilityActive, "Accessibility wasn't initialized!");
|
||||
|
||||
if (!gApplicationAccessible) {
|
||||
nsApplicationAccessibleWrap::PreCreate();
|
||||
@ -273,9 +263,8 @@ nsAccessNode::GetApplicationAccessible()
|
||||
|
||||
void nsAccessNode::InitXPAccessibility()
|
||||
{
|
||||
if (gIsAccessibilityActive) {
|
||||
return;
|
||||
}
|
||||
NS_ASSERTION(!gIsAccessibilityActive,
|
||||
"Accessibility was initialized already!");
|
||||
|
||||
nsCOMPtr<nsIStringBundleService> stringBundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID);
|
||||
@ -297,11 +286,13 @@ void nsAccessNode::InitXPAccessibility()
|
||||
prefBranch->GetBoolPref("browser.formfill.enable", &gIsFormFillEnabled);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
gIsAccessibilityActive = PR_TRUE;
|
||||
NotifyA11yInitOrShutdown();
|
||||
#endif
|
||||
NotifyA11yInitOrShutdown(PR_TRUE);
|
||||
}
|
||||
|
||||
void nsAccessNode::NotifyA11yInitOrShutdown()
|
||||
void nsAccessNode::NotifyA11yInitOrShutdown(PRBool aIsInit)
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> obsService =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
@ -310,7 +301,7 @@ void nsAccessNode::NotifyA11yInitOrShutdown()
|
||||
static const PRUnichar kInitIndicator[] = { '1', 0 };
|
||||
static const PRUnichar kShutdownIndicator[] = { '0', 0 };
|
||||
obsService->NotifyObservers(nsnull, "a11y-init-or-shutdown",
|
||||
gIsAccessibilityActive ? kInitIndicator : kShutdownIndicator);
|
||||
aIsInit ? kInitIndicator : kShutdownIndicator);
|
||||
}
|
||||
}
|
||||
|
||||
@ -320,16 +311,12 @@ void nsAccessNode::ShutdownXPAccessibility()
|
||||
// which happens when xpcom is shutting down
|
||||
// at exit of program
|
||||
|
||||
if (!gIsAccessibilityActive) {
|
||||
return;
|
||||
}
|
||||
gIsShuttingDownApp = PR_TRUE;
|
||||
NS_ASSERTION(gIsAccessibilityActive, "Accessibility was shutdown already!");
|
||||
|
||||
NS_IF_RELEASE(gStringBundle);
|
||||
NS_IF_RELEASE(gKeyStringBundle);
|
||||
NS_IF_RELEASE(gDoCommandTimer);
|
||||
NS_IF_RELEASE(gLastFocusedNode);
|
||||
NS_IF_RELEASE(sAccService);
|
||||
|
||||
nsApplicationAccessibleWrap::Unload();
|
||||
ClearCache(gGlobalDocAccessibleCache);
|
||||
@ -339,8 +326,10 @@ void nsAccessNode::ShutdownXPAccessibility()
|
||||
NS_IF_RELEASE(gApplicationAccessible);
|
||||
gApplicationAccessible = nsnull;
|
||||
|
||||
#ifdef DEBUG
|
||||
gIsAccessibilityActive = PR_FALSE;
|
||||
NotifyA11yInitOrShutdown();
|
||||
#endif
|
||||
NotifyA11yInitOrShutdown(PR_FALSE);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -174,21 +174,21 @@ protected:
|
||||
/**
|
||||
* Notify global nsIObserver's that a11y is getting init'd or shutdown
|
||||
*/
|
||||
static void NotifyA11yInitOrShutdown();
|
||||
static void NotifyA11yInitOrShutdown(PRBool aIsInit);
|
||||
|
||||
// Static data, we do our own refcounting for our static data
|
||||
static nsIStringBundle *gStringBundle;
|
||||
static nsIStringBundle *gKeyStringBundle;
|
||||
static nsITimer *gDoCommandTimer;
|
||||
#ifdef DEBUG
|
||||
static PRBool gIsAccessibilityActive;
|
||||
static PRBool gIsShuttingDownApp;
|
||||
#endif
|
||||
static PRBool gIsCacheDisabled;
|
||||
static PRBool gIsFormFillEnabled;
|
||||
|
||||
static nsAccessNodeHashtable gGlobalDocAccessibleCache;
|
||||
|
||||
private:
|
||||
static nsIAccessibilityService *sAccService;
|
||||
static nsApplicationAccessibleWrap *gApplicationAccessible;
|
||||
};
|
||||
|
||||
|
@ -113,6 +113,7 @@
|
||||
#endif
|
||||
|
||||
nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nsnull;
|
||||
PRBool nsAccessibilityService::gIsShutdown = PR_TRUE;
|
||||
|
||||
/**
|
||||
* nsAccessibilityService
|
||||
@ -120,6 +121,7 @@ nsAccessibilityService *nsAccessibilityService::gAccessibilityService = nsnull;
|
||||
|
||||
nsAccessibilityService::nsAccessibilityService()
|
||||
{
|
||||
// Add observers.
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
if (!observerService)
|
||||
@ -132,13 +134,15 @@ nsAccessibilityService::nsAccessibilityService()
|
||||
nsIWebProgress::NOTIFY_STATE_DOCUMENT |
|
||||
nsIWebProgress::NOTIFY_LOCATION);
|
||||
}
|
||||
|
||||
// Initialize accessibility.
|
||||
nsAccessNodeWrap::InitAccessibility();
|
||||
}
|
||||
|
||||
nsAccessibilityService::~nsAccessibilityService()
|
||||
{
|
||||
nsAccessibilityService::gAccessibilityService = nsnull;
|
||||
nsAccessNodeWrap::ShutdownAccessibility();
|
||||
NS_ASSERTION(gIsShutdown, "Accessibility wasn't shutdown!");
|
||||
gAccessibilityService = nsnull;
|
||||
}
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS5(nsAccessibilityService, nsIAccessibilityService, nsIAccessibleRetrieval,
|
||||
@ -151,6 +155,8 @@ nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
const PRUnichar *aData)
|
||||
{
|
||||
if (!nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID)) {
|
||||
|
||||
// Remove observers.
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
if (observerService) {
|
||||
@ -159,8 +165,8 @@ nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
nsCOMPtr<nsIWebProgress> progress(do_GetService(NS_DOCUMENTLOADER_SERVICE_CONTRACTID));
|
||||
if (progress)
|
||||
progress->RemoveProgressListener(static_cast<nsIWebProgressListener*>(this));
|
||||
nsAccessNodeWrap::ShutdownAccessibility();
|
||||
// Cancel and release load timers
|
||||
|
||||
// Cancel and release load timers.
|
||||
while (mLoadTimers.Count() > 0 ) {
|
||||
nsCOMPtr<nsITimer> timer = mLoadTimers.ObjectAt(0);
|
||||
void *closure = nsnull;
|
||||
@ -172,7 +178,18 @@ nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
|
||||
timer->Cancel();
|
||||
mLoadTimers.RemoveObjectAt(0);
|
||||
}
|
||||
|
||||
// Application is going to be closed, shutdown accessibility and mark
|
||||
// accessibility service as shutdown to prevent calls of its methods.
|
||||
// Don't null accessibility service static member at this point to be safe
|
||||
// if someone will try to operate with it.
|
||||
|
||||
NS_ASSERTION(!gIsShutdown, "Accessibility was shutdown already");
|
||||
|
||||
gIsShutdown = PR_TRUE;
|
||||
nsAccessNodeWrap::ShutdownAccessibility();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -182,7 +199,8 @@ NS_IMETHODIMP nsAccessibilityService::OnStateChange(nsIWebProgress *aWebProgress
|
||||
{
|
||||
NS_ASSERTION(aStateFlags & STATE_IS_DOCUMENT, "Other notifications excluded");
|
||||
|
||||
if (!aWebProgress || 0 == (aStateFlags & (STATE_START | STATE_STOP))) {
|
||||
if (gIsShutdown || !aWebProgress ||
|
||||
(aStateFlags & (STATE_START | STATE_STOP)) == 0) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -260,23 +278,26 @@ nsAccessibilityService::FireAccessibleEvent(PRUint32 aEvent,
|
||||
|
||||
void nsAccessibilityService::StartLoadCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsIAccessibilityService *accService = nsAccessNode::GetAccService();
|
||||
if (accService)
|
||||
accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START);
|
||||
if (gAccessibilityService)
|
||||
gAccessibilityService->
|
||||
ProcessDocLoadEvent(aTimer, aClosure,
|
||||
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_START);
|
||||
}
|
||||
|
||||
void nsAccessibilityService::EndLoadCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsIAccessibilityService *accService = nsAccessNode::GetAccService();
|
||||
if (accService)
|
||||
accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
|
||||
if (gAccessibilityService)
|
||||
gAccessibilityService->
|
||||
ProcessDocLoadEvent(aTimer, aClosure,
|
||||
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_COMPLETE);
|
||||
}
|
||||
|
||||
void nsAccessibilityService::FailedLoadCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
nsIAccessibilityService *accService = nsAccessNode::GetAccService();
|
||||
if (accService)
|
||||
accService->ProcessDocLoadEvent(aTimer, aClosure, nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
|
||||
if (gAccessibilityService)
|
||||
gAccessibilityService->
|
||||
ProcessDocLoadEvent(aTimer, aClosure,
|
||||
nsIAccessibleEvent::EVENT_DOCUMENT_LOAD_STOPPED);
|
||||
}
|
||||
|
||||
/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
|
||||
@ -1315,7 +1336,7 @@ NS_IMETHODIMP nsAccessibilityService::GetAccessible(nsIDOMNode *aNode,
|
||||
NS_ENSURE_ARG_POINTER(aAccessible);
|
||||
NS_ENSURE_ARG_POINTER(aFrameHint);
|
||||
*aAccessible = nsnull;
|
||||
if (!aPresShell || !aWeakShell) {
|
||||
if (!aPresShell || !aWeakShell || gIsShutdown) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
@ -2056,22 +2077,28 @@ NS_IMETHODIMP nsAccessibilityService::InvalidateSubtreeFor(nsIPresShell *aShell,
|
||||
nsresult
|
||||
nsAccessibilityService::GetAccessibilityService(nsIAccessibilityService** aResult)
|
||||
{
|
||||
NS_PRECONDITION(aResult != nsnull, "null ptr");
|
||||
if (! aResult)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
|
||||
*aResult = nsnull;
|
||||
if (!nsAccessibilityService::gAccessibilityService) {
|
||||
|
||||
if (!gAccessibilityService) {
|
||||
gAccessibilityService = new nsAccessibilityService();
|
||||
if (!gAccessibilityService ) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
NS_ENSURE_TRUE(gAccessibilityService, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
gIsShutdown = PR_FALSE;
|
||||
}
|
||||
*aResult = nsAccessibilityService::gAccessibilityService;
|
||||
NS_ADDREF(*aResult);
|
||||
|
||||
NS_ADDREF(*aResult = gAccessibilityService);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIAccessibilityService*
|
||||
nsAccessibilityService::GetAccessibilityService()
|
||||
{
|
||||
NS_ASSERTION(!gIsShutdown,
|
||||
"Going to deal with shutdown accessibility service!");
|
||||
return gAccessibilityService;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_GetAccessibilityService(nsIAccessibilityService** aResult)
|
||||
{
|
||||
|
@ -84,6 +84,16 @@ public:
|
||||
*/
|
||||
static nsresult GetAccessibilityService(nsIAccessibilityService** aResult);
|
||||
|
||||
/**
|
||||
* Return cached accessibility service.
|
||||
*/
|
||||
static nsIAccessibilityService* GetAccessibilityService();
|
||||
|
||||
/**
|
||||
* Indicates whether accessibility service was shutdown.
|
||||
*/
|
||||
static PRBool gIsShutdown;
|
||||
|
||||
private:
|
||||
/**
|
||||
* Return presentation shell, DOM node for the given frame.
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include "nsRootAccessible.h"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsAccessibleEventData.h"
|
||||
#include "nsIAccessibilityService.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsICommandManager.h"
|
||||
#include "nsIDocShell.h"
|
||||
@ -670,7 +670,7 @@ nsDocAccessible::Shutdown()
|
||||
// Remove from the cache after other parts of Shutdown(), so that Shutdown() procedures
|
||||
// can find the doc or root accessible in the cache if they need it.
|
||||
// We don't do this during ShutdownAccessibility() because that is already clearing the cache
|
||||
if (!gIsShuttingDownApp)
|
||||
if (!nsAccessibilityService::gIsShutdown)
|
||||
gGlobalDocAccessibleCache.Remove(static_cast<void*>(kungFuDeathGripDoc));
|
||||
|
||||
return NS_OK;
|
||||
|
@ -593,9 +593,8 @@ __try {
|
||||
|
||||
void nsAccessNodeWrap::InitAccessibility()
|
||||
{
|
||||
if (gIsAccessibilityActive) {
|
||||
return;
|
||||
}
|
||||
NS_ASSERTION(!gIsAccessibilityActive,
|
||||
"Accessibility was initialized already!");
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
if (prefBranch) {
|
||||
@ -623,9 +622,7 @@ void nsAccessNodeWrap::ShutdownAccessibility()
|
||||
NS_IF_RELEASE(gTextEvent);
|
||||
::DestroyCaret();
|
||||
|
||||
if (!gIsAccessibilityActive) {
|
||||
return;
|
||||
}
|
||||
NS_ASSERTION(gIsAccessibilityActive, "Accessibility was shutdown already!");
|
||||
|
||||
nsAccessNode::ShutdownXPAccessibility();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user