Bug 1319640: Make obtaining of plugin IAccessible go through Chrome process on Sandboxed builds; r=tbsaunde, a=jcristau
authorAaron Klotz <aklotz@mozilla.com>
Wed, 14 Dec 2016 15:18:34 -0700
changeset 352923 0644964811f1423a2c0958e141fa92ee41695279
parent 352922 08f5f2490cec7d4e4eaa175a1a03b7a6bb50a882
child 352924 00ced46aa9d09f6db2f9d9aa2483aaf9cf66e460
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstbsaunde, jcristau
bugs1319640
milestone52.0a2
Bug 1319640: Make obtaining of plugin IAccessible go through Chrome process on Sandboxed builds; r=tbsaunde, a=jcristau MozReview-Commit-ID: DQnOwJ1VpYS
accessible/ipc/DocAccessibleParent.cpp
accessible/ipc/DocAccessibleParent.h
accessible/ipc/win/PDocAccessible.ipdl
accessible/windows/msaa/HTMLWin32ObjectAccessible.cpp
accessible/windows/msaa/HTMLWin32ObjectAccessible.h
--- a/accessible/ipc/DocAccessibleParent.cpp
+++ b/accessible/ipc/DocAccessibleParent.cpp
@@ -476,12 +476,43 @@ DocAccessibleParent::RecvCOMProxy(const 
   IAccessible* rawNative = nullptr;
   if (outerDoc) {
     outerDoc->GetNativeInterface((void**) &rawNative);
   }
 
   aParentCOMProxy->Set(IAccessibleHolder::COMPtrType(rawNative));
   return true;
 }
+
+bool
+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 true;
+  }
+
+  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 true;
+  }
+
+  aPluginCOMProxy->Set(IAccessibleHolder::COMPtrType(rawAccPlugin));
+
+  return true;
+#else
+  return false;
+#endif
+}
+
 #endif // defined(XP_WIN)
 
 } // a11y
 } // mozilla
--- a/accessible/ipc/DocAccessibleParent.h
+++ b/accessible/ipc/DocAccessibleParent.h
@@ -140,16 +140,19 @@ public:
 
   size_t ChildDocCount() const { return mChildDocs.Length(); }
   const DocAccessibleParent* ChildDocAt(size_t aIdx) const
     { return mChildDocs[aIdx]; }
 
 #if defined(XP_WIN)
   virtual bool RecvCOMProxy(const IAccessibleHolder& aCOMProxy,
                             IAccessibleHolder* aParentCOMProxy) override;
+
+  virtual bool 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