Bug 1417327 part 1: Accessible handler: Cache IAccessibleAction::nActions. r=MarcoZ a=gchang
authorJames Teh <jteh@mozilla.com>
Wed, 15 Nov 2017 17:27:05 +1000
changeset 444960 403ec09d449e557972cf017f4f094e76e7009c95
parent 444959 7ebf334c8ed4fd51c3dc738a2274ed7485f7e5fc
child 444961 5b467b5636efa46906af107b824ecfb4787cc971
push id1618
push userCallek@gmail.com
push dateThu, 11 Jan 2018 17:45:48 +0000
treeherdermozilla-release@882ca853e05a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersMarcoZ, gchang
bugs1417327
milestone58.0
Bug 1417327 part 1: Accessible handler: Cache IAccessibleAction::nActions. r=MarcoZ a=gchang MozReview-Commit-ID: EJIhSxSiQGq
accessible/ipc/win/HandlerProvider.cpp
accessible/ipc/win/handler/AccessibleHandler.cpp
accessible/ipc/win/handler/HandlerData.idl
--- a/accessible/ipc/win/HandlerProvider.cpp
+++ b/accessible/ipc/win/HandlerProvider.cpp
@@ -348,16 +348,27 @@ HandlerProvider::BuildDynamicIA2Data(Dyn
     return;
   }
 
   hr = target->role(&aOutIA2Data->mIA2Role);
   if (FAILED(hr)) {
     return;
   }
 
+  RefPtr<IAccessibleAction> action;
+  // It is not an error if this fails.
+  hr = mTargetUnk.get()->QueryInterface(IID_IAccessibleAction,
+    getter_AddRefs(action));
+  if (SUCCEEDED(hr)) {
+    hr = action->nActions(&aOutIA2Data->mNActions);
+    if (FAILED(hr)) {
+      return;
+    }
+  }
+
   // NB: get_uniqueID should be the final property retrieved in this method,
   // as its presence is used to determine whether the rest of this data
   // retrieval was successful.
   hr = target->get_uniqueID(&aOutIA2Data->mUniqueId);
 }
 
 void
 HandlerProvider::CleanupStaticIA2Data(StaticIA2Data& aData)
--- a/accessible/ipc/win/handler/AccessibleHandler.cpp
+++ b/accessible/ipc/win/handler/AccessibleHandler.cpp
@@ -1190,21 +1190,31 @@ AccessibleHandler::GetClassInfo(ITypeInf
   return ctl->GetHandlerTypeInfo(aOutTypeInfo);
 }
 
 /*** IAccessibleAction ***/
 
 HRESULT
 AccessibleHandler::nActions(long* nActions)
 {
-  HRESULT hr = ResolveIAHyperlink();
-  if (FAILED(hr)) {
-    return hr;
+  if (!nActions) {
+    return E_INVALIDARG;
   }
-  return mIAHyperlinkPassThru->nActions(nActions);
+
+  if (!HasPayload()) {
+    HRESULT hr = ResolveIAHyperlink();
+    if (FAILED(hr)) {
+      return hr;
+    }
+    return mIAHyperlinkPassThru->nActions(nActions);
+  }
+
+  BEGIN_CACHE_ACCESS;
+  GET_FIELD(mNActions, *nActions);
+  return S_OK;
 }
 
 HRESULT
 AccessibleHandler::doAction(long actionIndex)
 {
   HRESULT hr = ResolveIAHyperlink();
   if (FAILED(hr)) {
     return hr;
--- a/accessible/ipc/win/handler/HandlerData.idl
+++ b/accessible/ipc/win/handler/HandlerData.idl
@@ -26,16 +26,17 @@ typedef struct _StaticIA2Data
   IAccessibleHyperlink* mIAHyperlink;
   IAccessibleTable* mIATable;
   IAccessibleTable2* mIATable2;
   IAccessibleTableCell* mIATableCell;
 } StaticIA2Data;
 
 typedef struct _DynamicIA2Data
 {
+  // From IAccessible/IAccessible2
   VARIANT           mRole;
   long              mState;
   long              mChildCount;
   long              mIA2Role;
   AccessibleStates  mIA2States;
   long              mLeft;
   long              mTop;
   long              mWidth;
@@ -43,16 +44,19 @@ typedef struct _DynamicIA2Data
   long              mHwnd;
   BSTR              mKeyboardShortcut;
   BSTR              mName;
   BSTR              mDescription;
   BSTR              mDefaultAction;
   BSTR              mValue;
   BSTR              mAttributes;
   IA2Locale         mIA2Locale;
+  // From IAccessibleAction
+  long              mNActions;
+  // From IAccessible2
   long              mUniqueId;
 } DynamicIA2Data;
 
 interface IGeckoBackChannel;
 
 // We define different CLSIDs and IIDs depending on channel and officiality.
 // This prevents handlers from installing overtop one another when multiple
 // channels are present. Note that we do not do this for all UUIDs in this IDL,