1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 #include "xpcAccessibilityService.h"
7 #include "mozilla/dom/Document.h"
9 #include "nsAccessiblePivot.h"
10 #include "nsAccessibilityService.h"
12 #include "xpcAccessibleApplication.h"
13 #include "xpcAccessibleDocument.h"
19 using namespace mozilla
;
20 using namespace mozilla::a11y
;
21 using namespace mozilla::dom
;
23 xpcAccessibilityService
* xpcAccessibilityService::gXPCAccessibilityService
=
26 ////////////////////////////////////////////////////////////////////////////////
29 void xpcAccessibilityService::ShutdownCallback(nsITimer
* aTimer
,
31 MaybeShutdownAccService(nsAccessibilityService::eXPCOM
);
32 xpcAccessibilityService
* xpcAccService
=
33 reinterpret_cast<xpcAccessibilityService
*>(aClosure
);
35 if (xpcAccService
->mShutdownTimer
) {
36 xpcAccService
->mShutdownTimer
->Cancel();
37 xpcAccService
->mShutdownTimer
= nullptr;
41 NS_IMETHODIMP_(MozExternalRefCountType
)
42 xpcAccessibilityService::AddRef(void) {
43 MOZ_ASSERT_TYPE_OK_FOR_REFCOUNTING(xpcAccessibilityService
)
44 MOZ_ASSERT(int32_t(mRefCnt
) >= 0, "illegal refcnt");
45 if (!nsAutoRefCnt::isThreadSafe
) {
46 NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService
);
48 nsrefcnt count
= ++mRefCnt
;
49 NS_LOG_ADDREF(this, count
, "xpcAccessibilityService", sizeof(*this));
51 // We want refcount to be > 1 because one reference is added in the XPCOM
52 // accessibility service getter.
55 mShutdownTimer
->Cancel();
56 mShutdownTimer
= nullptr;
59 GetOrCreateAccService(nsAccessibilityService::eXPCOM
);
65 NS_IMETHODIMP_(MozExternalRefCountType
)
66 xpcAccessibilityService::Release(void) {
67 MOZ_ASSERT(int32_t(mRefCnt
) > 0, "dup release");
69 if (!nsAutoRefCnt::isThreadSafe
) {
70 NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService
);
73 nsrefcnt count
= --mRefCnt
;
74 NS_LOG_RELEASE(this, count
, "xpcAccessibilityService");
77 if (!nsAutoRefCnt::isThreadSafe
) {
78 NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService
);
81 mRefCnt
= 1; /* stabilize */
86 // When ref count goes down to 1 (held internally as a static reference),
87 // it means that there are no more external references to the
88 // xpcAccessibilityService and we can attempt to shut down acceessiblity
90 if (count
== 1 && !mShutdownTimer
) {
91 NS_NewTimerWithFuncCallback(
92 getter_AddRefs(mShutdownTimer
), ShutdownCallback
, this, 100,
93 nsITimer::TYPE_ONE_SHOT
, "xpcAccessibilityService::Release");
99 NS_IMPL_QUERY_INTERFACE(xpcAccessibilityService
, nsIAccessibilityService
)
102 xpcAccessibilityService::GetApplicationAccessible(
103 nsIAccessible
** aAccessibleApplication
) {
104 NS_ENSURE_ARG_POINTER(aAccessibleApplication
);
106 NS_IF_ADDREF(*aAccessibleApplication
= XPCApplicationAcc());
111 xpcAccessibilityService::GetAccessibleFor(nsINode
* aNode
,
112 nsIAccessible
** aAccessible
) {
113 NS_ENSURE_ARG_POINTER(aAccessible
);
114 *aAccessible
= nullptr;
119 nsAccessibilityService
* accService
= GetAccService();
121 return NS_ERROR_SERVICE_NOT_AVAILABLE
;
124 DocAccessible
* document
= accService
->GetDocAccessible(aNode
->OwnerDoc());
126 NS_IF_ADDREF(*aAccessible
= ToXPC(document
->GetAccessible(aNode
)));
133 xpcAccessibilityService::GetAccessibleDescendantFor(
134 nsINode
* aNode
, nsIAccessible
** aAccessible
) {
135 NS_ENSURE_ARG_POINTER(aAccessible
);
136 *aAccessible
= nullptr;
141 nsAccessibilityService
* accService
= GetAccService();
143 return NS_ERROR_SERVICE_NOT_AVAILABLE
;
146 DocAccessible
* document
= accService
->GetDocAccessible(aNode
->OwnerDoc());
148 NS_IF_ADDREF(*aAccessible
=
149 ToXPC(document
->GetAccessibleOrDescendant(aNode
)));
156 xpcAccessibilityService::GetStringRole(uint32_t aRole
, nsAString
& aString
) {
157 nsAccessibilityService
* accService
= GetAccService();
159 return NS_ERROR_SERVICE_NOT_AVAILABLE
;
162 accService
->GetStringRole(aRole
, aString
);
167 xpcAccessibilityService::GetStringStates(uint32_t aState
, uint32_t aExtraState
,
168 nsISupports
** aStringStates
) {
169 nsAccessibilityService
* accService
= GetAccService();
171 return NS_ERROR_SERVICE_NOT_AVAILABLE
;
174 accService
->GetStringStates(aState
, aExtraState
, aStringStates
);
179 xpcAccessibilityService::GetStringEventType(uint32_t aEventType
,
180 nsAString
& aString
) {
181 nsAccessibilityService
* accService
= GetAccService();
183 return NS_ERROR_SERVICE_NOT_AVAILABLE
;
186 accService
->GetStringEventType(aEventType
, aString
);
191 xpcAccessibilityService::GetStringRelationType(uint32_t aRelationType
,
192 nsAString
& aString
) {
193 nsAccessibilityService
* accService
= GetAccService();
195 return NS_ERROR_SERVICE_NOT_AVAILABLE
;
198 accService
->GetStringRelationType(aRelationType
, aString
);
203 xpcAccessibilityService::GetAccessibleFromCache(nsINode
* aNode
,
204 nsIAccessible
** aAccessible
) {
205 NS_ENSURE_ARG_POINTER(aAccessible
);
206 *aAccessible
= nullptr;
211 nsAccessibilityService
* accService
= GetAccService();
213 return NS_ERROR_SERVICE_NOT_AVAILABLE
;
216 // Search for an accessible in each of our per document accessible object
217 // caches. If we don't find it, and the given node is itself a document, check
218 // our cache of document accessibles (document cache). Note usually shutdown
219 // document accessibles are not stored in the document cache, however an
220 // "unofficially" shutdown document (i.e. not from DocManager) can still
221 // exist in the document cache.
222 LocalAccessible
* accessible
= accService
->FindAccessibleInCache(aNode
);
223 if (!accessible
&& aNode
->IsDocument()) {
224 accessible
= mozilla::a11y::GetExistingDocAccessible(aNode
->AsDocument());
227 NS_IF_ADDREF(*aAccessible
= ToXPC(accessible
));
232 xpcAccessibilityService::CreateAccessiblePivot(nsIAccessible
* aRoot
,
233 nsIAccessiblePivot
** aPivot
) {
234 NS_ENSURE_ARG_POINTER(aPivot
);
235 NS_ENSURE_ARG(aRoot
);
238 LocalAccessible
* accessibleRoot
= aRoot
->ToInternalAccessible();
239 NS_ENSURE_TRUE(accessibleRoot
, NS_ERROR_INVALID_ARG
);
241 nsAccessiblePivot
* pivot
= new nsAccessiblePivot(accessibleRoot
);
242 NS_ADDREF(*aPivot
= pivot
);
248 xpcAccessibilityService::SetLogging(const nsACString
& aModules
) {
250 logging::Enable(PromiseFlatCString(aModules
));
256 xpcAccessibilityService::IsLogged(const nsAString
& aModule
, bool* aIsLogged
) {
257 NS_ENSURE_ARG_POINTER(aIsLogged
);
261 *aIsLogged
= logging::IsEnabled(aModule
);
268 xpcAccessibilityService::GetConsumers(nsAString
& aString
) {
269 nsAccessibilityService
* accService
= GetAccService();
271 return NS_ERROR_SERVICE_NOT_AVAILABLE
;
274 accService
->GetConsumers(aString
);
278 ////////////////////////////////////////////////////////////////////////////////
279 // NS_GetAccessibilityService
280 ////////////////////////////////////////////////////////////////////////////////
282 nsresult
NS_GetAccessibilityService(nsIAccessibilityService
** aResult
) {
283 NS_ENSURE_TRUE(aResult
, NS_ERROR_NULL_POINTER
);
286 if (!GetOrCreateAccService(nsAccessibilityService::eXPCOM
)) {
287 return NS_ERROR_SERVICE_NOT_AVAILABLE
;
290 xpcAccessibilityService
* service
= new xpcAccessibilityService();
291 xpcAccessibilityService::gXPCAccessibilityService
= service
;
292 NS_ADDREF(*aResult
= service
);