Bug 1268544: Integrate remote COM objects into a11y code; r?tbsaunde
MozReview-Commit-ID: ctPgegQ83a
--- a/accessible/base/DocManager.cpp
+++ b/accessible/base/DocManager.cpp
@@ -501,16 +501,21 @@ DocManager::CreateDocOrRootAccessible(ns
// XXX We may need to handle the case that we don't have a tab child
// differently. It may be that this will cause us to fail to notify
// the parent process about important accessible documents.
if (tabChild) {
DocAccessibleChild* ipcDoc = new DocAccessibleChild(docAcc);
docAcc->SetIPCDoc(ipcDoc);
static_cast<TabChild*>(tabChild.get())->
SendPDocAccessibleConstructor(ipcDoc, nullptr, 0);
+
+#if defined(XP_WIN)
+ IAccessibleHolder holder(CreateHolderFromAccessible(docAcc));
+ ipcDoc->SendCOMProxy(holder);
+#endif
}
}
}
} else {
parentDocAcc->BindChildDocument(docAcc);
}
#ifdef A11Y_LOG
--- a/accessible/base/NotificationController.cpp
+++ b/accessible/base/NotificationController.cpp
@@ -423,16 +423,20 @@ NotificationController::WillRefresh(mozi
ipcDoc = new DocAccessibleChild(childDoc);
childDoc->SetIPCDoc(ipcDoc);
nsCOMPtr<nsITabChild> tabChild =
do_GetInterface(mDocument->DocumentNode()->GetDocShell());
if (tabChild) {
static_cast<TabChild*>(tabChild.get())->
SendPDocAccessibleConstructor(ipcDoc, parentIPCDoc, id);
+#if defined(XP_WIN)
+ IAccessibleHolder holder(CreateHolderFromAccessible(childDoc));
+ ipcDoc->SendCOMProxy(holder);
+#endif
}
}
}
mObservingState = eRefreshObserving;
if (!mDocument)
return;
--- a/accessible/base/Platform.h
+++ b/accessible/base/Platform.h
@@ -1,14 +1,17 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+#ifndef mozilla_a11y_Platform_h
+#define mozilla_a11y_Platform_h
+
#include <stdint.h>
class nsString;
namespace mozilla {
namespace a11y {
class ProxyAccessible;
@@ -77,8 +80,9 @@ void ProxyTextChangeEvent(ProxyAccessibl
bool aFromUser);
void ProxyShowHideEvent(ProxyAccessible* aTarget, ProxyAccessible* aParent,
bool aInsert, bool aFromUser);
void ProxySelectionEvent(ProxyAccessible* aTarget, ProxyAccessible* aWidget,
uint32_t aType);
} // namespace a11y
} // namespace mozilla
+#endif // mozilla_a11y_Platform_h
--- a/accessible/base/moz.build
+++ b/accessible/base/moz.build
@@ -58,16 +58,28 @@ if CONFIG['A11Y_LOG']:
UNIFIED_SOURCES += [
'Logging.cpp',
]
LOCAL_INCLUDES += [
'/accessible/generic',
'/accessible/html',
'/accessible/ipc',
+]
+
+if CONFIG['OS_ARCH'] == 'WINNT':
+ LOCAL_INCLUDES += [
+ '/accessible/ipc/win',
+ ]
+else:
+ LOCAL_INCLUDES += [
+ '/accessible/ipc/other',
+ ]
+
+LOCAL_INCLUDES += [
'/accessible/xpcom',
'/accessible/xul',
'/dom/base',
'/dom/xbl',
'/ipc/chromium/src',
'/layout/generic',
'/layout/style',
'/layout/svg',
--- a/accessible/ipc/win/DocAccessibleChild.cpp
+++ b/accessible/ipc/win/DocAccessibleChild.cpp
@@ -2,24 +2,32 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DocAccessibleChild.h"
#include "Accessible-inl.h"
+#include "mozilla/a11y/PlatformChild.h"
+#include "mozilla/ClearOnShutdown.h"
namespace mozilla {
namespace a11y {
+static StaticAutoPtr<PlatformChild> sPlatformChild;
+
DocAccessibleChild::DocAccessibleChild(DocAccessible* aDoc)
: DocAccessibleChildBase(aDoc)
{
MOZ_COUNT_CTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase);
+ if (!sPlatformChild) {
+ sPlatformChild = new PlatformChild();
+ ClearOnShutdown(&sPlatformChild, ShutdownPhase::ShutdownThreads);
+ }
}
DocAccessibleChild::~DocAccessibleChild()
{
MOZ_COUNT_DTOR_INHERITED(DocAccessibleChild, DocAccessibleChildBase);
}
void
new file mode 100644
--- /dev/null
+++ b/accessible/ipc/win/PlatformChild.cpp
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "mozilla/a11y/PlatformChild.h"
+#include "mozilla/mscom/EnsureMTA.h"
+#include "mozilla/mscom/InterceptorLog.h"
+
+#include "Accessible2.h"
+
+namespace mozilla {
+namespace a11y {
+
+/**
+ * Unfortunately the COM interceptor does not intrinsically handle array
+ * outparams. Instead we manually define the relevant metadata here, and
+ * register it in a call to mozilla::mscom::RegisterArrayData.
+ * @see mozilla::mscom::ArrayData
+ */
+static const mozilla::mscom::ArrayData sPlatformChildArrayData[] = {
+ {IID_IEnumVARIANT, 3, 1, VT_DISPATCH, IID_IDispatch, 2},
+ {IID_IAccessible2, 30, 1, VT_UNKNOWN | VT_BYREF, IID_IAccessibleRelation, 2},
+ {IID_IAccessibleRelation, 7, 1, VT_UNKNOWN | VT_BYREF, IID_IUnknown, 2}
+};
+
+// Type libraries are thread-neutral, so we can register those from any
+// apartment. OTOH, proxies must be registered from within the apartment where
+// we intend to instantiate them. Therefore RegisterProxy() must be called
+// via EnsureMTA.
+PlatformChild::PlatformChild()
+ : mAccTypelib(mozilla::mscom::RegisterTypelib(L"oleacc.dll",
+ mozilla::mscom::RegistrationFlags::eUseSystemDirectory))
+ , mMiscTypelib(mozilla::mscom::RegisterTypelib(L"Accessible.tlb"))
+{
+ mozilla::mscom::InterceptorLog::Init();
+ mozilla::mscom::RegisterArrayData(sPlatformChildArrayData);
+
+ UniquePtr<mozilla::mscom::RegisteredProxy> ia2Proxy;
+ mozilla::mscom::EnsureMTA([&ia2Proxy]() -> void {
+ ia2Proxy = Move(mozilla::mscom::RegisterProxy(L"ia2marshal.dll"));
+ });
+ mIA2Proxy = Move(ia2Proxy);
+}
+
+} // namespace a11y
+} // namespace mozilla
+
new file mode 100644
--- /dev/null
+++ b/accessible/ipc/win/PlatformChild.h
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=2 et sw=2 tw=80: */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef mozilla_a11y_PlatformChild_h
+#define mozilla_a11y_PlatformChild_h
+
+#include "mozilla/mscom/Registration.h"
+
+namespace mozilla {
+namespace a11y {
+
+class PlatformChild
+{
+public:
+ PlatformChild();
+
+ PlatformChild(PlatformChild&) = delete;
+ PlatformChild(PlatformChild&&) = delete;
+ PlatformChild& operator=(PlatformChild&) = delete;
+ PlatformChild& operator=(PlatformChild&&) = delete;
+
+private:
+ UniquePtr<mozilla::mscom::RegisteredProxy> mIA2Proxy;
+ UniquePtr<mozilla::mscom::RegisteredProxy> mAccTypelib;
+ UniquePtr<mozilla::mscom::RegisteredProxy> mMiscTypelib;
+};
+
+} // namespace mozilla
+} // namespace a11y
+
+#endif // mozilla_a11y_PlatformChild_h
+
--- a/accessible/ipc/win/moz.build
+++ b/accessible/ipc/win/moz.build
@@ -7,22 +7,24 @@
IPDL_SOURCES += ['PDocAccessible.ipdl']
# with --disable-accessibility we need to compile PDocAccessible.ipdl, but not
# the C++.
if CONFIG['ACCESSIBILITY']:
EXPORTS.mozilla.a11y += [
'COMPtrTypes.h',
'DocAccessibleChild.h',
+ 'PlatformChild.h',
'ProxyAccessible.h'
]
SOURCES += [
'COMPtrTypes.cpp',
'DocAccessibleChild.cpp',
+ 'PlatformChild.cpp',
'ProxyAccessible.cpp',
]
LOCAL_INCLUDES += [
'/accessible/base',
'/accessible/generic',
'/accessible/windows/ia2',
'/accessible/windows/msaa',
--- a/accessible/windows/msaa/DocAccessibleWrap.cpp
+++ b/accessible/windows/msaa/DocAccessibleWrap.cpp
@@ -2,16 +2,17 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "DocAccessibleWrap.h"
#include "Compatibility.h"
+#include "DocAccessibleChild.h"
#include "nsWinUtils.h"
#include "mozilla/dom/TabChild.h"
#include "Role.h"
#include "RootAccessible.h"
#include "sdnDocAccessible.h"
#include "Statistics.h"
#include "nsIDocShell.h"
@@ -39,16 +40,40 @@ IMPL_IUNKNOWN_QUERY_HEAD(DocAccessibleWr
statistics::ISimpleDOMUsed();
*aInstancePtr = static_cast<ISimpleDOMDocument*>(new sdnDocAccessible(this));
static_cast<IUnknown*>(*aInstancePtr)->AddRef();
return S_OK;
}
IMPL_IUNKNOWN_QUERY_TAIL_INHERITED(HyperTextAccessibleWrap)
STDMETHODIMP
+DocAccessibleWrap::get_accParent(
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
+{
+ if (!Parent()) {
+ *ppdispParent = nullptr;
+ return S_FALSE;
+ }
+
+ if (!IPCDoc()) {
+ return DocAccessible::get_accParent(ppdispParent);
+ }
+
+ IAccessible* dispParent = IPCDoc()->GetParentIAccessible();
+ MOZ_ASSERT(dispParent);
+ if (!dispParent) {
+ return E_UNEXPECTED;
+ }
+
+ dispParent->AddRef();
+ *ppdispParent = static_cast<IDispatch*>(dispParent);
+ return S_OK;
+}
+
+STDMETHODIMP
DocAccessibleWrap::get_accValue(VARIANT aVarChild, BSTR __RPC_FAR* aValue)
{
A11Y_TRYBLOCK_BEGIN
if (!aValue)
return E_INVALIDARG;
*aValue = nullptr;
--- a/accessible/windows/msaa/DocAccessibleWrap.h
+++ b/accessible/windows/msaa/DocAccessibleWrap.h
@@ -17,20 +17,24 @@ class DocAccessibleWrap : public DocAcce
public:
DocAccessibleWrap(nsIDocument* aDocument, nsIPresShell* aPresShell);
virtual ~DocAccessibleWrap();
DECL_IUNKNOWN_INHERITED
// IAccessible
- // Override get_accValue to provide URL when no other value is available
- virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accValue(
- /* [optional][in] */ VARIANT varChild,
- /* [retval][out] */ BSTR __RPC_FAR *pszValue);
+ // Override get_accParent for e10s
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent(
+ /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispParent) override;
+
+ // Override get_accValue to provide URL when no other value is available
+ virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accValue(
+ /* [optional][in] */ VARIANT varChild,
+ /* [retval][out] */ BSTR __RPC_FAR *pszValue) override;
// Accessible
virtual void Shutdown();
// DocAccessible
virtual void* GetNativeWindow() const;
/**
--- a/accessible/windows/msaa/Platform.cpp
+++ b/accessible/windows/msaa/Platform.cpp
@@ -5,38 +5,63 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "Platform.h"
#include "AccEvent.h"
#include "Compatibility.h"
#include "HyperTextAccessibleWrap.h"
#include "ia2AccessibleText.h"
+#include "nsIXULRuntime.h"
#include "nsWinUtils.h"
#include "mozilla/a11y/ProxyAccessible.h"
+#include "mozilla/mscom/InterceptorLog.h"
+#include "mozilla/mscom/Registration.h"
+#include "mozilla/StaticPtr.h"
#include "ProxyWrappers.h"
using namespace mozilla;
using namespace mozilla::a11y;
+using namespace mozilla::mscom;
+
+static StaticAutoPtr<RegisteredProxy> gRegProxy;
+static StaticAutoPtr<RegisteredProxy> gRegAccTlb;
+static StaticAutoPtr<RegisteredProxy> gRegMiscTlb;
void
a11y::PlatformInit()
{
Compatibility::Init();
nsWinUtils::MaybeStartWindowEmulation();
ia2AccessibleText::InitTextChangeData();
+ if (BrowserTabsRemoteAutostart()) {
+ mscom::InterceptorLog::Init();
+ UniquePtr<RegisteredProxy> regProxy(
+ mscom::RegisterProxy(L"ia2marshal.dll"));
+ gRegProxy = regProxy.release();
+ UniquePtr<RegisteredProxy> regAccTlb(
+ mscom::RegisterTypelib(L"oleacc.dll",
+ RegistrationFlags::eUseSystemDirectory));
+ gRegAccTlb = regAccTlb.release();
+ UniquePtr<RegisteredProxy> regMiscTlb(
+ mscom::RegisterTypelib(L"Accessible.tlb"));
+ gRegMiscTlb = regMiscTlb.release();
+ }
}
void
a11y::PlatformShutdown()
{
::DestroyCaret();
nsWinUtils::ShutdownWindowEmulation();
+ gRegProxy = nullptr;
+ gRegAccTlb = nullptr;
+ gRegMiscTlb = nullptr;
}
void
a11y::ProxyCreated(ProxyAccessible* aProxy, uint32_t aInterfaces)
{
AccessibleWrap* wrapper = nullptr;
if (aInterfaces & Interfaces::DOCUMENT) {
wrapper = new DocProxyAccessibleWrap(aProxy);