Bug 1787269 [wpt PR 35624] - Further refine STP download regexs, a=testonly
[gecko.git] / accessible / xpcom / xpcAccessibilityService.cpp
blob5a51945e07e371085328cf4d71d925c314e2b635
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"
11 #include "Platform.h"
12 #include "xpcAccessibleApplication.h"
13 #include "xpcAccessibleDocument.h"
15 #ifdef A11Y_LOG
16 # include "Logging.h"
17 #endif
19 using namespace mozilla;
20 using namespace mozilla::a11y;
21 using namespace mozilla::dom;
23 xpcAccessibilityService* xpcAccessibilityService::gXPCAccessibilityService =
24 nullptr;
26 ////////////////////////////////////////////////////////////////////////////////
27 // nsISupports
29 void xpcAccessibilityService::ShutdownCallback(nsITimer* aTimer,
30 void* aClosure) {
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.
53 if (mRefCnt > 1) {
54 if (mShutdownTimer) {
55 mShutdownTimer->Cancel();
56 mShutdownTimer = nullptr;
59 GetOrCreateAccService(nsAccessibilityService::eXPCOM);
62 return count;
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");
76 if (count == 0) {
77 if (!nsAutoRefCnt::isThreadSafe) {
78 NS_ASSERT_OWNINGTHREAD(xpcAccessibilityService);
81 mRefCnt = 1; /* stabilize */
82 delete (this);
83 return 0;
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
89 // service.
90 if (count == 1 && !mShutdownTimer) {
91 NS_NewTimerWithFuncCallback(
92 getter_AddRefs(mShutdownTimer), ShutdownCallback, this, 100,
93 nsITimer::TYPE_ONE_SHOT, "xpcAccessibilityService::Release");
96 return count;
99 NS_IMPL_QUERY_INTERFACE(xpcAccessibilityService, nsIAccessibilityService)
101 NS_IMETHODIMP
102 xpcAccessibilityService::GetApplicationAccessible(
103 nsIAccessible** aAccessibleApplication) {
104 NS_ENSURE_ARG_POINTER(aAccessibleApplication);
106 NS_IF_ADDREF(*aAccessibleApplication = XPCApplicationAcc());
107 return NS_OK;
110 NS_IMETHODIMP
111 xpcAccessibilityService::GetAccessibleFor(nsINode* aNode,
112 nsIAccessible** aAccessible) {
113 NS_ENSURE_ARG_POINTER(aAccessible);
114 *aAccessible = nullptr;
115 if (!aNode) {
116 return NS_OK;
119 nsAccessibilityService* accService = GetAccService();
120 if (!accService) {
121 return NS_ERROR_SERVICE_NOT_AVAILABLE;
124 DocAccessible* document = accService->GetDocAccessible(aNode->OwnerDoc());
125 if (document) {
126 NS_IF_ADDREF(*aAccessible = ToXPC(document->GetAccessible(aNode)));
129 return NS_OK;
132 NS_IMETHODIMP
133 xpcAccessibilityService::GetAccessibleDescendantFor(
134 nsINode* aNode, nsIAccessible** aAccessible) {
135 NS_ENSURE_ARG_POINTER(aAccessible);
136 *aAccessible = nullptr;
137 if (!aNode) {
138 return NS_OK;
141 nsAccessibilityService* accService = GetAccService();
142 if (!accService) {
143 return NS_ERROR_SERVICE_NOT_AVAILABLE;
146 DocAccessible* document = accService->GetDocAccessible(aNode->OwnerDoc());
147 if (document) {
148 NS_IF_ADDREF(*aAccessible =
149 ToXPC(document->GetAccessibleOrDescendant(aNode)));
152 return NS_OK;
155 NS_IMETHODIMP
156 xpcAccessibilityService::GetStringRole(uint32_t aRole, nsAString& aString) {
157 nsAccessibilityService* accService = GetAccService();
158 if (!accService) {
159 return NS_ERROR_SERVICE_NOT_AVAILABLE;
162 accService->GetStringRole(aRole, aString);
163 return NS_OK;
166 NS_IMETHODIMP
167 xpcAccessibilityService::GetStringStates(uint32_t aState, uint32_t aExtraState,
168 nsISupports** aStringStates) {
169 nsAccessibilityService* accService = GetAccService();
170 if (!accService) {
171 return NS_ERROR_SERVICE_NOT_AVAILABLE;
174 accService->GetStringStates(aState, aExtraState, aStringStates);
175 return NS_OK;
178 NS_IMETHODIMP
179 xpcAccessibilityService::GetStringEventType(uint32_t aEventType,
180 nsAString& aString) {
181 nsAccessibilityService* accService = GetAccService();
182 if (!accService) {
183 return NS_ERROR_SERVICE_NOT_AVAILABLE;
186 accService->GetStringEventType(aEventType, aString);
187 return NS_OK;
190 NS_IMETHODIMP
191 xpcAccessibilityService::GetStringRelationType(uint32_t aRelationType,
192 nsAString& aString) {
193 nsAccessibilityService* accService = GetAccService();
194 if (!accService) {
195 return NS_ERROR_SERVICE_NOT_AVAILABLE;
198 accService->GetStringRelationType(aRelationType, aString);
199 return NS_OK;
202 NS_IMETHODIMP
203 xpcAccessibilityService::GetAccessibleFromCache(nsINode* aNode,
204 nsIAccessible** aAccessible) {
205 NS_ENSURE_ARG_POINTER(aAccessible);
206 *aAccessible = nullptr;
207 if (!aNode) {
208 return NS_OK;
211 nsAccessibilityService* accService = GetAccService();
212 if (!accService) {
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));
228 return NS_OK;
231 NS_IMETHODIMP
232 xpcAccessibilityService::CreateAccessiblePivot(nsIAccessible* aRoot,
233 nsIAccessiblePivot** aPivot) {
234 NS_ENSURE_ARG_POINTER(aPivot);
235 NS_ENSURE_ARG(aRoot);
236 *aPivot = nullptr;
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);
244 return NS_OK;
247 NS_IMETHODIMP
248 xpcAccessibilityService::SetLogging(const nsACString& aModules) {
249 #ifdef A11Y_LOG
250 logging::Enable(PromiseFlatCString(aModules));
251 #endif
252 return NS_OK;
255 NS_IMETHODIMP
256 xpcAccessibilityService::IsLogged(const nsAString& aModule, bool* aIsLogged) {
257 NS_ENSURE_ARG_POINTER(aIsLogged);
258 *aIsLogged = false;
260 #ifdef A11Y_LOG
261 *aIsLogged = logging::IsEnabled(aModule);
262 #endif
264 return NS_OK;
267 NS_IMETHODIMP
268 xpcAccessibilityService::GetConsumers(nsAString& aString) {
269 nsAccessibilityService* accService = GetAccService();
270 if (!accService) {
271 return NS_ERROR_SERVICE_NOT_AVAILABLE;
274 accService->GetConsumers(aString);
275 return NS_OK;
278 ////////////////////////////////////////////////////////////////////////////////
279 // NS_GetAccessibilityService
280 ////////////////////////////////////////////////////////////////////////////////
282 nsresult NS_GetAccessibilityService(nsIAccessibilityService** aResult) {
283 NS_ENSURE_TRUE(aResult, NS_ERROR_NULL_POINTER);
284 *aResult = nullptr;
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);
294 return NS_OK;