bug 1303133 - Implement ia2AccessibleValue methods in ProxyAccessible for Windows. r=aklotz
authorMichael Li <michael.li11702@gmail.com>
Thu, 13 Oct 2016 17:09:33 -0400
changeset 319873 81a257aa9c4e194750afb65dd666ea600981d99a
parent 319872 f686f5590975a862d85e61f643c6dc39b1a8ee8f
child 319874 d1e487f723a0154cbd9752f37fcbaebf17cbcf1c
push id20749
push userryanvm@gmail.com
push dateSat, 29 Oct 2016 13:21:21 +0000
treeherderfx-team@1b170b39ed6b [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersaklotz
bugs1303133
milestone52.0a1
bug 1303133 - Implement ia2AccessibleValue methods in ProxyAccessible for Windows. r=aklotz
accessible/ipc/win/ProxyAccessible.cpp
accessible/xpcom/xpcAccessibleValue.cpp
--- a/accessible/ipc/win/ProxyAccessible.cpp
+++ b/accessible/ipc/win/ProxyAccessible.cpp
@@ -1,16 +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/. */
 
 #include "Accessible2.h"
 #include "ProxyAccessible.h"
+#include "ia2AccessibleValue.h"
 #include "mozilla/a11y/DocAccessibleParent.h"
 #include "DocAccessible.h"
 #include "mozilla/a11y/DocManager.h"
 #include "mozilla/dom/Element.h"
 #include "mozilla/dom/TabParent.h"
 #include "mozilla/Unused.h"
 #include "mozilla/a11y/Platform.h"
 #include "RelationType.h"
@@ -44,16 +45,49 @@ ProxyAccessible::GetCOMInterface(void** 
     thisPtr->mCOMProxy = wrap->GetIAccessibleFor(realId, &isDefunct);
   }
 
   RefPtr<IAccessible> addRefed = mCOMProxy;
   addRefed.forget(aOutAccessible);
   return !!mCOMProxy;
 }
 
+/**
+ * Specializations of this template map an IAccessible type to its IID
+ */
+template<typename Interface> struct InterfaceIID {};
+
+template<>
+struct InterfaceIID<IAccessibleValue>
+{
+  static REFIID Value() { return IID_IAccessibleValue; }
+};
+
+/**
+ * Get the COM proxy for this proxy accessible and QueryInterface it with the
+ * correct IID
+ */
+template<typename Interface>
+static already_AddRefed<Interface>
+QueryInterface(const ProxyAccessible* aProxy)
+{
+  RefPtr<IAccessible> acc;
+  if (!aProxy->GetCOMInterface((void**)getter_AddRefs(acc))) {
+    return nullptr;
+  }
+
+  RefPtr<Interface> acc2;
+  if (FAILED(acc->QueryInterface(InterfaceIID<Interface>::Value(),
+                                 (void**)getter_AddRefs(acc2)))) {
+    return nullptr;
+  }
+
+  return acc2.forget();
+}
+
 void
 ProxyAccessible::Name(nsString& aName) const
 {
   aName.Truncate();
   RefPtr<IAccessible> acc;
   if (!GetCOMInterface((void**)getter_AddRefs(acc))) {
     return;
   }
@@ -272,10 +306,77 @@ ProxyAccessible::Attributes(nsTArray<Att
     return;
   }
 
   ConvertBSTRAttributesToArray(nsDependentString((wchar_t*)attrs,
                                                  attrsWrap.length()),
                                aAttrs);
 }
 
+double
+ProxyAccessible::CurValue()
+{
+  RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+  if (!acc) {
+    return UnspecifiedNaN<double>();
+  }
+
+  VARIANT currentValue;
+  HRESULT hr = acc->get_currentValue(&currentValue);
+  if (FAILED(hr) || currentValue.vt != VT_R8) {
+    return UnspecifiedNaN<double>();
+  }
+
+  return currentValue.dblVal;
+}
+
+bool
+ProxyAccessible::SetCurValue(double aValue)
+{
+  RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+  if (!acc) {
+    return false;
+  }
+
+  VARIANT currentValue;
+  VariantInit(&currentValue);
+  currentValue.vt = VT_R8;
+  currentValue.dblVal = aValue;
+  HRESULT hr = acc->setCurrentValue(currentValue);
+  return SUCCEEDED(hr);
+}
+
+double
+ProxyAccessible::MinValue()
+{
+  RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+  if (!acc) {
+    return UnspecifiedNaN<double>();
+  }
+
+  VARIANT minimumValue;
+  HRESULT hr = acc->get_minimumValue(&minimumValue);
+  if (FAILED(hr) || minimumValue.vt != VT_R8) {
+    return UnspecifiedNaN<double>();
+  }
+
+  return minimumValue.dblVal;
+}
+
+double
+ProxyAccessible::MaxValue()
+{
+  RefPtr<IAccessibleValue> acc = QueryInterface<IAccessibleValue>(this);
+  if (!acc) {
+    return UnspecifiedNaN<double>();
+  }
+
+  VARIANT maximumValue;
+  HRESULT hr = acc->get_maximumValue(&maximumValue);
+  if (FAILED(hr) || maximumValue.vt != VT_R8) {
+    return UnspecifiedNaN<double>();
+  }
+
+  return maximumValue.dblVal;
+}
+
 } // namespace a11y
 } // namespace mozilla
--- a/accessible/xpcom/xpcAccessibleValue.cpp
+++ b/accessible/xpcom/xpcAccessibleValue.cpp
@@ -21,21 +21,17 @@ xpcAccessibleValue::GetMaximumValue(doub
 
   if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
     return NS_ERROR_FAILURE;
 
   double value;
   if (Intl().IsAccessible()) {
     value = Intl().AsAccessible()->MaxValue();
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     value = Intl().AsProxy()->MaxValue();
-#endif
   }
 
   if (!IsNaN(value))
     *aValue = value;
 
   return NS_OK;
 }
 
@@ -50,21 +46,17 @@ xpcAccessibleValue::GetMinimumValue(doub
 
   if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
     return NS_ERROR_FAILURE;
 
   double value;
   if (Intl().IsAccessible()) {
     value = Intl().AsAccessible()->MinValue();
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     value = Intl().AsProxy()->MinValue();
-#endif
   }
 
   if (!IsNaN(value))
     *aValue = value;
 
   return NS_OK;
 }
 
@@ -79,21 +71,17 @@ xpcAccessibleValue::GetCurrentValue(doub
 
   if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
     return NS_ERROR_FAILURE;
 
   double value;
   if (Intl().IsAccessible()) {
     value = Intl().AsAccessible()->CurValue();
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     value = Intl().AsProxy()->CurValue();
-#endif
   }
 
   if (!IsNaN(value))
     *aValue = value;
 
   return NS_OK;
 }
 
@@ -104,21 +92,17 @@ xpcAccessibleValue::SetCurrentValue(doub
     return NS_ERROR_FAILURE;
 
   if (Intl().IsAccessible() && Intl().AsAccessible()->IsDefunct())
     return NS_ERROR_FAILURE;
 
   if (Intl().IsAccessible()) {
     Intl().AsAccessible()->SetCurValue(aValue);
   } else {
-#if defined(XP_WIN)
-    return NS_ERROR_NOT_IMPLEMENTED;
-#else
     Intl().AsProxy()->SetCurValue(aValue);
-#endif
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 xpcAccessibleValue::GetMinimumIncrement(double* aValue)
 {