зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1765430 - P3: Refactor Android Pivot methods. r=Jamie
This creates a clearer distinction between local pivots and remote pivots. The former happens in the parent process and the latter happens in the remote content process. Differential Revision: https://phabricator.services.mozilla.com/D144482
This commit is contained in:
Родитель
f45be3470b
Коммит
c9311969b2
|
@ -283,38 +283,37 @@ bool AccessibleWrap::GetSelectionBounds(int32_t* aStartOffset,
|
|||
return false;
|
||||
}
|
||||
|
||||
Accessible* AccessibleWrap::DoPivot(Accessible* aAccessible,
|
||||
int32_t aGranularity, bool aForward,
|
||||
bool aInclusive) {
|
||||
a11y::Pivot pivot(nullptr);
|
||||
// Depending on the start accessible, the pivot rule will either traverse
|
||||
// local or remote accessibles exclusively.
|
||||
TraversalRule rule(aGranularity, aAccessible->IsLocal());
|
||||
Accessible* result = aForward ? pivot.Next(aAccessible, rule, aInclusive)
|
||||
: pivot.Prev(aAccessible, rule, aInclusive);
|
||||
|
||||
if (result && (result != aAccessible || aInclusive)) {
|
||||
return result;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool AccessibleWrap::PivotTo(int32_t aGranularity, bool aForward,
|
||||
bool aInclusive) {
|
||||
a11y::Pivot pivot(RootAccessible());
|
||||
TraversalRule rule(aGranularity);
|
||||
Accessible* current = IsProxy() ? Proxy() : static_cast<Accessible*>(this);
|
||||
Accessible* result = aForward ? pivot.Next(current, rule, aInclusive)
|
||||
: pivot.Prev(current, rule, aInclusive);
|
||||
|
||||
if (result && (result != current || aInclusive)) {
|
||||
RefPtr<AccessibleWrap> newPosition =
|
||||
result->IsRemote() ? WrapperFor(result->AsRemote())
|
||||
: static_cast<AccessibleWrap*>(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<AccEvent> 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<SessionAccessibility> sessionAcc =
|
||||
SessionAccessibility::GetInstanceFor(result);
|
||||
sessionAcc->SendAccessibilityFocusedEvent(newPosition);
|
||||
}
|
||||
Accessible* result = DoPivot(this, aGranularity, aForward, aInclusive);
|
||||
if (result) {
|
||||
MOZ_ASSERT(result->IsLocal());
|
||||
// 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();
|
||||
RefPtr<AccEvent> event = new AccVCChangeEvent(
|
||||
localResult->Document(), this, -1, -1, localResult, -1, -1, reason,
|
||||
nsIAccessiblePivot::NO_BOUNDARY, eFromUserInput);
|
||||
nsEventShell::FireEvent(event);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -324,7 +323,7 @@ bool AccessibleWrap::PivotTo(int32_t aGranularity, bool aForward,
|
|||
|
||||
void AccessibleWrap::ExploreByTouch(float aX, float aY) {
|
||||
a11y::Pivot pivot(RootAccessible());
|
||||
ExploreByTouchRule rule;
|
||||
TraversalRule rule;
|
||||
|
||||
Accessible* maybeResult = pivot.AtPoint(aX, aY, rule);
|
||||
LocalAccessible* result = maybeResult ? maybeResult->AsLocal() : nullptr;
|
||||
|
|
|
@ -83,6 +83,9 @@ class AccessibleWrap : public LocalAccessible {
|
|||
|
||||
static void SetVirtualViewID(Accessible* aAccessible, int32_t aVirtualViewID);
|
||||
|
||||
static Accessible* DoPivot(Accessible* aAccessible, int32_t aGranularity,
|
||||
bool aForward, bool aInclusive);
|
||||
|
||||
protected:
|
||||
int32_t mID;
|
||||
|
||||
|
|
|
@ -157,7 +157,8 @@ void DocAccessibleWrap::CacheViewportCallback(nsITimer* aTimer,
|
|||
|
||||
if (docAcc->mCachePivotBoundaries) {
|
||||
a11y::Pivot pivot(docAcc);
|
||||
TraversalRule rule(java::SessionAccessibility::HTML_GRANULARITY_DEFAULT);
|
||||
TraversalRule rule(java::SessionAccessibility::HTML_GRANULARITY_DEFAULT,
|
||||
true);
|
||||
Accessible* maybeFirst = pivot.First(rule);
|
||||
Accessible* maybeLast = pivot.Last(rule);
|
||||
LocalAccessible* first = maybeFirst ? maybeFirst->AsLocal() : nullptr;
|
||||
|
|
|
@ -109,7 +109,7 @@ bool RemoteAccessibleWrap::PivotTo(int32_t aGranularity, bool aForward,
|
|||
return AccessibleWrap::PivotTo(aGranularity, aForward, aInclusive);
|
||||
}
|
||||
|
||||
Unused << Proxy()->Document()->GetPlatformExtension()->SendPivot(
|
||||
Unused << Proxy()->Document()->GetPlatformExtension()->SendPivotTo(
|
||||
Proxy()->ID(), aGranularity, aForward, aInclusive);
|
||||
|
||||
return true;
|
||||
|
|
|
@ -126,11 +126,24 @@ bool SessionAccessibility::CachedPivot(int32_t aID, int32_t aGranularity,
|
|||
bool ret = false;
|
||||
nsAppShell::SyncRunEvent(
|
||||
[this, self, aID, aGranularity, aForward, aInclusive, &ret] {
|
||||
if (AccessibleWrap* acc = GetAccessibleByID(aID)) {
|
||||
ret = acc->PivotTo(aGranularity, aForward, aInclusive);
|
||||
if (Accessible* acc = GetAccessibleByID(aID)) {
|
||||
if (acc->AsLocal()->IsProxy()) {
|
||||
// XXX: Will be removed with RemoteAccessibleWrap
|
||||
acc = acc->AsLocal()->Proxy();
|
||||
}
|
||||
Accessible* result =
|
||||
AccessibleWrap::DoPivot(acc, aGranularity, aForward, aInclusive);
|
||||
if (result) {
|
||||
ret = true;
|
||||
int32_t virtualViewID = AccessibleWrap::GetVirtualViewID(result);
|
||||
nsAppShell::PostEvent([this, self, virtualViewID] {
|
||||
if (AccessibleWrap* acc = GetAccessibleByID(virtualViewID)) {
|
||||
SendAccessibilityFocusedEvent(acc);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -236,7 +249,8 @@ void SessionAccessibility::SendAccessibilityFocusedEvent(
|
|||
mSessionAccessibility->SendEvent(
|
||||
java::sdk::AccessibilityEvent::TYPE_VIEW_ACCESSIBILITY_FOCUSED,
|
||||
aAccessible->VirtualViewID(), aAccessible->AndroidClass(), nullptr);
|
||||
aAccessible->ScrollTo(nsIAccessibleScrollType::SCROLL_TYPE_ANYWHERE);
|
||||
RefPtr<AccessibleWrap> acc = aAccessible;
|
||||
acc->ScrollTo(nsIAccessibleScrollType::SCROLL_TYPE_ANYWHERE);
|
||||
}
|
||||
|
||||
void SessionAccessibility::SendHoverEnterEvent(AccessibleWrap* aAccessible) {
|
||||
|
|
|
@ -70,7 +70,7 @@ class SessionAccessibility final
|
|||
void SendScrollingEvent(AccessibleWrap* aAccessible, int32_t aScrollX,
|
||||
int32_t aScrollY, int32_t aMaxScrollX,
|
||||
int32_t aMaxScrollY);
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
void SendAccessibilityFocusedEvent(AccessibleWrap* aAccessible);
|
||||
void SendHoverEnterEvent(AccessibleWrap* aAccessible);
|
||||
void SendTextSelectionChangedEvent(AccessibleWrap* aAccessible,
|
||||
|
|
|
@ -19,14 +19,28 @@ using namespace mozilla;
|
|||
using namespace mozilla::a11y;
|
||||
|
||||
TraversalRule::TraversalRule()
|
||||
: TraversalRule(java::SessionAccessibility::HTML_GRANULARITY_DEFAULT) {}
|
||||
: TraversalRule(java::SessionAccessibility::HTML_GRANULARITY_DEFAULT,
|
||||
true) {}
|
||||
|
||||
TraversalRule::TraversalRule(int32_t aGranularity)
|
||||
: mGranularity(aGranularity) {}
|
||||
TraversalRule::TraversalRule(int32_t aGranularity, bool aIsLocal)
|
||||
: mGranularity(aGranularity), mIsLocal(aIsLocal) {}
|
||||
|
||||
uint16_t TraversalRule::Match(Accessible* aAcc) {
|
||||
MOZ_ASSERT(aAcc);
|
||||
|
||||
if (mIsLocal && aAcc->IsRemote()) {
|
||||
// If we encounter a remote accessible in a local rule, we should
|
||||
// ignore the subtree because we won't encounter anymore local accessibles
|
||||
// in it.
|
||||
return nsIAccessibleTraversalRule::FILTER_IGNORE |
|
||||
nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
|
||||
} else if (!mIsLocal && aAcc->IsLocal()) {
|
||||
// If we encounter a local accessible in a remote rule we are likely
|
||||
// traversing backwards/upwards, we don't ignore its subtree because it is
|
||||
// likely the outer doc root of the remote tree.
|
||||
return nsIAccessibleTraversalRule::FILTER_IGNORE;
|
||||
}
|
||||
|
||||
uint16_t result = nsIAccessibleTraversalRule::FILTER_IGNORE;
|
||||
|
||||
if (nsAccUtils::MustPrune(aAcc)) {
|
||||
|
@ -281,14 +295,3 @@ uint16_t TraversalRule::DefaultMatch(Accessible* aAccessible) {
|
|||
|
||||
return nsIAccessibleTraversalRule::FILTER_IGNORE;
|
||||
}
|
||||
|
||||
uint16_t ExploreByTouchRule::Match(Accessible* aAcc) {
|
||||
if (aAcc->IsRemote()) {
|
||||
// Explore by touch happens in the local process and should
|
||||
// not drill down into remote frames.
|
||||
return nsIAccessibleTraversalRule::FILTER_IGNORE |
|
||||
nsIAccessibleTraversalRule::FILTER_IGNORE_SUBTREE;
|
||||
}
|
||||
|
||||
return TraversalRule::Match(aAcc);
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class Accessible;
|
|||
class TraversalRule : public PivotRule {
|
||||
public:
|
||||
TraversalRule();
|
||||
explicit TraversalRule(int32_t aGranularity);
|
||||
explicit TraversalRule(int32_t aGranularity, bool aIsLocal);
|
||||
|
||||
~TraversalRule() = default;
|
||||
|
||||
|
@ -48,10 +48,8 @@ class TraversalRule : public PivotRule {
|
|||
uint16_t LandmarkMatch(Accessible* aAccessible);
|
||||
|
||||
int32_t mGranularity;
|
||||
};
|
||||
|
||||
class ExploreByTouchRule final : public TraversalRule {
|
||||
virtual uint16_t Match(Accessible* aAcc) override;
|
||||
bool mIsLocal;
|
||||
};
|
||||
|
||||
} // namespace a11y
|
||||
|
|
|
@ -119,7 +119,6 @@ void ProxySelectionEvent(RemoteAccessible* aTarget, RemoteAccessible* aWidget,
|
|||
uint32_t aType);
|
||||
|
||||
#if defined(ANDROID)
|
||||
MOZ_CAN_RUN_SCRIPT
|
||||
void ProxyVirtualCursorChangeEvent(RemoteAccessible* aTarget,
|
||||
RemoteAccessible* aOldPosition,
|
||||
int32_t aOldStartOffset,
|
||||
|
|
|
@ -129,7 +129,6 @@ class DocAccessibleParent : public RemoteAccessible,
|
|||
const uint64_t& aID, const uint64_t& aWidgetID,
|
||||
const uint32_t& aType) override;
|
||||
|
||||
MOZ_CAN_RUN_SCRIPT_BOUNDARY
|
||||
virtual mozilla::ipc::IPCResult RecvVirtualCursorChangeEvent(
|
||||
const uint64_t& aID, const uint64_t& aOldPositionID,
|
||||
const int32_t& aOldStartOffset, const int32_t& aOldEndOffset,
|
||||
|
|
|
@ -12,7 +12,7 @@
|
|||
namespace mozilla {
|
||||
namespace a11y {
|
||||
|
||||
mozilla::ipc::IPCResult DocAccessiblePlatformExtChild::RecvPivot(
|
||||
mozilla::ipc::IPCResult DocAccessiblePlatformExtChild::RecvPivotTo(
|
||||
uint64_t aID, int32_t aGranularity, bool aForward, bool aInclusive) {
|
||||
if (auto acc = IdToAccessibleWrap(aID)) {
|
||||
acc->PivotTo(aGranularity, aForward, aInclusive);
|
||||
|
|
|
@ -16,8 +16,8 @@ class DocAccessibleChild;
|
|||
|
||||
class DocAccessiblePlatformExtChild : public PDocAccessiblePlatformExtChild {
|
||||
public:
|
||||
mozilla::ipc::IPCResult RecvPivot(uint64_t aID, int32_t aGranularity,
|
||||
bool aForward, bool aInclusive);
|
||||
mozilla::ipc::IPCResult RecvPivotTo(uint64_t aID, int32_t aGranularity,
|
||||
bool aForward, bool aInclusive);
|
||||
|
||||
mozilla::ipc::IPCResult RecvNavigateText(uint64_t aID, int32_t aGranularity,
|
||||
int32_t aStartOffset,
|
||||
|
|
|
@ -16,7 +16,7 @@ protocol PDocAccessiblePlatformExt {
|
|||
child:
|
||||
async __delete__();
|
||||
|
||||
async Pivot(uint64_t aID, int32_t aGranularity, bool aForward, bool aInclusive);
|
||||
async PivotTo(uint64_t aID, int32_t aGranularity, bool aForward, bool aInclusive);
|
||||
|
||||
async NavigateText(uint64_t aID, int32_t aGranularity, int32_t aStartOffset, int32_t aEndOffset, bool aForward, bool aSelect);
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче