|
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
2 /* vim:expandtab:shiftwidth=4:tabstop=4: |
|
3 */ |
|
4 /* This Source Code Form is subject to the terms of the Mozilla Public |
|
5 * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
7 |
|
8 #include "ApplicationAccessible.h" |
|
9 |
|
10 #include "nsAccessibilityService.h" |
|
11 #include "nsAccUtils.h" |
|
12 #include "Relation.h" |
|
13 #include "Role.h" |
|
14 #include "States.h" |
|
15 |
|
16 #include "nsIComponentManager.h" |
|
17 #include "nsIDOMDocument.h" |
|
18 #include "nsIDOMWindow.h" |
|
19 #include "nsIWindowMediator.h" |
|
20 #include "nsServiceManagerUtils.h" |
|
21 #include "mozilla/Services.h" |
|
22 #include "nsIStringBundle.h" |
|
23 |
|
24 using namespace mozilla::a11y; |
|
25 |
|
26 ApplicationAccessible::ApplicationAccessible() : |
|
27 AccessibleWrap(nullptr, nullptr) |
|
28 { |
|
29 mType = eApplicationType; |
|
30 mAppInfo = do_GetService("@mozilla.org/xre/app-info;1"); |
|
31 } |
|
32 |
|
33 //////////////////////////////////////////////////////////////////////////////// |
|
34 // nsISupports |
|
35 |
|
36 NS_IMPL_ISUPPORTS_INHERITED(ApplicationAccessible, Accessible, |
|
37 nsIAccessibleApplication) |
|
38 |
|
39 //////////////////////////////////////////////////////////////////////////////// |
|
40 // nsIAccessible |
|
41 |
|
42 NS_IMETHODIMP |
|
43 ApplicationAccessible::GetParent(nsIAccessible** aAccessible) |
|
44 { |
|
45 NS_ENSURE_ARG_POINTER(aAccessible); |
|
46 *aAccessible = nullptr; |
|
47 return NS_OK; |
|
48 } |
|
49 |
|
50 NS_IMETHODIMP |
|
51 ApplicationAccessible::GetNextSibling(nsIAccessible** aNextSibling) |
|
52 { |
|
53 NS_ENSURE_ARG_POINTER(aNextSibling); |
|
54 *aNextSibling = nullptr; |
|
55 return NS_OK; |
|
56 } |
|
57 |
|
58 NS_IMETHODIMP |
|
59 ApplicationAccessible::GetPreviousSibling(nsIAccessible** aPreviousSibling) |
|
60 { |
|
61 NS_ENSURE_ARG_POINTER(aPreviousSibling); |
|
62 *aPreviousSibling = nullptr; |
|
63 return NS_OK; |
|
64 } |
|
65 |
|
66 ENameValueFlag |
|
67 ApplicationAccessible::Name(nsString& aName) |
|
68 { |
|
69 aName.Truncate(); |
|
70 |
|
71 nsCOMPtr<nsIStringBundleService> bundleService = |
|
72 mozilla::services::GetStringBundleService(); |
|
73 |
|
74 NS_ASSERTION(bundleService, "String bundle service must be present!"); |
|
75 if (!bundleService) |
|
76 return eNameOK; |
|
77 |
|
78 nsCOMPtr<nsIStringBundle> bundle; |
|
79 nsresult rv = bundleService->CreateBundle("chrome://branding/locale/brand.properties", |
|
80 getter_AddRefs(bundle)); |
|
81 if (NS_FAILED(rv)) |
|
82 return eNameOK; |
|
83 |
|
84 nsXPIDLString appName; |
|
85 rv = bundle->GetStringFromName(MOZ_UTF16("brandShortName"), |
|
86 getter_Copies(appName)); |
|
87 if (NS_FAILED(rv) || appName.IsEmpty()) { |
|
88 NS_WARNING("brandShortName not found, using default app name"); |
|
89 appName.AssignLiteral("Gecko based application"); |
|
90 } |
|
91 |
|
92 aName.Assign(appName); |
|
93 return eNameOK; |
|
94 } |
|
95 |
|
96 void |
|
97 ApplicationAccessible::Description(nsString& aDescription) |
|
98 { |
|
99 aDescription.Truncate(); |
|
100 } |
|
101 |
|
102 void |
|
103 ApplicationAccessible::Value(nsString& aValue) |
|
104 { |
|
105 aValue.Truncate(); |
|
106 } |
|
107 |
|
108 uint64_t |
|
109 ApplicationAccessible::State() |
|
110 { |
|
111 return IsDefunct() ? states::DEFUNCT : 0; |
|
112 } |
|
113 |
|
114 already_AddRefed<nsIPersistentProperties> |
|
115 ApplicationAccessible::NativeAttributes() |
|
116 { |
|
117 return nullptr; |
|
118 } |
|
119 |
|
120 GroupPos |
|
121 ApplicationAccessible::GroupPosition() |
|
122 { |
|
123 return GroupPos(); |
|
124 } |
|
125 |
|
126 Accessible* |
|
127 ApplicationAccessible::ChildAtPoint(int32_t aX, int32_t aY, |
|
128 EWhichChildAtPoint aWhichChild) |
|
129 { |
|
130 return nullptr; |
|
131 } |
|
132 |
|
133 Accessible* |
|
134 ApplicationAccessible::FocusedChild() |
|
135 { |
|
136 Accessible* focus = FocusMgr()->FocusedAccessible(); |
|
137 if (focus && focus->Parent() == this) |
|
138 return focus; |
|
139 |
|
140 return nullptr; |
|
141 } |
|
142 |
|
143 Relation |
|
144 ApplicationAccessible::RelationByType(RelationType aRelationType) |
|
145 { |
|
146 return Relation(); |
|
147 } |
|
148 |
|
149 NS_IMETHODIMP |
|
150 ApplicationAccessible::GetBounds(int32_t* aX, int32_t* aY, |
|
151 int32_t* aWidth, int32_t* aHeight) |
|
152 { |
|
153 NS_ENSURE_ARG_POINTER(aX); |
|
154 *aX = 0; |
|
155 NS_ENSURE_ARG_POINTER(aY); |
|
156 *aY = 0; |
|
157 NS_ENSURE_ARG_POINTER(aWidth); |
|
158 *aWidth = 0; |
|
159 NS_ENSURE_ARG_POINTER(aHeight); |
|
160 *aHeight = 0; |
|
161 return NS_OK; |
|
162 } |
|
163 |
|
164 NS_IMETHODIMP |
|
165 ApplicationAccessible::SetSelected(bool aIsSelected) |
|
166 { |
|
167 return NS_OK; |
|
168 } |
|
169 |
|
170 NS_IMETHODIMP |
|
171 ApplicationAccessible::TakeSelection() |
|
172 { |
|
173 return NS_OK; |
|
174 } |
|
175 |
|
176 NS_IMETHODIMP |
|
177 ApplicationAccessible::TakeFocus() |
|
178 { |
|
179 return NS_OK; |
|
180 } |
|
181 |
|
182 uint8_t |
|
183 ApplicationAccessible::ActionCount() |
|
184 { |
|
185 return 0; |
|
186 } |
|
187 |
|
188 NS_IMETHODIMP |
|
189 ApplicationAccessible::GetActionName(uint8_t aIndex, nsAString& aName) |
|
190 { |
|
191 aName.Truncate(); |
|
192 return NS_ERROR_INVALID_ARG; |
|
193 } |
|
194 |
|
195 NS_IMETHODIMP |
|
196 ApplicationAccessible::GetActionDescription(uint8_t aIndex, |
|
197 nsAString& aDescription) |
|
198 { |
|
199 aDescription.Truncate(); |
|
200 return NS_ERROR_INVALID_ARG; |
|
201 } |
|
202 |
|
203 NS_IMETHODIMP |
|
204 ApplicationAccessible::DoAction(uint8_t aIndex) |
|
205 { |
|
206 return NS_OK; |
|
207 } |
|
208 |
|
209 //////////////////////////////////////////////////////////////////////////////// |
|
210 // nsIAccessibleApplication |
|
211 |
|
212 NS_IMETHODIMP |
|
213 ApplicationAccessible::GetAppName(nsAString& aName) |
|
214 { |
|
215 aName.Truncate(); |
|
216 |
|
217 if (!mAppInfo) |
|
218 return NS_ERROR_FAILURE; |
|
219 |
|
220 nsAutoCString cname; |
|
221 nsresult rv = mAppInfo->GetName(cname); |
|
222 NS_ENSURE_SUCCESS(rv, rv); |
|
223 |
|
224 AppendUTF8toUTF16(cname, aName); |
|
225 return NS_OK; |
|
226 } |
|
227 |
|
228 NS_IMETHODIMP |
|
229 ApplicationAccessible::GetAppVersion(nsAString& aVersion) |
|
230 { |
|
231 aVersion.Truncate(); |
|
232 |
|
233 if (!mAppInfo) |
|
234 return NS_ERROR_FAILURE; |
|
235 |
|
236 nsAutoCString cversion; |
|
237 nsresult rv = mAppInfo->GetVersion(cversion); |
|
238 NS_ENSURE_SUCCESS(rv, rv); |
|
239 |
|
240 AppendUTF8toUTF16(cversion, aVersion); |
|
241 return NS_OK; |
|
242 } |
|
243 |
|
244 NS_IMETHODIMP |
|
245 ApplicationAccessible::GetPlatformName(nsAString& aName) |
|
246 { |
|
247 aName.AssignLiteral("Gecko"); |
|
248 return NS_OK; |
|
249 } |
|
250 |
|
251 NS_IMETHODIMP |
|
252 ApplicationAccessible::GetPlatformVersion(nsAString& aVersion) |
|
253 { |
|
254 aVersion.Truncate(); |
|
255 |
|
256 if (!mAppInfo) |
|
257 return NS_ERROR_FAILURE; |
|
258 |
|
259 nsAutoCString cversion; |
|
260 nsresult rv = mAppInfo->GetPlatformVersion(cversion); |
|
261 NS_ENSURE_SUCCESS(rv, rv); |
|
262 |
|
263 AppendUTF8toUTF16(cversion, aVersion); |
|
264 return NS_OK; |
|
265 } |
|
266 |
|
267 //////////////////////////////////////////////////////////////////////////////// |
|
268 // Accessible public methods |
|
269 |
|
270 void |
|
271 ApplicationAccessible::Shutdown() |
|
272 { |
|
273 mAppInfo = nullptr; |
|
274 } |
|
275 |
|
276 void |
|
277 ApplicationAccessible::ApplyARIAState(uint64_t* aState) const |
|
278 { |
|
279 } |
|
280 |
|
281 role |
|
282 ApplicationAccessible::NativeRole() |
|
283 { |
|
284 return roles::APP_ROOT; |
|
285 } |
|
286 |
|
287 uint64_t |
|
288 ApplicationAccessible::NativeState() |
|
289 { |
|
290 return 0; |
|
291 } |
|
292 |
|
293 void |
|
294 ApplicationAccessible::InvalidateChildren() |
|
295 { |
|
296 // Do nothing because application children are kept updated by AppendChild() |
|
297 // and RemoveChild() method calls. |
|
298 } |
|
299 |
|
300 KeyBinding |
|
301 ApplicationAccessible::AccessKey() const |
|
302 { |
|
303 return KeyBinding(); |
|
304 } |
|
305 |
|
306 //////////////////////////////////////////////////////////////////////////////// |
|
307 // Accessible protected methods |
|
308 |
|
309 void |
|
310 ApplicationAccessible::CacheChildren() |
|
311 { |
|
312 // CacheChildren is called only once for application accessible when its |
|
313 // children are requested because empty InvalidateChldren() prevents its |
|
314 // repeated calls. |
|
315 |
|
316 // Basically children are kept updated by Append/RemoveChild method calls. |
|
317 // However if there are open windows before accessibility was started |
|
318 // then we need to make sure root accessibles for open windows are created so |
|
319 // that all root accessibles are stored in application accessible children |
|
320 // array. |
|
321 |
|
322 nsCOMPtr<nsIWindowMediator> windowMediator = |
|
323 do_GetService(NS_WINDOWMEDIATOR_CONTRACTID); |
|
324 |
|
325 nsCOMPtr<nsISimpleEnumerator> windowEnumerator; |
|
326 nsresult rv = windowMediator->GetEnumerator(nullptr, |
|
327 getter_AddRefs(windowEnumerator)); |
|
328 if (NS_FAILED(rv)) |
|
329 return; |
|
330 |
|
331 bool hasMore = false; |
|
332 windowEnumerator->HasMoreElements(&hasMore); |
|
333 while (hasMore) { |
|
334 nsCOMPtr<nsISupports> window; |
|
335 windowEnumerator->GetNext(getter_AddRefs(window)); |
|
336 nsCOMPtr<nsIDOMWindow> DOMWindow = do_QueryInterface(window); |
|
337 if (DOMWindow) { |
|
338 nsCOMPtr<nsIDOMDocument> DOMDocument; |
|
339 DOMWindow->GetDocument(getter_AddRefs(DOMDocument)); |
|
340 if (DOMDocument) { |
|
341 nsCOMPtr<nsIDocument> docNode(do_QueryInterface(DOMDocument)); |
|
342 GetAccService()->GetDocAccessible(docNode); // ensure creation |
|
343 } |
|
344 } |
|
345 windowEnumerator->HasMoreElements(&hasMore); |
|
346 } |
|
347 } |
|
348 |
|
349 Accessible* |
|
350 ApplicationAccessible::GetSiblingAtOffset(int32_t aOffset, |
|
351 nsresult* aError) const |
|
352 { |
|
353 if (aError) |
|
354 *aError = NS_OK; // fail peacefully |
|
355 |
|
356 return nullptr; |
|
357 } |
|
358 |
|
359 //////////////////////////////////////////////////////////////////////////////// |
|
360 // nsIAccessible |
|
361 |
|
362 NS_IMETHODIMP |
|
363 ApplicationAccessible::GetRootDocument(nsIAccessibleDocument** aRootDocument) |
|
364 { |
|
365 NS_ENSURE_ARG_POINTER(aRootDocument); |
|
366 *aRootDocument = nullptr; |
|
367 return NS_OK; |
|
368 } |
|
369 |
|
370 NS_IMETHODIMP |
|
371 ApplicationAccessible::ScrollTo(uint32_t aScrollType) |
|
372 { |
|
373 return NS_OK; |
|
374 } |
|
375 |
|
376 NS_IMETHODIMP |
|
377 ApplicationAccessible::ScrollToPoint(uint32_t aCoordinateType, |
|
378 int32_t aX, int32_t aY) |
|
379 { |
|
380 return NS_OK; |
|
381 } |
|
382 |
|
383 NS_IMETHODIMP |
|
384 ApplicationAccessible::GetLanguage(nsAString& aLanguage) |
|
385 { |
|
386 aLanguage.Truncate(); |
|
387 return NS_OK; |
|
388 } |
|
389 |