|
Packit |
f0b94e |
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
Packit |
f0b94e |
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
Packit |
f0b94e |
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "xpcAccessibilityService.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#include "nsAccessiblePivot.h"
|
|
Packit |
f0b94e |
#include "nsAccessibilityService.h"
|
|
Packit |
f0b94e |
#include "Platform.h"
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#ifdef A11Y_LOG
|
|
Packit |
f0b94e |
#include "Logging.h"
|
|
Packit |
f0b94e |
#endif
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
using namespace mozilla;
|
|
Packit |
f0b94e |
using namespace mozilla::a11y;
|
|
Packit |
f0b94e |
using namespace mozilla::dom;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
xpcAccessibilityService* xpcAccessibilityService::gXPCAccessibilityService =
|
|
Packit |
f0b94e |
nullptr;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
////////////////////////////////////////////////////////////////////////////////
|
|
Packit |
f0b94e |
// nsISupports
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
void xpcAccessibilityService::ShutdownCallback(nsITimer* aTimer,
|
|
Packit |
f0b94e |
void* aClosure) {
|
|
Packit |
f0b94e |
MaybeShutdownAccService(nsAccessibilityService::eXPCOM);
|
|
Packit |
f0b94e |
xpcAccessibilityService* xpcAccService =
|
|
Packit |
f0b94e |
reinterpret_cast<xpcAccessibilityService*>(aClosure);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (xpcAccService->mShutdownTimer) {
|
|
Packit |
f0b94e |
xpcAccService->mShutdownTimer->Cancel();
|
|
Packit |
f0b94e |
xpcAccService->mShutdownTimer = nullptr;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP_(MozExternalRefCountType)
|
|
Packit |
f0b94e |
xpcAccessibilityService::AddRef(void) {
|
|
Packit |
f0b94e |
MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(xpcAccessibilityService)
|
|
Packit |
f0b94e |
MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
|
|
Packit |
f0b94e |
if (!mRefCnt.isThreadSafe) NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
|
|
Packit |
f0b94e |
nsrefcnt count = ++mRefCnt;
|
|
Packit |
f0b94e |
NS_LOG_ADDREF(this, count, "xpcAccessibilityService", sizeof(*this));
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// We want refcount to be > 1 because one reference is added in the XPCOM
|
|
Packit |
f0b94e |
// accessibility service getter.
|
|
Packit |
f0b94e |
if (mRefCnt > 1) {
|
|
Packit |
f0b94e |
if (mShutdownTimer) {
|
|
Packit |
f0b94e |
mShutdownTimer->Cancel();
|
|
Packit |
f0b94e |
mShutdownTimer = nullptr;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
GetOrCreateAccService(nsAccessibilityService::eXPCOM);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return count;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP_(MozExternalRefCountType)
|
|
Packit |
f0b94e |
xpcAccessibilityService::Release(void) {
|
|
Packit |
f0b94e |
MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (!mRefCnt.isThreadSafe) {
|
|
Packit |
f0b94e |
NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsrefcnt count = --mRefCnt;
|
|
Packit |
f0b94e |
NS_LOG_RELEASE(this, count, "xpcAccessibilityService");
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (count == 0) {
|
|
Packit |
f0b94e |
if (!mRefCnt.isThreadSafe) {
|
|
Packit |
f0b94e |
NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
mRefCnt = 1; /* stabilize */
|
|
Packit |
f0b94e |
delete (this);
|
|
Packit |
f0b94e |
return 0;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// When ref count goes down to 1 (held internally as a static reference),
|
|
Packit |
f0b94e |
// it means that there are no more external references to the
|
|
Packit |
f0b94e |
// xpcAccessibilityService and we can attempt to shut down acceessiblity
|
|
Packit |
f0b94e |
// service.
|
|
Packit |
f0b94e |
if (count == 1 && !mShutdownTimer) {
|
|
Packit |
f0b94e |
NS_NewTimerWithFuncCallback(
|
|
Packit |
f0b94e |
getter_AddRefs(mShutdownTimer), ShutdownCallback, this, 100,
|
|
Packit |
f0b94e |
nsITimer::TYPE_ONE_SHOT, "xpcAccessibilityService::Release");
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return count;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMPL_QUERY_INTERFACE(xpcAccessibilityService, nsIAccessibilityService)
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::GetApplicationAccessible(
|
|
Packit |
f0b94e |
nsIAccessible** aAccessibleApplication) {
|
|
Packit |
f0b94e |
NS_ENSURE_ARG_POINTER(aAccessibleApplication);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IF_ADDREF(*aAccessibleApplication = XPCApplicationAcc());
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::GetAccessibleFor(nsIDOMNode* aNode,
|
|
Packit |
f0b94e |
nsIAccessible** aAccessible) {
|
|
Packit |
f0b94e |
NS_ENSURE_ARG_POINTER(aAccessible);
|
|
Packit |
f0b94e |
*aAccessible = nullptr;
|
|
Packit |
f0b94e |
if (!aNode) {
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
|
|
Packit |
f0b94e |
if (!node) {
|
|
Packit |
f0b94e |
return NS_ERROR_INVALID_ARG;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsAccessibilityService* accService = GetAccService();
|
|
Packit |
f0b94e |
if (!accService) {
|
|
Packit |
f0b94e |
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
DocAccessible* document = accService->GetDocAccessible(node->OwnerDoc());
|
|
Packit |
f0b94e |
if (document) {
|
|
Packit |
f0b94e |
NS_IF_ADDREF(*aAccessible = ToXPC(document->GetAccessible(node)));
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::GetStringRole(uint32_t aRole, nsAString& aString) {
|
|
Packit |
f0b94e |
nsAccessibilityService* accService = GetAccService();
|
|
Packit |
f0b94e |
if (!accService) {
|
|
Packit |
f0b94e |
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
accService->GetStringRole(aRole, aString);
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
|
|
Packit |
f0b94e |
nsISupports** aStringStates) {
|
|
Packit |
f0b94e |
nsAccessibilityService* accService = GetAccService();
|
|
Packit |
f0b94e |
if (!accService) {
|
|
Packit |
f0b94e |
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
accService->GetStringStates(aState, aExtraState, aStringStates);
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::GetStringEventType(uint32_t aEventType,
|
|
Packit |
f0b94e |
nsAString& aString) {
|
|
Packit |
f0b94e |
nsAccessibilityService* accService = GetAccService();
|
|
Packit |
f0b94e |
if (!accService) {
|
|
Packit |
f0b94e |
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
accService->GetStringEventType(aEventType, aString);
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::GetStringRelationType(uint32_t aRelationType,
|
|
Packit |
f0b94e |
nsAString& aString) {
|
|
Packit |
f0b94e |
nsAccessibilityService* accService = GetAccService();
|
|
Packit |
f0b94e |
if (!accService) {
|
|
Packit |
f0b94e |
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
accService->GetStringRelationType(aRelationType, aString);
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::GetAccessibleFromCache(nsIDOMNode* aNode,
|
|
Packit |
f0b94e |
nsIAccessible** aAccessible) {
|
|
Packit |
f0b94e |
NS_ENSURE_ARG_POINTER(aAccessible);
|
|
Packit |
f0b94e |
*aAccessible = nullptr;
|
|
Packit |
f0b94e |
if (!aNode) {
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsCOMPtr<nsINode> node(do_QueryInterface(aNode));
|
|
Packit |
f0b94e |
if (!node) {
|
|
Packit |
f0b94e |
return NS_ERROR_INVALID_ARG;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsAccessibilityService* accService = GetAccService();
|
|
Packit |
f0b94e |
if (!accService) {
|
|
Packit |
f0b94e |
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
// Search for an accessible in each of our per document accessible object
|
|
Packit |
f0b94e |
// caches. If we don't find it, and the given node is itself a document, check
|
|
Packit |
f0b94e |
// our cache of document accessibles (document cache). Note usually shutdown
|
|
Packit |
f0b94e |
// document accessibles are not stored in the document cache, however an
|
|
Packit |
f0b94e |
// "unofficially" shutdown document (i.e. not from DocManager) can still
|
|
Packit |
f0b94e |
// exist in the document cache.
|
|
Packit |
f0b94e |
Accessible* accessible = accService->FindAccessibleInCache(node);
|
|
Packit |
f0b94e |
if (!accessible) {
|
|
Packit |
f0b94e |
nsCOMPtr<nsIDocument> document(do_QueryInterface(node));
|
|
Packit |
f0b94e |
if (document) {
|
|
Packit |
f0b94e |
accessible = mozilla::a11y::GetExistingDocAccessible(document);
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IF_ADDREF(*aAccessible = ToXPC(accessible));
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
|
|
Packit |
f0b94e |
nsIAccessiblePivot** aPivot) {
|
|
Packit |
f0b94e |
NS_ENSURE_ARG_POINTER(aPivot);
|
|
Packit |
f0b94e |
NS_ENSURE_ARG(aRoot);
|
|
Packit |
f0b94e |
*aPivot = nullptr;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
Accessible* accessibleRoot = aRoot->ToInternalAccessible();
|
|
Packit |
f0b94e |
NS_ENSURE_TRUE(accessibleRoot, NS_ERROR_INVALID_ARG);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsAccessiblePivot* pivot = new nsAccessiblePivot(accessibleRoot);
|
|
Packit |
f0b94e |
NS_ADDREF(*aPivot = pivot);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::SetLogging(const nsACString& aModules) {
|
|
Packit |
f0b94e |
#ifdef A11Y_LOG
|
|
Packit |
f0b94e |
logging::Enable(PromiseFlatCString(aModules));
|
|
Packit |
f0b94e |
#endif
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::IsLogged(const nsAString& aModule, bool* aIsLogged) {
|
|
Packit |
f0b94e |
NS_ENSURE_ARG_POINTER(aIsLogged);
|
|
Packit |
f0b94e |
*aIsLogged = false;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
#ifdef A11Y_LOG
|
|
Packit |
f0b94e |
*aIsLogged = logging::IsEnabled(aModule);
|
|
Packit |
f0b94e |
#endif
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
NS_IMETHODIMP
|
|
Packit |
f0b94e |
xpcAccessibilityService::GetConsumers(nsAString& aString) {
|
|
Packit |
f0b94e |
nsAccessibilityService* accService = GetAccService();
|
|
Packit |
f0b94e |
if (!accService) {
|
|
Packit |
f0b94e |
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
accService->GetConsumers(aString);
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
////////////////////////////////////////////////////////////////////////////////
|
|
Packit |
f0b94e |
// NS_GetAccessibilityService
|
|
Packit |
f0b94e |
////////////////////////////////////////////////////////////////////////////////
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult) {
|
|
Packit |
f0b94e |
NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
|
|
Packit |
f0b94e |
*aResult = nullptr;
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
if (!GetOrCreateAccService(nsAccessibilityService::eXPCOM)) {
|
|
Packit |
f0b94e |
return NS_ERROR_SERVICE_NOT_AVAILABLE;
|
|
Packit |
f0b94e |
}
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
xpcAccessibilityService* service = new xpcAccessibilityService();
|
|
Packit |
f0b94e |
NS_ENSURE_TRUE(service, NS_ERROR_OUT_OF_MEMORY);
|
|
Packit |
f0b94e |
xpcAccessibilityService::gXPCAccessibilityService = service;
|
|
Packit |
f0b94e |
NS_ADDREF(*aResult = service);
|
|
Packit |
f0b94e |
|
|
Packit |
f0b94e |
return NS_OK;
|
|
Packit |
f0b94e |
}
|