Bug 1769547 - Do not MOZ_CRASH() on missing process r=nika
[gecko.git] / accessible / windows / msaa / ServiceProvider.cpp
blobbeb24f6da8f88a819d4e86e3640cb7438f0253e2
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "ServiceProvider.h"
9 #include "AccessibleApplication_i.c"
10 #include "ApplicationAccessibleWrap.h"
11 #include "DocAccessible.h"
12 #include "nsAccUtils.h"
13 #include "nsCoreUtils.h"
14 #include "Relation.h"
15 #include "RootAccessible.h"
16 #include "uiaRawElmProvider.h"
18 #include "mozilla/a11y/DocAccessibleChild.h"
19 #include "mozilla/Preferences.h"
21 #include "ISimpleDOM.h"
23 namespace mozilla {
24 namespace a11y {
26 IMPL_IUNKNOWN_QUERY_HEAD(ServiceProvider)
27 IMPL_IUNKNOWN_QUERY_IFACE(IServiceProvider)
28 IMPL_IUNKNOWN_QUERY_TAIL_AGGREGATED(mMsaa)
30 ////////////////////////////////////////////////////////////////////////////////
31 // IServiceProvider
33 STDMETHODIMP
34 ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID,
35 void** aInstancePtr) {
36 if (!aInstancePtr) return E_INVALIDARG;
38 *aInstancePtr = nullptr;
39 Accessible* acc = mMsaa->Acc();
40 if (!acc) {
41 return CO_E_OBJNOTCONNECTED;
43 AccessibleWrap* localAcc = mMsaa->LocalAcc();
45 // UIA IAccessibleEx
46 if (aGuidService == IID_IAccessibleEx &&
47 Preferences::GetBool("accessibility.uia.enable") && localAcc) {
48 uiaRawElmProvider* accEx = new uiaRawElmProvider(localAcc);
49 HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
50 if (FAILED(hr)) delete accEx;
52 return hr;
55 // Provide a special service ID for getting the accessible for the browser tab
56 // document that contains this accessible object. If this accessible object
57 // is not inside a browser tab then the service fails with E_NOINTERFACE.
58 // A use case for this is for screen readers that need to switch context or
59 // 'virtual buffer' when focus moves from one browser tab area to another.
60 static const GUID SID_IAccessibleContentDocument = {
61 0xa5d8e1f3,
62 0x3571,
63 0x4d8f,
64 {0x95, 0x21, 0x07, 0xed, 0x28, 0xfb, 0x07, 0x2e}};
65 if (aGuidService == SID_IAccessibleContentDocument && localAcc) {
66 if (aIID != IID_IAccessible) return E_NOINTERFACE;
68 // If acc is within an OOP iframe document, the top level document
69 // lives in a different process.
70 if (XRE_IsContentProcess()) {
71 RootAccessible* root = localAcc->RootAccessible();
72 // root will be null if acc is the ApplicationAccessible.
73 if (root) {
74 DocAccessibleChild* ipcDoc = root->IPCDoc();
75 if (ipcDoc) {
76 RefPtr<IAccessible> topDoc = ipcDoc->GetTopLevelDocIAccessible();
77 // topDoc will be null if this isn't an OOP iframe document.
78 if (topDoc) {
79 topDoc.forget(aInstancePtr);
80 return S_OK;
86 Relation rel = localAcc->RelationByType(RelationType::CONTAINING_TAB_PANE);
87 AccessibleWrap* tabDoc = static_cast<AccessibleWrap*>(rel.Next());
88 if (!tabDoc) return E_NOINTERFACE;
90 RefPtr<IAccessible> result;
91 tabDoc->GetNativeInterface(getter_AddRefs(result));
92 result.forget(aInstancePtr);
93 return S_OK;
96 // Can get to IAccessibleApplication from any node via QS
97 // Note: in case of JAWS we want to check if aIID is
98 // IID_IAccessibleApplication.
99 if (aGuidService == IID_IAccessibleApplication ||
100 aIID == IID_IAccessibleApplication) {
101 ApplicationAccessibleWrap* applicationAcc =
102 static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
103 if (!applicationAcc) return E_NOINTERFACE;
105 RefPtr<IAccessible> appIa;
106 applicationAcc->GetNativeInterface(getter_AddRefs(appIa));
107 return appIa->QueryInterface(aIID, aInstancePtr);
110 static const GUID IID_SimpleDOMDeprecated = {
111 0x0c539790,
112 0x12e4,
113 0x11cf,
114 {0xb6, 0x61, 0x00, 0xaa, 0x00, 0x4c, 0xd6, 0xd8}};
115 if (aGuidService == IID_ISimpleDOMNode ||
116 aGuidService == IID_SimpleDOMDeprecated ||
117 aGuidService == IID_IAccessible || aGuidService == IID_IAccessible2)
118 return mMsaa->QueryInterface(aIID, aInstancePtr);
120 return E_INVALIDARG;
123 } // namespace a11y
124 } // namespace mozilla