Bug 1319640: Make obtaining of plugin IAccessible go through Chrome process on Sandboxed builds; r=tbsaunde
MozReview-Commit-ID: DQnOwJ1VpYS
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -481,12 +481,43 @@ DocAccessibleParent::RecvCOMProxy(const
IAccessible* rawNative = nullptr;
if (outerDoc) {
outerDoc->GetNativeInterface((void**) &rawNative);
}
aParentCOMProxy->Set(IAccessibleHolder::COMPtrType(rawNative));
return IPC_OK();
}
+
+mozilla::ipc::IPCResult
+DocAccessibleParent::RecvGetWindowedPluginIAccessible(
+ const WindowsHandle& aHwnd, IAccessibleHolder* aPluginCOMProxy)
+{
+#if defined(MOZ_CONTENT_SANDBOX)
+ // We don't actually want the accessible object for aHwnd, but rather the
+ // one that belongs to its child (see HTMLWin32ObjectAccessible).
+ HWND childWnd = ::GetWindow(reinterpret_cast<HWND>(aHwnd), GW_CHILD);
+ if (!childWnd) {
+ return IPC_FAIL(this, "GetWindow failed");
+ }
+
+ IAccessible* rawAccPlugin = nullptr;
+ HRESULT hr = ::AccessibleObjectFromWindow(childWnd, OBJID_WINDOW,
+ IID_IAccessible,
+ (void**)&rawAccPlugin);
+ if (FAILED(hr)) {
+ // This might happen if the plugin doesn't handle WM_GETOBJECT properly.
+ // We should not consider that a failure.
+ return IPC_OK();
+ }
+
+ aPluginCOMProxy->Set(IAccessibleHolder::COMPtrType(rawAccPlugin));
+
+ return IPC_OK();
+#else
+ return IPC_FAIL(this, "Message unsupported in this build configuration");
+#endif
+}
+
#endif // defined(XP_WIN)
} // a11y
} // mozilla
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -141,16 +141,19 @@ public:
size_t ChildDocCount() const { return mChildDocs.Length(); }
const DocAccessibleParent* ChildDocAt(size_t aIdx) const
{ return mChildDocs[aIdx]; }
#if defined(XP_WIN)
virtual mozilla::ipc::IPCResult RecvCOMProxy(const IAccessibleHolder& aCOMProxy,
IAccessibleHolder* aParentCOMProxy) override;
+
+ virtual mozilla::ipc::IPCResult RecvGetWindowedPluginIAccessible(
+ const WindowsHandle& aHwnd, IAccessibleHolder* aPluginCOMProxy) override;
#endif
private:
class ProxyEntry : public PLDHashEntryHdr
{
public:
explicit ProxyEntry(const void*) : mProxy(nullptr) {}
--- a/accessible/ipc/win/PDocAccessible.ipdl
+++ b/accessible/ipc/win/PDocAccessible.ipdl
@@ -3,16 +3,17 @@
/* 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 protocol PFileDescriptorSet;
include protocol PBrowser;
using mozilla::a11y::IAccessibleHolder from "mozilla/a11y/COMPtrTypes.h";
+using mozilla::WindowsHandle from "ipc/IPCMessageUtils.h";
namespace mozilla {
namespace a11y {
struct AccessibleData
{
uint64_t ID;
int32_t MsaaID;
@@ -56,16 +57,19 @@ parent:
async RoleChangedEvent(uint32_t aRole);
/*
* Tell the parent document to bind the existing document as a new child
* document.
*/
async BindChildDoc(PDocAccessible aChildDoc, uint64_t aID);
+ sync GetWindowedPluginIAccessible(WindowsHandle aHwnd)
+ returns (IAccessibleHolder aPluginCOMProxy);
+
// For now we'll add the command to send the proxy here. This might move to
// PDocAccessible constructor in PBrowser.
sync COMProxy(IAccessibleHolder aDocCOMProxy)
returns(IAccessibleHolder aParentCOMProxy);
child:
async __delete__();
};
--- a/accessible/windows/msaa/HTMLWin32ObjectAccessible.cpp
+++ b/accessible/windows/msaa/HTMLWin32ObjectAccessible.cpp
@@ -57,29 +57,56 @@ HTMLWin32ObjectOwnerAccessible::Natively
////////////////////////////////////////////////////////////////////////////////
HTMLWin32ObjectAccessible::HTMLWin32ObjectAccessible(void* aHwnd,
DocAccessible* aDoc) :
DummyAccessible(aDoc)
{
mHwnd = aHwnd;
if (mHwnd) {
+#if defined(MOZ_CONTENT_SANDBOX)
+ if (XRE_IsContentProcess()) {
+ DocAccessibleChild* ipcDoc = aDoc->IPCDoc();
+ MOZ_ASSERT(ipcDoc);
+ if (!ipcDoc) {
+ return;
+ }
+
+ IAccessibleHolder proxyHolder;
+ if (!ipcDoc->SendGetWindowedPluginIAccessible(
+ reinterpret_cast<uintptr_t>(mHwnd), &proxyHolder)) {
+ return;
+ }
+
+ mCOMProxy.reset(proxyHolder.Release());
+ return;
+ }
+#endif
+
// The plugin is not windowless. In this situation we use
// use its inner child owned by the plugin so that we don't get
// in an infinite loop, where the WM_GETOBJECT's get forwarded
// back to us and create another HTMLWin32ObjectAccessible
HWND childWnd = ::GetWindow((HWND)aHwnd, GW_CHILD);
if (childWnd) {
mHwnd = childWnd;
}
}
}
void
HTMLWin32ObjectAccessible::GetNativeInterface(void** aNativeAccessible)
{
+#if defined(MOZ_CONTENT_SANDBOX)
+ if (XRE_IsContentProcess()) {
+ RefPtr<IAccessible> addRefed = mCOMProxy.get();
+ addRefed.forget(aNativeAccessible);
+ return;
+ }
+#endif
+
if (mHwnd) {
::AccessibleObjectFromWindow(static_cast<HWND>(mHwnd),
OBJID_WINDOW, IID_IAccessible,
aNativeAccessible);
}
}
--- a/accessible/windows/msaa/HTMLWin32ObjectAccessible.h
+++ b/accessible/windows/msaa/HTMLWin32ObjectAccessible.h
@@ -3,16 +3,20 @@
* 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_HTMLWin32ObjectAccessible_h_
#define mozilla_a11y_HTMLWin32ObjectAccessible_h_
#include "BaseAccessibles.h"
+#if defined(MOZ_CONTENT_SANDBOX)
+#include "mozilla/mscom/Ptr.h"
+#endif
+
struct IAccessible;
namespace mozilla {
namespace a11y {
class HTMLWin32ObjectOwnerAccessible : public AccessibleWrap
{
public:
@@ -50,14 +54,17 @@ class HTMLWin32ObjectAccessible : public
public:
HTMLWin32ObjectAccessible(void* aHwnd, DocAccessible* aDoc);
virtual ~HTMLWin32ObjectAccessible() {}
virtual void GetNativeInterface(void** aNativeAccessible) override;
protected:
void* mHwnd;
+#if defined(MOZ_CONTENT_SANDBOX)
+ mscom::ProxyUniquePtr<IAccessible> mCOMProxy;
+#endif
};
} // namespace a11y
} // namespace mozilla
#endif