From 57f4ee0c7b04f7c2823a670724df30b27fd1c037 Mon Sep 17 00:00:00 2001 From: Eitan Isaacson Date: Thu, 3 Mar 2022 22:04:39 +0000 Subject: [PATCH] Bug 1757812 - P2: Move pivot in parent when caching is enabled. r=morgan This is a baby step in the caching direction. It isn't perfect yet. Specifically, cache we have now in Android depends on a cache push from content that doesn't happen if we do this all parent side. So most of the junit tests pass, except for the heading one because we don't cache heading levels in the less complete viewport cache. tl;dr This will work right when the accessibles being retrieved are from our ctw cache. This will happen in followup bugs. Differential Revision: https://phabricator.services.mozilla.com/D140120 --- accessible/android/AccessibleWrap.cpp | 38 ++++++++++++++----- accessible/android/AccessibleWrap.h | 1 + accessible/android/RemoteAccessibleWrap.cpp | 6 +++ accessible/android/SessionAccessibility.cpp | 42 ++++++++++----------- accessible/android/SessionAccessibility.h | 7 +--- 5 files changed, 58 insertions(+), 36 deletions(-) diff --git a/accessible/android/AccessibleWrap.cpp b/accessible/android/AccessibleWrap.cpp index c8e64b06dd82..8849e4227002 100644 --- a/accessible/android/AccessibleWrap.cpp +++ b/accessible/android/AccessibleWrap.cpp @@ -298,16 +298,34 @@ void AccessibleWrap::PivotTo(int32_t aGranularity, bool aForward, bool aInclusive) { a11y::Pivot pivot(RootAccessible()); TraversalRule rule(aGranularity); - Accessible* maybeResult = aForward ? pivot.Next(this, rule, aInclusive) - : pivot.Prev(this, rule, aInclusive); - LocalAccessible* result = maybeResult ? maybeResult->AsLocal() : nullptr; - if (result && (result != this || aInclusive)) { - PivotMoveReason reason = aForward ? nsIAccessiblePivot::REASON_NEXT - : nsIAccessiblePivot::REASON_PREV; - RefPtr event = new AccVCChangeEvent( - result->Document(), this, -1, -1, result, -1, -1, reason, - nsIAccessiblePivot::NO_BOUNDARY, eFromUserInput); - nsEventShell::FireEvent(event); + Accessible* current = IsProxy() ? Proxy() : static_cast(this); + Accessible* result = aForward ? pivot.Next(current, rule, aInclusive) + : pivot.Prev(current, rule, aInclusive); + + if (result && (result != current || aInclusive)) { + RefPtr newPosition = + result->IsRemote() ? WrapperFor(result->AsRemote()) + : static_cast(result->AsLocal()); + + if (IPCAccessibilityActive()) { + // We are in the child process. Dispatch a virtual cursor + // change event that will be turned into an android + // accessibility focused changed event in the parent. + PivotMoveReason reason = aForward ? nsIAccessiblePivot::REASON_NEXT + : nsIAccessiblePivot::REASON_PREV; + LocalAccessible* localResult = result->AsLocal(); + MOZ_ASSERT(localResult); + RefPtr event = new AccVCChangeEvent( + localResult->Document(), this, -1, -1, localResult, -1, -1, reason, + nsIAccessiblePivot::NO_BOUNDARY, eFromUserInput); + nsEventShell::FireEvent(event); + } else { + // We are in the parent process. Dispatch an accessibility focused + // event directly. + RefPtr sessionAcc = + SessionAccessibility::GetInstanceFor(result); + sessionAcc->SendAccessibilityFocusedEvent(newPosition); + } } } diff --git a/accessible/android/AccessibleWrap.h b/accessible/android/AccessibleWrap.h index fa384f090247..7c99c11372f5 100644 --- a/accessible/android/AccessibleWrap.h +++ b/accessible/android/AccessibleWrap.h @@ -36,6 +36,7 @@ class AccessibleWrap : public LocalAccessible { virtual bool GetSelectionBounds(int32_t* aStartOffset, int32_t* aEndOffset); + MOZ_CAN_RUN_SCRIPT_BOUNDARY virtual void PivotTo(int32_t aGranularity, bool aForward, bool aInclusive); virtual void NavigateText(int32_t aGranularity, int32_t aStartOffset, diff --git a/accessible/android/RemoteAccessibleWrap.cpp b/accessible/android/RemoteAccessibleWrap.cpp index 4c61ffa456b7..9718b766b852 100644 --- a/accessible/android/RemoteAccessibleWrap.cpp +++ b/accessible/android/RemoteAccessibleWrap.cpp @@ -7,6 +7,7 @@ #include "LocalAccessible-inl.h" #include "mozilla/a11y/DocAccessiblePlatformExtParent.h" +#include "mozilla/StaticPrefs_accessibility.h" using namespace mozilla::a11y; @@ -110,6 +111,11 @@ bool RemoteAccessibleWrap::GetSelectionBounds(int32_t* aStartOffset, void RemoteAccessibleWrap::PivotTo(int32_t aGranularity, bool aForward, bool aInclusive) { + if (StaticPrefs::accessibility_cache_enabled_AtStartup()) { + AccessibleWrap::PivotTo(aGranularity, aForward, aInclusive); + return; + } + Unused << Proxy()->Document()->GetPlatformExtension()->SendPivot( Proxy()->ID(), aGranularity, aForward, aInclusive); } diff --git a/accessible/android/SessionAccessibility.cpp b/accessible/android/SessionAccessibility.cpp index b1582ceaef58..c27381fd349c 100644 --- a/accessible/android/SessionAccessibility.cpp +++ b/accessible/android/SessionAccessibility.cpp @@ -18,6 +18,7 @@ #include "mozilla/PresShell.h" #include "mozilla/dom/BrowserParent.h" +#include "mozilla/a11y/Accessible.h" #include "mozilla/a11y/DocAccessibleParent.h" #include "mozilla/a11y/DocManager.h" #include "mozilla/jni/GeckoBundleUtils.h" @@ -173,9 +174,26 @@ void SessionAccessibility::Paste(int32_t aID) { } RefPtr SessionAccessibility::GetInstanceFor( - RemoteAccessible* aAccessible) { - auto tab = - static_cast(aAccessible->Document()->Manager()); + Accessible* aAccessible) { + if (aAccessible->IsLocal()) { + RootAccessible* rootAcc = aAccessible->AsLocal()->RootAccessible(); + nsViewManager* vm = rootAcc->PresShellPtr()->GetViewManager(); + if (!vm) { + return nullptr; + } + + nsCOMPtr rootWidget = vm->GetRootWidget(); + // `rootWidget` can be one of several types. Here we make sure it is an + // android nsWindow. + if (RefPtr window = nsWindow::From(rootWidget)) { + return window->GetSessionAccessibility(); + } + + return nullptr; + } + + auto tab = static_cast( + aAccessible->AsRemote()->Document()->Manager()); dom::Element* frame = tab->GetOwnerElement(); MOZ_ASSERT(frame); if (!frame) { @@ -186,24 +204,6 @@ RefPtr SessionAccessibility::GetInstanceFor( return chromeDoc ? GetInstanceFor(chromeDoc) : nullptr; } -RefPtr SessionAccessibility::GetInstanceFor( - LocalAccessible* aAccessible) { - RootAccessible* rootAcc = aAccessible->RootAccessible(); - nsViewManager* vm = rootAcc->PresShellPtr()->GetViewManager(); - if (!vm) { - return nullptr; - } - - nsCOMPtr rootWidget = vm->GetRootWidget(); - // `rootWidget` can be one of several types. Here we make sure it is an - // android nsWindow. - if (RefPtr window = nsWindow::From(rootWidget)) { - return window->GetSessionAccessibility(); - } - - return nullptr; -} - void SessionAccessibility::SendAccessibilityFocusedEvent( AccessibleWrap* aAccessible) { mSessionAccessibility->SendEvent( diff --git a/accessible/android/SessionAccessibility.h b/accessible/android/SessionAccessibility.h index 26d6ff3db176..6f8d695b4c38 100644 --- a/accessible/android/SessionAccessibility.h +++ b/accessible/android/SessionAccessibility.h @@ -16,7 +16,7 @@ namespace mozilla { namespace a11y { class AccessibleWrap; -class RemoteAccessible; +class Accessible; class RootAccessibleWrap; class BatchData; @@ -42,10 +42,7 @@ class SessionAccessibility final } static void Init(); - static RefPtr GetInstanceFor( - RemoteAccessible* aAccessible); - static RefPtr GetInstanceFor( - LocalAccessible* aAccessible); + static RefPtr GetInstanceFor(Accessible* aAccessible); // Native implementations using Base::AttachNative;