bug 832158 - implement IServiceProvider with a taer off r=surkov
authorTrevor Saunders <trev.saunders@gmail.com>
Wed, 09 Jan 2013 15:01:10 -0500
changeset 122495 bb29fef8cd2e6b63069df07660a6ac973e03b959
parent 122494 851342f5eafe34a1c782c0821f204741f1223650
child 122496 c5c4c51585c30fc794d6e77f64c03a64ad62d3a9
push id24342
push userryanvm@gmail.com
push dateThu, 21 Feb 2013 13:05:06 +0000
treeherdermozilla-central@702d2814efbf [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssurkov
bugs832158
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 832158 - implement IServiceProvider with a taer off r=surkov
accessible/src/msaa/AccessibleWrap.cpp
accessible/src/msaa/AccessibleWrap.h
accessible/src/msaa/Makefile.in
accessible/src/msaa/ServiceProvider.cpp
accessible/src/msaa/ServiceProvider.h
accessible/src/msaa/nsAccessNodeWrap.cpp
accessible/src/msaa/nsAccessNodeWrap.h
--- a/accessible/src/msaa/AccessibleWrap.cpp
+++ b/accessible/src/msaa/AccessibleWrap.cpp
@@ -10,22 +10,22 @@
 #include "DocAccessible-inl.h"
 #include "EnumVariant.h"
 #include "ia2AccessibleRelation.h"
 #include "nsAccUtils.h"
 #include "nsCoreUtils.h"
 #include "nsIAccessibleEvent.h"
 #include "nsIAccessibleRelation.h"
 #include "nsWinUtils.h"
+#include "ServiceProvider.h"
 #include "Relation.h"
 #include "Role.h"
 #include "RootAccessible.h"
 #include "sdnAccessible.h"
 #include "States.h"
-#include "uiaRawElmProvider.h"
 
 #ifdef A11Y_LOG
 #include "Logging.h"
 #endif
 
 #include "nsIMutableArray.h"
 #include "nsIFrame.h"
 #include "nsIScrollableFrame.h"
@@ -85,17 +85,17 @@ AccessibleWrap::QueryInterface(REFIID ii
     *ppv = static_cast<IAccessible*>(this);
   else if (IID_IEnumVARIANT == iid) {
     // Don't support this interface for leaf elements.
     if (!HasChildren() || nsAccUtils::MustPrune(this))
       return E_NOINTERFACE;
 
     *ppv = static_cast<IEnumVARIANT*>(new ChildrenEnumVariant(this));
   } else if (IID_IServiceProvider == iid)
-    *ppv = static_cast<IServiceProvider*>(this);
+    *ppv = new ServiceProvider(this);
   else if (IID_IAccessible2 == iid && !Compatibility::IsIA2Off())
     *ppv = static_cast<IAccessible2*>(this);
   else if (IID_ISimpleDOMNode == iid) {
     if (IsDefunct() || (!HasOwnContent() && !IsDoc()))
       return E_NOINTERFACE;
 
     *ppv = new sdnAccessible(GetNode());
   }
@@ -122,42 +122,16 @@ AccessibleWrap::QueryInterface(REFIID ii
     return E_NOINTERFACE;
 
   (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
   return S_OK;
 
   A11Y_TRYBLOCK_END
 }
 
-////////////////////////////////////////////////////////////////////////////////
-// IServiceProvider
-
-STDMETHODIMP
-AccessibleWrap::QueryService(REFGUID aGuidService, REFIID aIID,
-                             void** aInstancePtr)
-{
-  if (!aInstancePtr)
-    return E_INVALIDARG;
-
-  *aInstancePtr = NULL;
-
-  // UIA IAccessibleEx
-  if (aGuidService == IID_IAccessibleEx &&
-      Preferences::GetBool("accessibility.uia.enable")) {
-    uiaRawElmProvider* accEx = new uiaRawElmProvider(this);
-    HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
-    if (FAILED(hr))
-      delete accEx;
-
-    return hr;
-  }
-
-  return nsAccessNodeWrap::QueryService(aGuidService, aIID, aInstancePtr);
-}
-
 //-----------------------------------------------------
 // IAccessible methods
 //-----------------------------------------------------
 
 STDMETHODIMP
 AccessibleWrap::get_accParent( IDispatch __RPC_FAR *__RPC_FAR *ppdispParent)
 {
   A11Y_TRYBLOCK_BEGIN
--- a/accessible/src/msaa/AccessibleWrap.h
+++ b/accessible/src/msaa/AccessibleWrap.h
@@ -133,21 +133,16 @@ public: // construction, destruction
     NS_DECL_ISUPPORTS_INHERITED
 
   public: // IUnknown methods - see iunknown.h for documentation
     STDMETHODIMP QueryInterface(REFIID, void**);
 
   // Return the registered OLE class ID of this object's CfDataObj.
     CLSID GetClassID() const;
 
-  // IServiceProvider
-  virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
-                                                 REFIID aIID,
-                                                 void** aInstancePtr);
-
   public: // COM interface IAccessible
     virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accParent( 
         /* [retval][out] */ IDispatch __RPC_FAR *__RPC_FAR *ppdispParent);
 
     virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChildCount( 
         /* [retval][out] */ long __RPC_FAR *pcountChildren);
 
     virtual /* [id][propget] */ HRESULT STDMETHODCALLTYPE get_accChild( 
--- a/accessible/src/msaa/Makefile.in
+++ b/accessible/src/msaa/Makefile.in
@@ -24,16 +24,17 @@ CPPSRCS = \
   HTMLWin32ObjectAccessible.cpp \
   HyperTextAccessibleWrap.cpp \
   ImageAccessibleWrap.cpp \
   nsAccessNodeWrap.cpp \
   nsWinUtils.cpp \
   Compatibility.cpp \
   EnumVariant.cpp \
   Platform.cpp \
+  ServiceProvider.cpp \
   RootAccessibleWrap.cpp \
   TextLeafAccessibleWrap.cpp \
   $(NULL)
 
 ifdef MOZ_XUL
 CPPSRCS += \
   XULListboxAccessibleWrap.cpp \
   XULMenuAccessibleWrap.cpp \
new file mode 100644
--- /dev/null
+++ b/accessible/src/msaa/ServiceProvider.cpp
@@ -0,0 +1,117 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=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 "ServiceProvider.h"
+
+#include "ApplicationAccessibleWrap.h"
+#include "Compatibility.h"
+#include "DocAccessible.h"
+#include "nsAccUtils.h"
+#include "nsCoreUtils.h"
+#include "uiaRawElmProvider.h"
+
+#include "mozilla/Preferences.h"
+#include "nsIDocShell.h"
+
+#include "ISimpleDOMNode_i.c"
+
+namespace mozilla {
+namespace a11y {
+
+IMPL_IUNKNOWN_QUERY_HEAD(ServiceProvider)
+  IMPL_IUNKNOWN_QUERY_IFACE(IServiceProvider)
+  return mAccessible->QueryInterface(aIID, aInstancePtr);
+A11Y_TRYBLOCK_END
+  }
+
+////////////////////////////////////////////////////////////////////////////////
+// IServiceProvider
+
+STDMETHODIMP
+ServiceProvider::QueryService(REFGUID aGuidService, REFIID aIID,
+                              void** aInstancePtr)
+{
+  if (!aInstancePtr)
+    return E_INVALIDARG;
+
+  *aInstancePtr = NULL;
+
+  // UIA IAccessibleEx
+  if (aGuidService == IID_IAccessibleEx &&
+      Preferences::GetBool("accessibility.uia.enable")) {
+    uiaRawElmProvider* accEx = new uiaRawElmProvider(mAccessible);
+    HRESULT hr = accEx->QueryInterface(aIID, aInstancePtr);
+    if (FAILED(hr))
+      delete accEx;
+
+    return hr;
+  }
+
+  // Provide a special service ID for getting the accessible for the browser tab
+  // document that contains this accessible object. If this accessible object
+  // is not inside a browser tab then the service fails with E_NOINTERFACE.
+  // A use case for this is for screen readers that need to switch context or
+  // 'virtual buffer' when focus moves from one browser tab area to another.
+  static const GUID SID_IAccessibleContentDocument =
+    { 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
+  if (aGuidService == SID_IAccessibleContentDocument) {
+    if (aIID != IID_IAccessible)
+      return E_NOINTERFACE;
+
+    nsCOMPtr<nsIDocShell> docShell =
+      nsCoreUtils::GetDocShellFor(mAccessible->GetNode());
+    if (!docShell)
+      return E_UNEXPECTED;
+
+    // Walk up the parent chain without crossing the boundary at which item
+    // types change, preventing us from walking up out of tab content.
+    nsCOMPtr<nsIDocShellTreeItem> root;
+    docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
+    if (!root)
+      return E_UNEXPECTED;
+
+
+    // If the item type is typeContent, we assume we are in browser tab content.
+    // Note this includes content such as about:addons, for consistency.
+    int32_t itemType;
+    root->GetItemType(&itemType);
+    if (itemType != nsIDocShellTreeItem::typeContent)
+      return E_NOINTERFACE;
+
+    // Make sure this is a document.
+    DocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
+    if (!docAcc)
+      return E_UNEXPECTED;
+
+    *aInstancePtr = static_cast<IAccessible*>(docAcc);
+
+    (reinterpret_cast<IUnknown*>(*aInstancePtr))->AddRef();
+    return S_OK;
+  }
+
+  // Can get to IAccessibleApplication from any node via QS
+  if (aGuidService == IID_IAccessibleApplication ||
+      (Compatibility::IsJAWS() && aIID == IID_IAccessibleApplication)) {
+    ApplicationAccessibleWrap* applicationAcc =
+      static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
+    if (!applicationAcc)
+      return E_NOINTERFACE;
+
+    return applicationAcc->QueryInterface(aIID, aInstancePtr);
+  }
+
+  static const GUID IID_SimpleDOMDeprecated =
+    { 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
+  if (aGuidService == IID_ISimpleDOMNode ||
+      aGuidService == IID_SimpleDOMDeprecated ||
+      aGuidService == IID_IAccessible ||  aGuidService == IID_IAccessible2)
+    return mAccessible->QueryInterface(aIID, aInstancePtr);
+
+  return E_INVALIDARG;
+}
+
+} // namespace a11y
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/accessible/src/msaa/ServiceProvider.h
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=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_ServiceProvider_h_
+#define mozilla_a11y_ServiceProvider_h_
+
+#include <servprov.h>
+
+#include "AccessibleWrap.h"
+
+namespace mozilla {
+namespace a11y {
+
+class ServiceProvider MOZ_FINAL : public IServiceProvider
+{
+public:
+  ServiceProvider(AccessibleWrap* aAcc) : mRefCnt(0), mAccessible(aAcc) {}
+  ~ServiceProvider() {}
+
+  DECL_IUNKNOWN
+
+  // IServiceProvider
+  virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
+                                                 REFIID aIID,
+                                                 void** aInstancePtr);
+
+private:
+  nsRefPtr<AccessibleWrap> mAccessible;
+};
+
+}
+}
+
+#endif
--- a/accessible/src/msaa/nsAccessNodeWrap.cpp
+++ b/accessible/src/msaa/nsAccessNodeWrap.cpp
@@ -1,31 +1,18 @@
 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* 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 "nsAccessNodeWrap.h"
 
-#include "AccessibleApplication.h"
-#include "ApplicationAccessibleWrap.h"
-#include "sdnAccessible.h"
+#include "DocAccessible.h"
+#include "nsWinUtils.h"
 
-#include "Compatibility.h"
-#include "nsAccessibilityService.h"
-#include "nsAccUtils.h"
-#include "nsCoreUtils.h"
-#include "nsWinUtils.h"
-#include "RootAccessible.h"
-#include "Statistics.h"
-
-#include "nsAttrName.h"
-#include "nsIDOMNodeList.h"
-#include "nsIDOMHTMLElement.h"
-#include "nsINameSpaceManager.h"
 #include "nsPIDOMWindow.h"
 #include "nsIServiceManager.h"
 
 using namespace mozilla;
 using namespace mozilla::a11y;
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsAccessNodeWrap
@@ -42,111 +29,16 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
 }
 
 //-----------------------------------------------------
 // nsISupports methods
 //-----------------------------------------------------
 
 NS_IMPL_ISUPPORTS_INHERITED0(nsAccessNodeWrap, nsAccessNode)
 
-STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
-{
-  *ppv = nullptr;
-
-  if (IID_IUnknown == iid) {
-    *ppv = static_cast<IUnknown*>(this);
-  } else {
-    return E_NOINTERFACE; //iid not supported.
-  }
-
-  (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
-  return S_OK;
-}
-
-STDMETHODIMP
-nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
-{
-  *ppv = nullptr;
-
-  // Provide a special service ID for getting the accessible for the browser tab
-  // document that contains this accessible object. If this accessible object
-  // is not inside a browser tab then the service fails with E_NOINTERFACE.
-  // A use case for this is for screen readers that need to switch context or
-  // 'virtual buffer' when focus moves from one browser tab area to another.
-  static const GUID SID_IAccessibleContentDocument =
-    { 0xa5d8e1f3,0x3571,0x4d8f,{0x95,0x21,0x07,0xed,0x28,0xfb,0x07,0x2e} };
-  if (guidService == SID_IAccessibleContentDocument) {
-    if (iid != IID_IAccessible)
-      return E_NOINTERFACE;
-
-    nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mContent);
-    if (!docShell)
-      return E_UNEXPECTED;
-
-    // Walk up the parent chain without crossing the boundary at which item
-    // types change, preventing us from walking up out of tab content.
-    nsCOMPtr<nsIDocShellTreeItem> root;
-    docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
-    if (!root)
-      return E_UNEXPECTED;
-
-
-    // If the item type is typeContent, we assume we are in browser tab content.
-    // Note this includes content such as about:addons, for consistency.
-    int32_t itemType;
-    root->GetItemType(&itemType);
-    if (itemType != nsIDocShellTreeItem::typeContent)
-      return E_NOINTERFACE;
-
-    // Make sure this is a document.
-    DocAccessible* docAcc = nsAccUtils::GetDocAccessibleFor(root);
-    if (!docAcc)
-      return E_UNEXPECTED;
-
-    *ppv = static_cast<IAccessible*>(docAcc);
-
-    (reinterpret_cast<IUnknown*>(*ppv))->AddRef();
-    return S_OK;
-  }
-
-  // Can get to IAccessibleApplication from any node via QS
-  if (guidService == IID_IAccessibleApplication ||
-      (Compatibility::IsJAWS() && iid == IID_IAccessibleApplication)) {
-    ApplicationAccessibleWrap* applicationAcc =
-      static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
-    if (!applicationAcc)
-      return E_NOINTERFACE;
-
-    return applicationAcc->QueryInterface(iid, ppv);
-  }
-
-  /**
-   * To get an ISimpleDOMNode, ISimpleDOMDocument, ISimpleDOMText
-   * or any IAccessible2 interface on should use IServiceProvider like this:
-   * -----------------------------------------------------------------------
-   * ISimpleDOMDocument *pAccDoc = NULL;
-   * IServiceProvider *pServProv = NULL;
-   * pAcc->QueryInterface(IID_IServiceProvider, (void**)&pServProv);
-   * if (pServProv) {
-   *   const GUID unused;
-   *   pServProv->QueryService(unused, IID_ISimpleDOMDocument, (void**)&pAccDoc);
-   *   pServProv->Release();
-   * }
-   */
-
-  static const GUID IID_SimpleDOMDeprecated =
-    { 0x0c539790,0x12e4,0x11cf,{0xb6,0x61,0x00,0xaa,0x00,0x4c,0xd6,0xd8} };
-  if (guidService == IID_ISimpleDOMNode ||
-      guidService == IID_SimpleDOMDeprecated ||
-      guidService == IID_IAccessible ||  guidService == IID_IAccessible2)
-    return QueryInterface(iid, ppv);
-
-  return E_INVALIDARG;
-}
- 
 int nsAccessNodeWrap::FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo)
 {
   if (aCode == EXCEPTION_ACCESS_VIOLATION) {
 #ifdef MOZ_CRASHREPORTER
     // MSAA swallows crashes (because it is COM-based)
     // but we still need to learn about those crashes so we can fix them
     // Make sure to pass them to the crash reporter
     nsCOMPtr<nsICrashReporter> crashReporter =
--- a/accessible/src/msaa/nsAccessNodeWrap.h
+++ b/accessible/src/msaa/nsAccessNodeWrap.h
@@ -48,35 +48,25 @@ namespace a11y {
 
 #ifdef __GNUC__
 // Inheriting from both XPCOM and MSCOM interfaces causes a lot of warnings
 // about virtual functions being hidden by each other. This is done by
 // design, so silence the warning.
 #pragma GCC diagnostic ignored "-Woverloaded-virtual"
 #endif
 
-class nsAccessNodeWrap : public nsAccessNode,
-                         public IServiceProvider
+class nsAccessNodeWrap : public nsAccessNode
 {
   public:
     NS_DECL_ISUPPORTS_INHERITED
 
 public: // construction, destruction
   nsAccessNodeWrap(nsIContent* aContent, DocAccessible* aDoc);
   virtual ~nsAccessNodeWrap();
 
-  // IUnknown
-  virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID aIID,
-                                                   void** aInstancePtr);
-
-  // IServiceProvider
-  virtual HRESULT STDMETHODCALLTYPE QueryService(REFGUID aGuidService,
-                                                 REFIID aIID,
-                                                 void** aInstancePtr);
-
     static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo);
 
   static LRESULT CALLBACK WindowProc(HWND hWnd, UINT Msg,
                                      WPARAM WParam, LPARAM lParam);
 
   static nsRefPtrHashtable<nsPtrHashKey<void>, DocAccessible> sHWNDCache;
 };