Bug 1695116 part 9: Fail gracefully for MSAA methods which don't support RemoteAccessible yet instead of crashing. r=morgan
authorJames Teh <jteh@mozilla.com>
Tue, 08 Jun 2021 07:20:52 +0000
changeset 582191 52c8369045239cc3e2878ad7ee7915a1b940d195
parent 582190 55273d675037ad1ff9e88fdef6c17dbdb5536a6a
child 582192 185d685563d9720a6d19cca4ae19334339c378c2
push id38523
push userimoraru@mozilla.com
push dateTue, 08 Jun 2021 15:57:50 +0000
treeherdermozilla-central@a5021586700f [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmorgan
bugs1695116
milestone91.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 1695116 part 9: Fail gracefully for MSAA methods which don't support RemoteAccessible yet instead of crashing. r=morgan Differential Revision: https://phabricator.services.mozilla.com/D116199
accessible/windows/msaa/MsaaAccessible.cpp
accessible/windows/msaa/MsaaRootAccessible.cpp
--- a/accessible/windows/msaa/MsaaAccessible.cpp
+++ b/accessible/windows/msaa/MsaaAccessible.cpp
@@ -922,16 +922,19 @@ MsaaAccessible::get_accName(
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
     return hr;
   }
 
   if (accessible) {
     return accessible->get_accName(kVarChildIdSelf, pszName);
   }
+  if (mAcc->IsRemote()) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   nsAutoString name;
   LocalAcc()->Name(name);
 
   // The name was not provided, e.g. no alt attribute for an image. A screen
   // reader may choose to invent its own accessible name, e.g. from an image src
   // attribute. Refer to eNoNameOnPurpose return value.
   if (name.IsVoid()) return S_FALSE;
@@ -953,16 +956,19 @@ MsaaAccessible::get_accValue(
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
     return hr;
   }
 
   if (accessible) {
     return accessible->get_accValue(kVarChildIdSelf, pszValue);
   }
+  if (mAcc->IsRemote()) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   nsAutoString value;
   LocalAcc()->Value(value);
 
   // See bug 438784: need to expose URL on doc's value attribute. For this,
   // reverting part of fix for bug 425693 to make this MSAA method behave
   // IAccessible2-style.
   if (value.IsEmpty()) return S_FALSE;
@@ -983,16 +989,19 @@ MsaaAccessible::get_accDescription(VARIA
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
     return hr;
   }
 
   if (accessible) {
     return accessible->get_accDescription(kVarChildIdSelf, pszDescription);
   }
+  if (mAcc->IsRemote()) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   nsAutoString description;
   LocalAcc()->Description(description);
 
   *pszDescription =
       ::SysAllocStringLen(description.get(), description.Length());
   return *pszDescription ? S_OK : E_OUTOFMEMORY;
 }
@@ -1113,16 +1122,19 @@ MsaaAccessible::get_accState(
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
     return hr;
   }
 
   if (accessible) {
     return accessible->get_accState(kVarChildIdSelf, pvarState);
   }
+  if (mAcc->IsRemote()) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   // MSAA only has 31 states and the lowest 31 bits of our state bit mask
   // are the same states as MSAA.
   // Note: we map the following Gecko states to different MSAA states:
   //   REQUIRED -> ALERT_LOW
   //   ALERT -> ALERT_MEDIUM
   //   INVALID -> ALERT_HIGH
   //   CHECKABLE -> MARQUEED
@@ -1171,16 +1183,19 @@ MsaaAccessible::get_accKeyboardShortcut(
   }
 
   if (accessible) {
     return accessible->get_accKeyboardShortcut(kVarChildIdSelf,
                                                pszKeyboardShortcut);
   }
 
   LocalAccessible* localAcc = LocalAcc();
+  if (!localAcc) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
   KeyBinding keyBinding = localAcc->AccessKey();
   if (keyBinding.IsEmpty()) keyBinding = localAcc->KeyboardShortcut();
 
   nsAutoString shortcut;
   keyBinding.ToString(shortcut);
 
   *pszKeyboardShortcut = ::SysAllocStringLen(shortcut.get(), shortcut.Length());
   return *pszKeyboardShortcut ? S_OK : E_OUTOFMEMORY;
@@ -1196,18 +1211,23 @@ MsaaAccessible::get_accFocus(
   // clang-format off
   // VT_EMPTY:    None. This object does not have the keyboard focus itself
   //              and does not contain a child that has the keyboard focus.
   // VT_I4:       lVal is CHILDID_SELF. The object itself has the keyboard focus.
   // VT_I4:       lVal contains the child ID of the child element with the keyboard focus.
   // VT_DISPATCH: pdispVal member is the address of the IDispatch interface
   //              for the child object with the keyboard focus.
   // clang-format on
+  if (!mAcc) {
+    return CO_E_OBJNOTCONNECTED;
+  }
   LocalAccessible* localAcc = LocalAcc();
-  if (!localAcc) return CO_E_OBJNOTCONNECTED;
+  if (!localAcc) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   // Return the current IAccessible child that has focus
   LocalAccessible* focusedAccessible = localAcc->FocusedChild();
 
   if (focusedAccessible == localAcc) {
     pvarChild->vt = VT_I4;
     pvarChild->lVal = CHILDID_SELF;
   } else if (focusedAccessible) {
@@ -1328,18 +1348,23 @@ AccessibleEnumerator::Skip(unsigned long
  */
 STDMETHODIMP
 MsaaAccessible::get_accSelection(VARIANT __RPC_FAR* pvarChildren) {
   if (!pvarChildren) return E_INVALIDARG;
 
   VariantInit(pvarChildren);
   pvarChildren->vt = VT_EMPTY;
 
+  if (!mAcc) {
+    return CO_E_OBJNOTCONNECTED;
+  }
   LocalAccessible* localAcc = LocalAcc();
-  if (!localAcc) return CO_E_OBJNOTCONNECTED;
+  if (!localAcc) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   if (!localAcc->IsSelect()) {
     return S_OK;
   }
 
   AutoTArray<LocalAccessible*, 10> selectedItems;
   localAcc->SelectedItems(&selectedItems);
   uint32_t count = selectedItems.Length();
@@ -1371,16 +1396,19 @@ MsaaAccessible::get_accDefaultAction(
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
     return hr;
   }
 
   if (accessible) {
     return accessible->get_accDefaultAction(kVarChildIdSelf, pszDefaultAction);
   }
+  if (mAcc->IsRemote()) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   nsAutoString defaultAction;
   LocalAcc()->ActionNameAt(0, defaultAction);
 
   *pszDefaultAction =
       ::SysAllocStringLen(defaultAction.get(), defaultAction.Length());
   return *pszDefaultAction ? S_OK : E_OUTOFMEMORY;
 }
@@ -1393,16 +1421,19 @@ MsaaAccessible::accSelect(
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
     return hr;
   }
 
   if (accessible) {
     return accessible->accSelect(flagsSelect, kVarChildIdSelf);
   }
+  if (mAcc->IsRemote()) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   LocalAccessible* localAcc = LocalAcc();
   if (flagsSelect & SELFLAG_TAKEFOCUS) {
     if (XRE_IsContentProcess()) {
       // In this case we might have been invoked while the IPC MessageChannel is
       // waiting on a sync reply. We cannot dispatch additional IPC while that
       // is happening, so we dispatch TakeFocus from the main thread to
       // guarantee that we are outside any IPC.
@@ -1455,17 +1486,17 @@ MsaaAccessible::accLocation(
 
   if (accessible) {
     return accessible->accLocation(pxLeft, pyTop, pcxWidth, pcyHeight,
                                    kVarChildIdSelf);
   }
 
   LocalAccessible* localAcc = LocalAcc();
   if (!localAcc) {
-    return CO_E_OBJNOTCONNECTED;
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
   }
 
   nsIntRect rect = localAcc->Bounds();
 
   *pxLeft = rect.X();
   *pyTop = rect.Y();
   *pcxWidth = rect.Width();
   *pcyHeight = rect.Height();
@@ -1567,18 +1598,23 @@ STDMETHODIMP
 MsaaAccessible::accHitTest(
     /* [in] */ long xLeft,
     /* [in] */ long yTop,
     /* [retval][out] */ VARIANT __RPC_FAR* pvarChild) {
   if (!pvarChild) return E_INVALIDARG;
 
   VariantInit(pvarChild);
 
+  if (!mAcc) {
+    return CO_E_OBJNOTCONNECTED;
+  }
   LocalAccessible* localAcc = LocalAcc();
-  if (!localAcc) return CO_E_OBJNOTCONNECTED;
+  if (!localAcc) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   LocalAccessible* accessible = localAcc->LocalChildAtPoint(
       xLeft, yTop, Accessible::EWhichChildAtPoint::DirectChild);
 
   // if we got a child
   if (accessible) {
     // if the child is us
     if (accessible == localAcc) {
@@ -1603,16 +1639,19 @@ MsaaAccessible::accDoDefaultAction(
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
     return hr;
   }
 
   if (accessible) {
     return accessible->accDoDefaultAction(kVarChildIdSelf);
   }
+  if (mAcc->IsRemote()) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   return LocalAcc()->DoAction(0) ? S_OK : E_INVALIDARG;
 }
 
 STDMETHODIMP
 MsaaAccessible::put_accName(
     /* [optional][in] */ VARIANT varChild,
     /* [in] */ BSTR szName) {
@@ -1627,16 +1666,19 @@ MsaaAccessible::put_accValue(
   HRESULT hr = ResolveChild(varChild, getter_AddRefs(accessible));
   if (FAILED(hr)) {
     return hr;
   }
 
   if (accessible) {
     return accessible->put_accValue(kVarChildIdSelf, szValue);
   }
+  if (mAcc->IsRemote()) {
+    return E_NOTIMPL;  // XXX Not supported for RemoteAccessible yet.
+  }
 
   HyperTextAccessible* ht = LocalAcc()->AsHyperText();
   if (!ht) {
     return E_NOTIMPL;
   }
 
   uint32_t length = ::SysStringLen(szValue);
   nsAutoString text(szValue, length);
--- a/accessible/windows/msaa/MsaaRootAccessible.cpp
+++ b/accessible/windows/msaa/MsaaRootAccessible.cpp
@@ -121,16 +121,19 @@ MsaaRootAccessible::get_accFocus(
     // remote document because this causes mysterious intermittent crashes
     // when we're called by UIA clients; see bug 1424505.
     return hr;
   }
 
   // The base implementation reported no focus.
   // Focus might be in a remote document.
   // (The base implementation can't handle this.)
+  if (StaticPrefs::accessibility_cache_enabled_AtStartup()) {
+    return S_FALSE;
+  }
   // Get the document in the active tab.
   RootAccessible* rootAcc = RootAcc();
   if (!rootAcc) {
     return CO_E_OBJNOTCONNECTED;
   }
   RemoteAccessible* docProxy = rootAcc->GetPrimaryRemoteTopLevelContentDoc();
   if (!docProxy) {
     return hr;