Open Bug 1531537 Opened 5 years ago Updated 2 years ago

Investigate a11y instantiator oddities on ARM64

Categories

(Core :: Disability Access APIs, enhancement, P3)

ARM64
Windows
enhancement

Tracking

()

REOPENED

People

(Reporter: Jamie, Unassigned)

References

(Blocks 2 open bugs)

Details

Issue 1:

On several ARM64 machines, a11y always seems to be instantiated even when there's no known a11y client. We just see "UNKNOWN|" as the instantiator.

Issue 2:

Normally, NVDA would cause us to see UIAUTOMATION as an in-process a11y instantiator at least some of the time. (This is a little unreliable because it depends on the timing of injection and queries from both NVDA and UIA.) If only Narrator is used, I would expect to always see UIAUTOMATION as an instantiator. On ARM64, I never see UIAUTOMATION show up as an in-process instantiator. For NVDA, I see NVDA. For Narrator, I see UNKNOWN. Either:

  1. UIA isn't getting injected. This seems odd; UIA is definitely in other ARM64 apps.
  2. We're blocking/preventing it somehow.
  3. We're failing to detect it. This seems unlikely; it's a simple call to GetModuleHandleW.
  4. Another client is instantiating a11y before UIA does. Since we only record instantiator info for the first query, we wouldn't detect later injection of UIA.

These two issues might be related, especially if the reason for UIA not showing up turns out to be reason 4 above. They also might be entirely unrelated, in which case we can split up this bug.

Potential next steps (with WinDBG):

  1. With no (obvious) a11y client loaded, use a breakpoint to figure out where the call to WM_GETOBJECT is coming from.
  2. With Narrator loaded, check whether UIAutomationCore.dll is loaded in the Firefox parent process.

Issue 1 is causing the a11y indicator tests to fail. See bug 1525665 and bug 1516214 comment 17.

I wonder whether issue 1 has anything to do with the fact that the DLL interceptor is not yet ready to block touchscreren instantiations.

Ah. That'd make sense. Is there a bug I can block this on for that functionality? Thanks!

Here you go!

Depends on: 1532470
Blocks: 1533114

Now that bug 1532470 is fixed, I tested this again. I did once see UIAUTOMATION show up as an instantiator. However, I still see a11y get instantiated (with UNKNOWN) even without Narrator or NVDA running. With Narrator, I saw UNKNOWN instead of UIAUTOMATION. So, we must be missing some touch-related a11y instantiation specific to Windows 10 ARM64. :(

We'd need to see how far the rabbit hole goes, but the first thing I caught was that something is trying to QueryService on LazyInstantiator for the service id {33F139EE-E509-47F7-BF39-837644F74576}.

Since LazyInstantiator currently does not block any QueryService requests, that's probably the first thing that needs to be stamped out.

Unfortunately, it looks like the rabbit hole goes pretty deep. :(

This all seems to start with a ShowWindow call (frame 17 below), which presumably fires a show win event (and maybe a focus win event?) Then, MSCTF (which I'm fairly sure relates to Text Services Framework) catches this (frame 08) and makes a bunch of queries. I dealt with each of these to get further each time. After disabling QueryService, it wanted accChild with CHILDID_SELF, then QueryInterface to some IID we don't support, then finally accParent. I could try faking accParent (it just needs to return an oleacc window proxy), but I fear we're getting to calls we really don't want to mess with. Looking at the names in the stack (OLEACC!AccWrap_Annotate::get_accRole), I think it wants the role eventually, and if that's all it wants before it gives up, maybe we can deal with it that far; I'll poke at it more later. Here's the stack at present:

0:000> kp
 # Child-SP          RetAddr           Call Site
00 00000008`64bfcfe0 00007ffd`c8e94df0 KERNELBASE!wil::details::DebugBreak
01 00000008`64bfcfe0 00007ffd`c8e9551c xul!mozilla::a11y::LazyInstantiator::MaybeResolveRoot(void)+0x68 [c:\Users\jamie\src\gecko-aarch64\accessible\windows\msaa\LazyInstantiator.cpp @ 320] 
02 00000008`64bfd020 00007ffd`eef25efc xul!mozilla::a11y::LazyInstantiator::get_accParent(struct IDispatch ** ppdispParent = 0x00000000`fb754500)+0x18 [c:\Users\jamie\src\gecko-aarch64\accessible\windows\msaa\LazyInstantiator.cpp @ 526] 
03 00000008`64bfd040 00007ffd`eef24b4c OLEACC!AccWrap_AddIAccProp::QueryInterface+0x25c
04 00000008`64bfd100 00007ffd`fbf14554 OLEACC!AccWrap_Annotate::get_accRole+0x9c
05 00000008`64bfd220 00007ffd`fbf141a4 MSCTF!CThreadInputMgr::OnAccFocusEvent+0x154
06 00000008`64bfd340 00007ffd`fbeeab0c MSCTF!CThreadInputMgr::OnCiceroEvent+0x34
07 00000008`64bfd380 00007ffd`fbeea9ec MSCTF!SYSTHREAD::OnCiceroEvent+0x104
08 00000008`64bfd430 00007ffd`fb916474 MSCTF!WinEventProc+0x5c
09 00000008`64bfd480 00007ffd`fe424bf0 user32!_ClientCallWinEventProc+0x44
0a 00000008`64bfd4c0 00007ffd`fb562654 ntdll!KiUserCallbackDispatcherReturn
0b 00000008`64bfd530 00007ffd`fb905d6c win32u!NtUserMessageCall+0x4
0c 00000008`64bfd530 00007ffd`fb9059fc user32!RealDefWindowProcWorker+0x12c
0d 00000008`64bfd640 00007ffd`fb907178 user32!DefWindowProcW+0xfc
0e 00000008`64bfd6b0 00007ffd`fb906568 user32!UserCallWinProcCheckWow+0x320
0f 00000008`64bfd860 00007ffd`c83d801c user32!CallWindowProcW+0x78
10 00000008`64bfd8a0 00007ffd`c60e19f4 xul!nsWindow::WindowProcInternal(struct HWND__ * hWnd = <Value unavailable error>, unsigned int msg = <Memory access error>, unsigned int64 wParam = <Value unavailable error>, int64 lParam = <Value unavailable error>)+0x1c4 [c:\Users\jamie\src\gecko-aarch64\widget\windows\nsWindow.cpp @ 4767] 
11 00000008`64bfd920 00007ffd`c83d08b8 xul!CallWindowProcCrashProtected(<function> * aWndProc = <Value unavailable error>, struct HWND__ * aHWnd = <Value unavailable error>, unsigned int aMsg = <Value unavailable error>, unsigned int64 aWParam = <Value unavailable error>, int64 aLParam = <Value unavailable error>)+0x2c [c:\Users\jamie\src\gecko-aarch64\xpcom\base\nsCrashOnException.cpp @ 32] 
12 00000008`64bfd940 00007ffd`fb907178 xul!nsWindow::WindowProc(struct HWND__ * hWnd = <Value unavailable error>, unsigned int msg = <Value unavailable error>, unsigned int64 wParam = <Value unavailable error>, int64 lParam = <Value unavailable error>)+0x68 [c:\Users\jamie\src\gecko-aarch64\widget\windows\nsWindow.cpp @ 4716] 
13 00000008`64bfd980 00007ffd`fb906b30 user32!UserCallWinProcCheckWow+0x320
14 00000008`64bfdb30 00007ffd`fb912380 user32!DispatchClientMessage+0x80
15 00000008`64bfdb70 00007ffd`fe424bf0 user32!_fnDWORD+0x40
16 00000008`64bfdbb0 00007ffd`fb562b54 ntdll!KiUserCallbackDispatcherReturn
17 00000008`64bfdc20 00007ffd`c83d1900 win32u!NtUserShowWindow+0x4
18 00000008`64bfdc20 00007ffd`c8e8fe10 xul!nsWindow::Show(bool bState = <Value unavailable error>)+0x3f8 [c:\Users\jamie\src\gecko-aarch64\widget\windows\nsWindow.cpp @ 0] 
19 00000008`64bfdc70 00007ffd`c8e8bacc xul!nsXULWindow::SetVisibility(CvRegToMachine(arm64) conversion failure for 0x8
CvRegToMachine(arm64) conversion failure for 0x8
bool aVisibility = false)+0xc4 [c:\Users\jamie\src\gecko-aarch64\xpfe\appshell\nsXULWindow.cpp @ 847] 
1a 00000008`64bfdcc0 00007ffd`c6a8dfe8 xul!nsWebShellWindow::OnStateChange(class nsIWebProgress * aProgress = <Value unavailable error>, class nsIRequest * aRequest = <Value unavailable error>, unsigned int aStateFlags = <Value unavailable error>, nsresult aStatus = <Value unavailable error>)+0xdc [c:\Users\jamie\src\gecko-aarch64\xpfe\appshell\nsWebShellWindow.cpp @ 616] 
1b 00000008`64bfdd00 00007ffd`c6a8dcb4 xul!nsDocLoader::DoFireOnStateChange(class nsIWebProgress * aProgress = 0x00000000`64bfcca0, class nsIRequest * aRequest = 0x00000000`00000059, int * aStateFlags = 0x00000000`0000028e, nsresult aStatus = 0n-76200704 (No matching enumerant))+0x110 [c:\Users\jamie\src\gecko-aarch64\uriloader\base\nsDocLoader.cpp @ 1333] 
1c 00000008`64bfdd80 00007ffd`c6a8cb38 xul!nsDocLoader::doStopDocumentLoad(class nsIRequest * request = 0x00000000`0000028e, nsresult aStatus = 0n-76200704 (No matching enumerant))+0x154 [c:\Users\jamie\src\gecko-aarch64\uriloader\base\nsDocLoader.cpp @ 902] 
1d 00000008`64bfde20 00007ffd`c6a8d768 xul!nsDocLoader::DocLoaderIsEmpty(void)+0x170 [c:\Users\jamie\src\gecko-aarch64\uriloader\base\nsDocLoader.cpp @ 729] 
1e 00000008`64bfdf30 00007ffd`c624c480 xul!nsDocLoader::OnStopRequest(class nsIRequest * aRequest = 0x00000000`00000059, nsresult aStatus = 0n712 (No matching enumerant))+0x21c [c:\Users\jamie\src\gecko-aarch64\uriloader\base\nsDocLoader.cpp @ 615] 
1f 00000008`64bfe020 00007ffd`c624b538 xul!mozilla::net::nsLoadGroup::RemoveRequest(class nsIRequest * request = 0x00000000`fb754500, class nsISupports * ctxt = <Value unavailable error>, nsresult aStatus = 0n89 (No matching enumerant))+0x2a4 [c:\Users\jamie\src\gecko-aarch64\netwerk\base\nsLoadGroup.cpp @ 568] 
...

Btw, I have a nasty suspicion this might happen on Windows 10 computers with touch screens, not just ARM64. Asa noted that on his Surface, he gets accessibility enabled even without any known client loaded.

I wonder if we could hook MSCTF!WinEventProc (sounds like a WinEventProc signature) and block WM_GETOBJECT for the duration?

(In reply to James Teh [:Jamie] from comment #9)

I wonder if we could hook MSCTF!WinEventProc (sounds like a WinEventProc signature) and block WM_GETOBJECT for the duration?

I suspect this happens even without touch screens. See bug 1687535.

Turns out 'Issue 1' here is related to devices which turn on On Screen Keyboard support I believe. So indeed mainly touch screens. Implemented a fix for Issue 1 on bug 1687535.

Status: NEW → RESOLVED
Closed: 3 years ago
Resolution: --- → DUPLICATE

Didn't mean to dupe this, keeping open for Issue 2.

Status: RESOLVED → REOPENED
Resolution: DUPLICATE → ---
Severity: normal → S3
You need to log in before you can comment on or make changes to this bug.